From d872d69349d8510a373708ad2bcb4a9b8c014344 Mon Sep 17 00:00:00 2001 From: Wali Viqas Date: Sun, 19 Apr 2026 04:40:05 -0700 Subject: [PATCH 01/18] feat: dynamic match cache + team setup + spotting board modes Adds GameFetchService that pulls live rosters, stats, and injury news from ESPN/MLB/NHL/Google News so the match cache is built on demand from a team name instead of shipping hardcoded data. TeamSetupView drives the flow on first launch and from the sidebar. Research center gains Stats-First, Story-First, and Tactical spotting board modes plus a commentator style picker. Network client entitlement enabled for live fetches. Co-Authored-By: Claude Opus 4.7 (1M context) --- BroadcastBrain.xcodeproj/project.pbxproj | 24 + BroadcastBrain/BroadcastBrain.entitlements | 2 +- BroadcastBrain/ContentView.swift | 20 +- .../Services/GameFetchService.swift | 557 +++++++++ BroadcastBrain/Stores/AppStore.swift | 76 +- .../Views/CommentatorStylePickerView.swift | 153 +++ BroadcastBrain/Views/Components/Tokens.swift | 1 + BroadcastBrain/Views/ResearchCenterView.swift | 19 +- BroadcastBrain/Views/SidebarView.swift | 23 + .../Views/StatsFirstSpottingBoardView.swift | 372 ++++++ .../Views/StoryFirstSpottingBoardView.swift | 401 +++++++ .../Views/TacticalSpottingBoardView.swift | 374 ++++++ BroadcastBrain/Views/TeamSetupView.swift | 239 ++++ project.yml | 2 +- src/data/FetchGame.swift | 1000 +++++++++++++++++ src/data/News.swift | 176 +++ 16 files changed, 3411 insertions(+), 28 deletions(-) create mode 100644 BroadcastBrain/Services/GameFetchService.swift create mode 100644 BroadcastBrain/Views/CommentatorStylePickerView.swift create mode 100644 BroadcastBrain/Views/StatsFirstSpottingBoardView.swift create mode 100644 BroadcastBrain/Views/StoryFirstSpottingBoardView.swift create mode 100644 BroadcastBrain/Views/TacticalSpottingBoardView.swift create mode 100644 BroadcastBrain/Views/TeamSetupView.swift create mode 100644 src/data/FetchGame.swift create mode 100644 src/data/News.swift diff --git a/BroadcastBrain.xcodeproj/project.pbxproj b/BroadcastBrain.xcodeproj/project.pbxproj index b260a52d..3a863d33 100644 --- a/BroadcastBrain.xcodeproj/project.pbxproj +++ b/BroadcastBrain.xcodeproj/project.pbxproj @@ -21,6 +21,12 @@ 4888A82003BDA03F00D954CD /* LivePill.swift in Sources */ = {isa = PBXBuildFile; fileRef = B79E4BA0F9248D3466873BBE /* LivePill.swift */; }; 5982407B776A2A4BF04125BA /* StatCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE64AD9C32691F3111C8595F /* StatCardView.swift */; }; 67EED72EDEC3D8621574A4BC /* ResearchCenterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */; }; + AA1B2C3D4E5F6A7B8C9D0E1F /* CommentatorStylePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C3D4E5F6A7B8C9D0E1F2A /* CommentatorStylePickerView.swift */; }; + CC3D4E5F6A7B8C9D0E1F2A3B /* StatsFirstSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4E5F6A7B8C9D0E1F2A3B4C /* StatsFirstSpottingBoardView.swift */; }; + EE5F6A7B8C9D0E1F2A3B4C5D /* StoryFirstSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6A7B8C9D0E1F2A3B4C5D6E /* StoryFirstSpottingBoardView.swift */; }; + A1B2C3D4E5F60718293A4B5C /* TacticalSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */; }; + F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */; }; + A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */; }; 70BA18D24CCC880D502CADD7 /* SquadsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */; }; 70BC25E15A41151CA931A4B9 /* cactus-macos.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */; }; 73474C0EE14E2A4A9B79742C /* LivePaneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01550DE4B92113B1173C6B2F /* LivePaneView.swift */; }; @@ -80,6 +86,12 @@ 154FDBDC815FD074D17C258E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 1BDB3FB2A46D89FB8F6E528D /* BroadcastBrain.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BroadcastBrain.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResearchCenterView.swift; sourceTree = ""; }; + BB2C3D4E5F6A7B8C9D0E1F2A /* CommentatorStylePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentatorStylePickerView.swift; sourceTree = ""; }; + DD4E5F6A7B8C9D0E1F2A3B4C /* StatsFirstSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsFirstSpottingBoardView.swift; sourceTree = ""; }; + FF6A7B8C9D0E1F2A3B4C5D6E /* StoryFirstSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryFirstSpottingBoardView.swift; sourceTree = ""; }; + B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalSpottingBoardView.swift; sourceTree = ""; }; + E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameFetchService.swift; sourceTree = ""; }; + B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamSetupView.swift; sourceTree = ""; }; 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "cactus-macos.xcframework"; path = "BroadcastBrain/Frameworks/cactus-macos.xcframework"; sourceTree = ""; }; 46EAD55D55FDE50021FA38E3 /* SportradarBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportradarBadge.swift; sourceTree = ""; }; 51919B20535309C89D4E15B9 /* Tokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tokens.swift; sourceTree = ""; }; @@ -132,6 +144,11 @@ children = ( 05EF9474EB26DF74B8D7FDAA /* ArchiveDetailView.swift */, 8CC045EB8451818A6CD5A1ED /* ArchivesListView.swift */, + BB2C3D4E5F6A7B8C9D0E1F2A /* CommentatorStylePickerView.swift */, + DD4E5F6A7B8C9D0E1F2A3B4C /* StatsFirstSpottingBoardView.swift */, + FF6A7B8C9D0E1F2A3B4C5D6E /* StoryFirstSpottingBoardView.swift */, + B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */, + B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */, 01550DE4B92113B1173C6B2F /* LivePaneView.swift */, 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */, FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */, @@ -220,6 +237,7 @@ isa = PBXGroup; children = ( B83E5A0C129A26A3CC625311 /* AudioCaptureService.swift */, + E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */, 82B9451069B6343C41C337AC /* Cactus.swift */, 90AFD39809B3E0BE8DF8644B /* CactusService.swift */, 7CE728CE31ACC8F9DB7324B9 /* MockResponder.swift */, @@ -370,6 +388,12 @@ B6F4346E4C192BF816F68EAA /* Cactus.swift in Sources */, D2F4BB6524F4500D144AF80C /* CactusService.swift in Sources */, 30702CFDAB6E91475D9965F5 /* ChatMessageRow.swift in Sources */, + AA1B2C3D4E5F6A7B8C9D0E1F /* CommentatorStylePickerView.swift in Sources */, + CC3D4E5F6A7B8C9D0E1F2A3B /* StatsFirstSpottingBoardView.swift in Sources */, + EE5F6A7B8C9D0E1F2A3B4C5D /* StoryFirstSpottingBoardView.swift in Sources */, + A1B2C3D4E5F60718293A4B5C /* TacticalSpottingBoardView.swift in Sources */, + F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */, + A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */, B28DD1DE6BE6197370BB602C /* ContentView.swift in Sources */, 43DB7EFEFC8C19A84E734EF6 /* DottedGrid.swift in Sources */, E05C57FFDF0F3B9977139753 /* LatencyTag.swift in Sources */, diff --git a/BroadcastBrain/BroadcastBrain.entitlements b/BroadcastBrain/BroadcastBrain.entitlements index 62373bba..30d9cee6 100644 --- a/BroadcastBrain/BroadcastBrain.entitlements +++ b/BroadcastBrain/BroadcastBrain.entitlements @@ -9,6 +9,6 @@ com.apple.security.files.user-selected.read-write com.apple.security.network.client - + diff --git a/BroadcastBrain/ContentView.swift b/BroadcastBrain/ContentView.swift index 88c2faff..a29a9ce8 100644 --- a/BroadcastBrain/ContentView.swift +++ b/BroadcastBrain/ContentView.swift @@ -4,13 +4,21 @@ struct ContentView: View { @Environment(AppStore.self) private var store var body: some View { - NavigationSplitView { - SidebarView() - .navigationSplitViewColumnWidth(min: 220, ideal: 260) - } detail: { - detailView + ZStack { + NavigationSplitView { + SidebarView() + .navigationSplitViewColumnWidth(min: 220, ideal: 260) + } detail: { + detailView + } + .background(Color.bgBase) + + if store.showingSetup { + TeamSetupView() + .transition(.opacity) + } } - .background(Color.bgBase) + .animation(.easeInOut(duration: 0.2), value: store.showingSetup) } @ViewBuilder diff --git a/BroadcastBrain/Services/GameFetchService.swift b/BroadcastBrain/Services/GameFetchService.swift new file mode 100644 index 00000000..718367d5 --- /dev/null +++ b/BroadcastBrain/Services/GameFetchService.swift @@ -0,0 +1,557 @@ +import Foundation + +// MARK: - Progress + +enum FetchStep: String { + case detectingSport = "Detecting sport…" + case findingGame = "Finding next game…" + case fetchingRosters = "Fetching rosters…" + case fetchingNews = "Fetching news & storylines…" + case buildingCache = "Building match cache…" + case done = "Done" +} + +@Observable +final class GameFetchService { + var step: FetchStep = .detectingSport + var stepDetail: String = "" + var isRunning = false + + // MARK: - Entry point + + func buildMatchCache(teamName: String) async throws -> MatchCache { + isRunning = true + defer { isRunning = false } + + progress(.detectingSport, "") + let (sport, league, display) = await detectSport(teamName) + + progress(.findingGame, "") + var gameInfo: GameInfo? = nil + var ourTeamId = "" + + if sport == "soccer" || sport == "basketball" { + ourTeamId = await espnFindTeamId(teamName, sport: sport, league: league) ?? "" + if !ourTeamId.isEmpty { gameInfo = await espnNextGame(teamId: ourTeamId, sport: sport, league: league) } + } else if sport == "baseball" { + ourTeamId = await mlbFindTeamId(teamName) ?? "" + if !ourTeamId.isEmpty { gameInfo = await mlbNextGame(teamId: ourTeamId) } + } else if sport == "hockey" { + ourTeamId = nhlAbbrev(teamName) ?? "" + if !ourTeamId.isEmpty { gameInfo = await nhlNextGame(abbrev: ourTeamId) } + } + + // Fallback if no upcoming game found + let gi = gameInfo ?? GameInfo( + homeTeam: teamName, awayTeam: "TBD", + homeId: ourTeamId, awayId: "", + venue: "TBD", dateISO: ISO8601DateFormatter().string(from: Date()), + competition: display + ) + progress(.findingGame, "\(gi.homeTeam) vs \(gi.awayTeam)") + + progress(.fetchingRosters, "") + let isHome = teamName.lowercased().contains(gi.homeTeam.lowercased()) || gi.homeTeam.lowercased().contains(teamName.lowercased()) + let oppName = isHome ? gi.awayTeam : gi.homeTeam + var oppId = isHome ? gi.awayId : gi.homeId + + var homeRaw: [RawPlayerInfo] = [] + var awayRaw: [RawPlayerInfo] = [] + + if sport == "soccer" || sport == "basketball" { + if !ourTeamId.isEmpty { homeRaw = await espnRoster(teamId: ourTeamId, sport: sport, league: league) } + if oppId.isEmpty && oppName != "TBD" { oppId = await espnFindTeamId(oppName, sport: sport, league: league) ?? "" } + if !oppId.isEmpty { awayRaw = await espnRoster(teamId: oppId, sport: sport, league: league) } + } else if sport == "baseball" { + if !ourTeamId.isEmpty { homeRaw = await mlbRoster(teamId: ourTeamId) } + if oppName != "TBD" { + let id = oppId.isEmpty ? (await mlbFindTeamId(oppName) ?? "") : oppId + if !id.isEmpty { awayRaw = await mlbRoster(teamId: id) } + } + } else if sport == "hockey" { + if !ourTeamId.isEmpty { homeRaw = await nhlRoster(abbrev: ourTeamId) } + if oppName != "TBD" { + let abbr = oppId.isEmpty ? (nhlAbbrev(oppName) ?? "") : oppId + if !abbr.isEmpty { awayRaw = await nhlRoster(abbrev: abbr) } + } + } + progress(.fetchingRosters, "\(homeRaw.count) + \(awayRaw.count) players") + + progress(.fetchingNews, "") + let homeNews = await googleNews("\(gi.homeTeam) news 2026", max: 5) + let awayNews = gi.awayTeam != "TBD" ? await googleNews("\(gi.awayTeam) news 2026", max: 3) : [] + var storylines = Array((homeNews + awayNews).prefix(8)) + if (sport == "soccer" || sport == "basketball") && !ourTeamId.isEmpty { + let espnH = await espnTeamNews(teamId: ourTeamId, sport: sport, league: league) + storylines = Array((espnH.prefix(4) + storylines).prefix(8)) + } + + progress(.buildingCache, "") + let injuryLines = await googleNews("\(gi.homeTeam) injury doubtful out 2026", max: 8) + + (gi.awayTeam != "TBD" ? await googleNews("\(gi.awayTeam) injury doubtful out 2026", max: 5) : []) + + var players: [Player] = [] + for (raw, teamDisplay, oppDisplay) in [(homeRaw, gi.homeTeam, gi.awayTeam), (awayRaw, gi.awayTeam, gi.homeTeam)] { + for (i, p) in raw.prefix(18).enumerated() { + var stats: [String: String] = [:] + if i < 8 && !p.id.isEmpty { + if sport == "soccer" || sport == "basketball" { + stats = await espnPlayerStats(playerId: p.id, sport: sport, league: league) + } else if sport == "baseball" { + stats = await mlbPlayerStats(playerId: p.id) + } else if sport == "hockey" { + stats = await nhlPlayerStats(playerId: p.id) + } + } + var playerNews: [String] = [] + if i < 6 { + playerNews = await fetchNewsForPlayer(name: p.name, team: teamDisplay) + } + let status = inferStatus(name: p.name, headlines: injuryLines) + var keyStats: [String: String] = [:] + let statPairs = stats.filter { !["","0","0.0","—"].contains($0.value) } + let topThree = statPairs.prefix(4) + let keys = ["stat1","stat2","stat3","stat4"] + for (idx, kv) in topThree.enumerated() { + keyStats[keys[idx]] = "\(kv.value) \(kv.key)" + } + keyStats["storyHero"] = makeStoryline(name: p.name, position: p.position, stats: stats, news: playerNews, status: status) + keyStats["tactical"] = makeMatchupNote(name: p.name, opponent: oppDisplay) + players.append(Player( + name: p.name.isEmpty ? "Player \(i+1)" : p.name, + team: teamDisplay, + jersey: p.number.map(String.init) ?? "\(i+1)", + position: p.position.isEmpty ? "—" : p.position, + keyStats: keyStats + )) + } + } + + let title = "\(gi.homeTeam) vs \(gi.awayTeam) · \(gi.competition.isEmpty ? display : gi.competition) · \(gi.venue)" + let facts = [ + "Match: \(gi.homeTeam) vs \(gi.awayTeam)", + "Competition: \(gi.competition.isEmpty ? display : gi.competition)", + "Venue: \(gi.venue)", + "Date: \(gi.dateISO)", + ] + storylines.prefix(4).map { $0 } + + progress(.done, title) + return MatchCache( + matchId: makeId(gi.homeTeam, gi.awayTeam), + title: title, + players: players, + facts: facts, + storylines: storylines + ) + } + + // MARK: - Progress helper + + private func progress(_ s: FetchStep, _ detail: String) { + step = s; stepDetail = detail + } + + // MARK: - Sport detection + + private func detectSport(_ teamName: String) async -> (String, String, String) { + let lower = teamName.lowercased().trimmingCharacters(in: .whitespaces) + for (key, entry) in Self.knownTeams { + if key.contains(lower) || lower.contains(key) { return entry } + } + // ESPN search fallback + for (sport, league) in [("soccer","eng.1"),("soccer","esp.1"),("soccer","ger.1"),("basketball","nba")] { + guard let url = URL(string: "\(Self.espnBase)/\(sport)/\(league)/teams"), + let data = await getJSON(url) as? [String: Any], + let teams = ((data["sports"] as? [[String:Any]])?.first?["leagues"] as? [[String:Any]])?.first?["teams"] as? [[String:Any]] else { continue } + for entry in teams { + let t = entry["team"] as? [String:Any] ?? [:] + let name = (t["displayName"] as? String ?? "").lowercased() + let nick = (t["nickname"] as? String ?? "").lowercased() + if lower.contains(name) || name.contains(lower) || nick.contains(lower) { + return (sport, league, league.uppercased()) + } + } + } + return ("soccer", "eng.1", "Premier League") + } + + // MARK: - ESPN + + private func espnFindTeamId(_ teamName: String, sport: String, league: String) async -> String? { + guard let url = URL(string: "\(Self.espnBase)/\(sport)/\(league)/teams"), + let data = await getJSON(url) as? [String: Any], + let teams = ((data["sports"] as? [[String:Any]])?.first?["leagues"] as? [[String:Any]])?.first?["teams"] as? [[String:Any]] else { return nil } + let lower = teamName.lowercased() + var bestId: String?; var bestScore = 0 + for entry in teams { + let t = entry["team"] as? [String:Any] ?? [:] + let name = (t["displayName"] as? String ?? "").lowercased() + let nick = (t["nickname"] as? String ?? "").lowercased() + let slug = (t["slug"] as? String ?? "").lowercased() + var score = 0 + if lower == name { score = 100 } + else if lower.contains(name) || name.contains(lower) { score = 80 } + else if nick.contains(lower) || lower.contains(nick) { score = 60 } + else if slug.contains(lower) { score = 50 } + if score > bestScore { bestScore = score; bestId = t["id"] as? String } + } + return bestId + } + + private func espnNextGame(teamId: String, sport: String, league: String) async -> GameInfo? { + guard let url = URL(string: "\(Self.espnBase)/\(sport)/\(league)/teams/\(teamId)/schedule"), + let data = await getJSON(url) as? [String: Any], + let events = data["events"] as? [[String: Any]] else { return nil } + for event in events { + guard let comp = (event["competitions"] as? [[String:Any]])?.first else { continue } + let state = ((comp["status"] as? [String:Any])?["type"] as? [String:Any])?["state"] as? String ?? "" + guard state == "pre" else { continue } + let competitors = comp["competitors"] as? [[String:Any]] ?? [] + let home = competitors.first(where: { ($0["homeAway"] as? String) == "home" }) ?? [:] + let away = competitors.first(where: { ($0["homeAway"] as? String) == "away" }) ?? [:] + let ht = home["team"] as? [String:Any] ?? [:] + let at = away["team"] as? [String:Any] ?? [:] + return GameInfo( + homeTeam: ht["displayName"] as? String ?? "", + awayTeam: at["displayName"] as? String ?? "", + homeId: ht["id"] as? String ?? "", + awayId: at["id"] as? String ?? "", + venue: (comp["venue"] as? [String:Any])?["fullName"] as? String ?? "TBD", + dateISO: event["date"] as? String ?? "", + competition: (data["season"] as? [String:Any])?["displayName"] as? String ?? "" + ) + } + return nil + } + + private func espnRoster(teamId: String, sport: String, league: String) async -> [RawPlayerInfo] { + guard let url = URL(string: "\(Self.espnBase)/\(sport)/\(league)/teams/\(teamId)/roster"), + let data = await getJSON(url) as? [String: Any], + let athletes = data["athletes"] as? [[String:Any]] else { return [] } + var players: [RawPlayerInfo] = [] + for item in athletes { + if let items = item["items"] as? [[String:Any]] { + players.append(contentsOf: items.map(parseAthlete)) + } else { + players.append(parseAthlete(item)) + } + } + return players + } + + private func espnPlayerStats(playerId: String, sport: String, league: String) async -> [String: String] { + guard let url = URL(string: "\(Self.espnCore)/\(sport)/leagues/\(league)/athletes/\(playerId)/statistics/0"), + let data = await getJSON(url) as? [String: Any], + let cats = (data["splits"] as? [String:Any])?["categories"] as? [[String:Any]] else { return [:] } + var stats: [String: String] = [:] + for cat in cats { + for stat in (cat["stats"] as? [[String:Any]] ?? []) { + let name = stat["displayName"] as? String ?? "" + let value = stat["displayValue"] as? String ?? "" + if !name.isEmpty && !["","0","0.0"].contains(value) { stats[name] = value } + } + } + return stats + } + + private func espnTeamNews(teamId: String, sport: String, league: String) async -> [String] { + guard let url = URL(string: "\(Self.espnBase)/\(sport)/\(league)/news?team=\(teamId)&limit=10"), + let data = await getJSON(url) as? [String: Any], + let articles = data["articles"] as? [[String:Any]] else { return [] } + return articles.compactMap { ($0["headline"] as? String)?.trimmingCharacters(in: .whitespaces) }.filter { !$0.isEmpty }.prefix(6).map { $0 } + } + + // MARK: - MLB + + private func mlbFindTeamId(_ teamName: String) async -> String? { + guard let url = URL(string: "https://statsapi.mlb.com/api/v1/teams?sportId=1"), + let data = await getJSON(url) as? [String: Any], + let teams = data["teams"] as? [[String:Any]] else { return nil } + let lower = teamName.lowercased() + for team in teams { + let name = (team["name"] as? String ?? "").lowercased() + let short = (team["teamName"] as? String ?? "").lowercased() + if lower.contains(name) || name.contains(lower) || lower.contains(short) { + return String(team["id"] as? Int ?? 0) + } + } + return nil + } + + private func mlbNextGame(teamId: String) async -> GameInfo? { + guard let url = URL(string: "https://statsapi.mlb.com/api/v1/schedule/games/?sportId=1&teamId=\(teamId)"), + let data = await getJSON(url) as? [String: Any], + let dates = data["dates"] as? [[String:Any]], !dates.isEmpty, + let game = (dates[0]["games"] as? [[String:Any]])?.first else { return nil } + let homeTeam = (game["teams"] as? [String:Any])?["home"] as? [String:Any] + let awayTeam = (game["teams"] as? [String:Any])?["away"] as? [String:Any] + return GameInfo( + homeTeam: (homeTeam?["team"] as? [String:Any])?["name"] as? String ?? "", + awayTeam: (awayTeam?["team"] as? [String:Any])?["name"] as? String ?? "", + homeId: String((homeTeam?["team"] as? [String:Any])?["id"] as? Int ?? 0), + awayId: String((awayTeam?["team"] as? [String:Any])?["id"] as? Int ?? 0), + venue: (game["venue"] as? [String:Any])?["name"] as? String ?? "TBD", + dateISO: game["gameDate"] as? String ?? "", + competition: "MLB" + ) + } + + private func mlbRoster(teamId: String) async -> [RawPlayerInfo] { + guard let url = URL(string: "https://statsapi.mlb.com/api/v1/teams/\(teamId)/roster?season=2026&rosterType=active"), + let data = await getJSON(url) as? [String: Any], + let roster = data["roster"] as? [[String:Any]] else { return [] } + return roster.map { entry in + let person = entry["person"] as? [String:Any] ?? [:] + return RawPlayerInfo( + id: String(person["id"] as? Int ?? 0), + name: person["fullName"] as? String ?? "", + number: Int(entry["jerseyNumber"] as? String ?? ""), + position: (entry["position"] as? [String:Any])?["abbreviation"] as? String ?? "" + ) + } + } + + private func mlbPlayerStats(playerId: String) async -> [String: String] { + for group in ["hitting","pitching"] { + guard let url = URL(string: "https://statsapi.mlb.com/api/v1/people/\(playerId)/stats?stats=season&season=2026&group=\(group)"), + let data = await getJSON(url) as? [String: Any], + let splits = (data["stats"] as? [[String:Any]])?.first?["splits"] as? [[String:Any]], + !splits.isEmpty, + let stat = splits[0]["stat"] as? [String:Any] else { continue } + var result: [String: String] = [:] + for (k,v) in stat { let s = "\(v)"; if !["0","0.0",".000","","null"].contains(s) { result[k] = s } } + if !result.isEmpty { return result } + } + return [:] + } + + // MARK: - NHL + + func nhlAbbrev(_ teamName: String) -> String? { + let lower = teamName.lowercased() + for (key, abbrev) in Self.nhlAbbrevs { if lower.contains(key) { return abbrev } } + return nil + } + + private func nhlNextGame(abbrev: String) async -> GameInfo? { + guard let url = URL(string: "https://api-web.nhle.com/v1/club-schedule-season/\(abbrev)/now"), + let data = await getJSON(url) as? [String: Any], + let games = data["games"] as? [[String:Any]] else { return nil } + for game in games { + let state = game["gameState"] as? String ?? "" + guard ["FUT","PRE"].contains(state) else { continue } + let home = game["homeTeam"] as? [String:Any] ?? [:] + let away = game["awayTeam"] as? [String:Any] ?? [:] + let hn = [home["placeName"] as? [String:Any], home["commonName"] as? [String:Any]] + .compactMap { $0?["default"] as? String }.joined(separator: " ").trimmingCharacters(in: .whitespaces) + let an = [away["placeName"] as? [String:Any], away["commonName"] as? [String:Any]] + .compactMap { $0?["default"] as? String }.joined(separator: " ").trimmingCharacters(in: .whitespaces) + return GameInfo(homeTeam: hn, awayTeam: an, + homeId: home["abbrev"] as? String ?? "", + awayId: away["abbrev"] as? String ?? "", + venue: (game["venue"] as? [String:Any])?["default"] as? String ?? "TBD", + dateISO: game["gameDate"] as? String ?? "", competition: "NHL") + } + return nil + } + + private func nhlRoster(abbrev: String) async -> [RawPlayerInfo] { + guard let url = URL(string: "https://api-web.nhle.com/v1/roster/\(abbrev)/current"), + let data = await getJSON(url) as? [String: Any] else { return [] } + var players: [RawPlayerInfo] = [] + for group in ["forwards","defensemen","goalies"] { + for p in (data[group] as? [[String:Any]] ?? []) { + let fn = (p["firstName"] as? [String:Any])?["default"] as? String ?? "" + let ln = (p["lastName"] as? [String:Any])?["default"] as? String ?? "" + players.append(RawPlayerInfo( + id: String(p["id"] as? Int ?? 0), + name: "\(fn) \(ln)".trimmingCharacters(in: .whitespaces), + number: p["sweaterNumber"] as? Int, + position: p["positionCode"] as? String ?? "" + )) + } + } + return players + } + + private func nhlPlayerStats(playerId: String) async -> [String: String] { + guard let url = URL(string: "https://api-web.nhle.com/v1/player/\(playerId)/landing"), + let data = await getJSON(url) as? [String: Any], + let totals = data["seasonTotals"] as? [[String:Any]], !totals.isEmpty else { return [:] } + let latest = totals[totals.count - 1] + var stats: [String: String] = [:] + for key in ["goals","assists","points","plusMinus","shots","gamesPlayed","savePctg","goalsAgainstAvg","wins"] { + if let val = latest[key], "\(val)" != "0" { stats[key] = "\(val)" } + } + return stats + } + + // MARK: - Google News RSS + + private func googleNews(_ query: String, max: Int = 5) async -> [String] { + guard let encoded = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), + let url = URL(string: "https://news.google.com/rss/search?q=\(encoded)&hl=en-US&gl=US&ceid=US:en"), + let (data, resp) = try? await URLSession.shared.data(for: URLRequest(url: url)), + (resp as? HTTPURLResponse)?.statusCode == 200, + let xml = String(data: data, encoding: .utf8) else { return [] } + var headlines: [String] = [] + let pattern = try! NSRegularExpression(pattern: "<!\\[CDATA\\[(.*?)\\]\\]>|(.*?)") + for match in pattern.matches(in: xml, range: NSRange(xml.startIndex..., in: xml)) { + let raw: String + if let r = Range(match.range(at: 1), in: xml) { raw = String(xml[r]).trimmingCharacters(in: .whitespaces) } + else if let r = Range(match.range(at: 2), in: xml) { raw = String(xml[r]).trimmingCharacters(in: .whitespaces) } + else { continue } + guard !raw.isEmpty, raw != "Google News" else { continue } + let clean = raw.replacingOccurrences(of: "\\s*-\\s*[^-]+$", with: "", options: .regularExpression) + .trimmingCharacters(in: .whitespaces) + if !clean.isEmpty { headlines.append(clean) } + if headlines.count >= max { break } + } + return headlines + } + + // MARK: - Helpers + + private func parseAthlete(_ a: [String:Any]) -> RawPlayerInfo { + RawPlayerInfo( + id: a["id"] as? String ?? "", + name: a["displayName"] as? String ?? a["fullName"] as? String ?? "", + number: Int(a["jersey"] as? String ?? ""), + position: (a["position"] as? [String:Any])?["abbreviation"] as? String ?? "" + ) + } + + private func inferStatus(name: String, headlines: [String]) -> String { + let parts = name.lowercased().split(separator: " ").filter { $0.count > 2 }.map(String.init) + for hl in headlines { + let h = hl.lowercased() + guard parts.contains(where: { h.contains($0) }) else { continue } + if h.contains("suspend") { return "suspended" } + if h.contains("doubtful") { return "doubtful" } + if ["out","ruled out","injured","sidelined","misses"].contains(where: h.contains) { return "injured" } + } + return "fit" + } + + private func makeId(_ parts: String...) -> String { + let raw = parts.filter { !$0.isEmpty }.joined(separator: "-").lowercased().trimmingCharacters(in: .whitespaces) + let r = raw.replacingOccurrences(of: "[^a-z0-9]+", with: "-", options: .regularExpression) + .trimmingCharacters(in: CharacterSet(charactersIn: "-")) + return r.isEmpty ? "unknown" : r + } + + private func getJSON(_ url: URL) async -> Any? { + var req = URLRequest(url: url) + req.setValue("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36", forHTTPHeaderField: "User-Agent") + req.setValue("en-US,en;q=0.9", forHTTPHeaderField: "Accept-Language") + guard let (data, resp) = try? await URLSession.shared.data(for: req), + (resp as? HTTPURLResponse)?.statusCode == 200 else { return nil } + return try? JSONSerialization.jsonObject(with: data) + } + + // MARK: - Constants + + static let espnBase = "https://site.api.espn.com/apis/site/v2/sports" + static let espnCore = "https://sports.core.api.espn.com/v2/sports" + + static let nhlAbbrevs: [String: String] = [ + "toronto":"TOR","maple leafs":"TOR","leafs":"TOR", + "montreal":"MTL","canadiens":"MTL","boston":"BOS","bruins":"BOS", + "new york rangers":"NYR","rangers":"NYR","edmonton":"EDM","oilers":"EDM", + "colorado":"COL","avalanche":"COL","tampa bay":"TBL","lightning":"TBL", + "vegas":"VGK","golden knights":"VGK","carolina":"CAR","hurricanes":"CAR", + "florida":"FLA","panthers":"FLA","dallas":"DAL","stars":"DAL", + "new york islanders":"NYI","islanders":"NYI","new jersey":"NJD","devils":"NJD", + "pittsburgh":"PIT","penguins":"PIT","detroit":"DET","red wings":"DET", + "nashville":"NSH","predators":"NSH","minnesota":"MIN","wild":"MIN", + "winnipeg":"WPG","jets":"WPG","st. louis":"STL","blues":"STL", + "seattle":"SEA","kraken":"SEA","chicago":"CHI","blackhawks":"CHI", + "ottawa":"OTT","senators":"OTT","calgary":"CGY","flames":"CGY", + "vancouver":"VAN","canucks":"VAN","buffalo":"BUF","sabres":"BUF", + "san jose":"SJS","sharks":"SJS","philadelphia":"PHI","flyers":"PHI", + "anaheim":"ANA","ducks":"ANA","columbus":"CBJ","washington":"WSH","capitals":"WSH", + ] + + static let knownTeams: [String: (String, String, String)] = [ + // Soccer – PL + "manchester city":("soccer","eng.1","Premier League"), + "manchester united":("soccer","eng.1","Premier League"), + "liverpool":("soccer","eng.1","Premier League"), + "arsenal":("soccer","eng.1","Premier League"), + "chelsea":("soccer","eng.1","Premier League"), + "tottenham":("soccer","eng.1","Premier League"), + "newcastle":("soccer","eng.1","Premier League"), + "aston villa":("soccer","eng.1","Premier League"), + // La Liga + "real madrid":("soccer","esp.1","La Liga"), + "barcelona":("soccer","esp.1","La Liga"), + "atletico madrid":("soccer","esp.1","La Liga"), + // Bundesliga + "bayern munich":("soccer","ger.1","Bundesliga"), + "borussia dortmund":("soccer","ger.1","Bundesliga"), + // Serie A + "juventus":("soccer","ita.1","Serie A"), + "inter milan":("soccer","ita.1","Serie A"), + "ac milan":("soccer","ita.1","Serie A"), + "napoli":("soccer","ita.1","Serie A"), + // Ligue 1 + "paris saint-germain":("soccer","fra.1","Ligue 1"), + "psg":("soccer","fra.1","Ligue 1"), + "monaco":("soccer","fra.1","Ligue 1"), + // MLS + "inter miami":("soccer","usa.1","MLS"), + "la galaxy":("soccer","usa.1","MLS"), + "lafc":("soccer","usa.1","MLS"), + // NBA + "los angeles lakers":("basketball","nba","NBA"), + "lakers":("basketball","nba","NBA"), + "golden state warriors":("basketball","nba","NBA"), + "boston celtics":("basketball","nba","NBA"), + "miami heat":("basketball","nba","NBA"), + "chicago bulls":("basketball","nba","NBA"), + "new york knicks":("basketball","nba","NBA"), + "dallas mavericks":("basketball","nba","NBA"), + "denver nuggets":("basketball","nba","NBA"), + "oklahoma city thunder":("basketball","nba","NBA"), + "cleveland cavaliers":("basketball","nba","NBA"), + "houston rockets":("basketball","nba","NBA"), + "indiana pacers":("basketball","nba","NBA"), + "minnesota timberwolves":("basketball","nba","NBA"), + // MLB + "new york yankees":("baseball","mlb","MLB"), + "yankees":("baseball","mlb","MLB"), + "los angeles dodgers":("baseball","mlb","MLB"), + "dodgers":("baseball","mlb","MLB"), + "boston red sox":("baseball","mlb","MLB"), + "chicago cubs":("baseball","mlb","MLB"), + "houston astros":("baseball","mlb","MLB"), + "atlanta braves":("baseball","mlb","MLB"), + "new york mets":("baseball","mlb","MLB"), + "philadelphia phillies":("baseball","mlb","MLB"), + // NHL + "toronto maple leafs":("hockey","nhl","NHL"), + "leafs":("hockey","nhl","NHL"), + "montreal canadiens":("hockey","nhl","NHL"), + "boston bruins":("hockey","nhl","NHL"), + "edmonton oilers":("hockey","nhl","NHL"), + "oilers":("hockey","nhl","NHL"), + "colorado avalanche":("hockey","nhl","NHL"), + "tampa bay lightning":("hockey","nhl","NHL"), + "vegas golden knights":("hockey","nhl","NHL"), + "carolina hurricanes":("hockey","nhl","NHL"), + "florida panthers":("hockey","nhl","NHL"), + ] +} + +// MARK: - Internal types + +private struct GameInfo { + var homeTeam: String; var awayTeam: String + var homeId: String; var awayId: String + var venue: String; var dateISO: String + var competition: String +} + +struct RawPlayerInfo { + var id: String; var name: String; var number: Int?; var position: String +} diff --git a/BroadcastBrain/Stores/AppStore.swift b/BroadcastBrain/Stores/AppStore.swift index e8e3b156..b707a80a 100644 --- a/BroadcastBrain/Stores/AppStore.swift +++ b/BroadcastBrain/Stores/AppStore.swift @@ -12,17 +12,15 @@ enum SpottingMode: String, CaseIterable, Identifiable { var label: String { switch self { - case .stats: return "STATS" - case .story: return "STORY" + case .stats: return "STATS" + case .story: return "STORY" case .tactical: return "TACTICAL" } } } enum LiveState: Equatable { - case idle - case listening - case processing + case idle, listening, processing case error(String) } @@ -34,27 +32,28 @@ final class AppStore { var liveState: LiveState = .idle var partialTranscript: String = "" var lastLatencyMs: Int? + var spottingMode: SpottingMode? = nil + var showingSetup: Bool = false + private(set) var matchCache: MatchCache? let sessionStore: SessionStore let cactus: CactusService - let matchCache: MatchCache? + + // Saved cache location — overrides bundled resource after first user fetch + private static let savedCacheURL: URL = FileManager.default + .urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] + .appendingPathComponent("BroadcastBrain/match_cache.json") init(sessionStore: SessionStore, cactus: CactusService) { self.sessionStore = sessionStore self.cactus = cactus - if let url = Bundle.main.url(forResource: "match_cache", withExtension: "json"), - let data = try? Data(contentsOf: url), - let cache = try? JSONDecoder().decode(MatchCache.self, from: data) { - self.matchCache = cache - } else { - self.matchCache = nil - } + // Prefer the user-saved cache, fall back to bundled resource + let initialCache = Self.loadSavedCache() ?? Self.loadBundledCache() + self.matchCache = initialCache - let title = matchCache?.title ?? "Argentina vs France · 2022 WC Final" + let title = initialCache?.title ?? "New Match" - // Reuse an empty session for today's match if one already exists. - // Prevents the archives list from accumulating one empty entry per launch. let cal = Calendar.current if let reusable = sessionStore.sessions.first(where: { s in s.title == title @@ -71,8 +70,30 @@ final class AppStore { sessionStore.save(fresh) } - // Sweep any stray empty duplicate sessions (from pre-fix launches) sessionStore.purgeEmptyDuplicates(except: self.currentSession.id) + + // Show setup screen if there's no cache at all + if self.matchCache == nil { + self.showingSetup = true + } + } + + // Called by TeamSetupView after a successful fetch + func loadMatchCache(_ cache: MatchCache) { + matchCache = cache + spottingMode = nil + showingSetup = false + Self.persistCache(cache) + + // Start a fresh session for the new match + let fresh = Session(title: cache.title) + sessionStore.save(fresh) + currentSession = fresh + selectedSurface = .research + } + + func presentSetup() { + showingSetup = true } func appendStatCard(_ card: StatCard) { @@ -104,4 +125,25 @@ final class AppStore { selectedArchiveId = nil selectedSurface = .live } + + // MARK: - Cache persistence + + private static func loadSavedCache() -> MatchCache? { + guard FileManager.default.fileExists(atPath: savedCacheURL.path), + let data = try? Data(contentsOf: savedCacheURL) else { return nil } + return try? JSONDecoder().decode(MatchCache.self, from: data) + } + + private static func loadBundledCache() -> MatchCache? { + guard let url = Bundle.main.url(forResource: "match_cache", withExtension: "json"), + let data = try? Data(contentsOf: url) else { return nil } + return try? JSONDecoder().decode(MatchCache.self, from: data) + } + + private static func persistCache(_ cache: MatchCache) { + let dir = savedCacheURL.deletingLastPathComponent() + try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) + let enc = JSONEncoder(); enc.outputFormatting = [.prettyPrinted, .sortedKeys] + try? enc.encode(cache).write(to: savedCacheURL, options: .atomic) + } } diff --git a/BroadcastBrain/Views/CommentatorStylePickerView.swift b/BroadcastBrain/Views/CommentatorStylePickerView.swift new file mode 100644 index 00000000..808483ea --- /dev/null +++ b/BroadcastBrain/Views/CommentatorStylePickerView.swift @@ -0,0 +1,153 @@ +import SwiftUI + +struct CommentatorStylePickerView: View { + @Environment(AppStore.self) private var store + @State private var hovered: SpottingMode? = nil + + private var cache: MatchCache? { store.matchCache } + + private var playerCount: Int { cache?.players.count ?? 0 } + private var storylineCount: Int { cache?.storylines.count ?? 0 } + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + // Header pill + HStack(spacing: 6) { + Image(systemName: "checkmark.circle.fill") + .font(.system(size: 10, weight: .medium, design: .monospaced)) + .foregroundStyle(Color.verified) + Text("READY · PRE-INDEXED OVERNIGHT") + .font(Typography.chip) + .foregroundStyle(Color.verified) + } + .padding(.bottom, 14) + + Text("Pick your commentator style.") + .font(.system(size: 20, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + .padding(.bottom, 8) + + Text("\(playerCount) players · \(storylineCount) storylines pre-indexed.") + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + .padding(.bottom, 24) + + // Style rows + VStack(spacing: 1) { + StyleRow( + mode: .stats, + title: "STATS-FIRST", + badge: nil, + description: "xG · xA · progressive carries. Numbers lead.", + detail: "\(playerCount) player stats · \(storylineCount) matchups cached.", + hovered: $hovered + ) + StyleRow( + mode: .story, + title: "STORY-FIRST", + badge: "RECOMMENDED FOR YOU", + description: "Arcs, feuds, milestones. Narrative leads.", + detail: "World Cup · tournament history · season arcs.", + hovered: $hovered + ) + StyleRow( + mode: .tactical, + title: "TACTICAL", + badge: nil, + description: "Formations, pressing, roles. Function leads.", + detail: "Top scoreboard list · goals · comments.", + hovered: $hovered + ) + } + .clipShape(RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + + // Footer + HStack(spacing: 4) { + Text("MODE IS A PREFERENCE — NOT A CAGE.") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + Spacer() + Button("SKIP — CUSTOMIZE FROM SCRATCH") { + store.spottingMode = .stats + store.selectedSurface = .research + } + .buttonStyle(.plain) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .underline() + } + .padding(.top, 16) + } + .padding(28) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) + .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1)) + .frame(maxWidth: 540) + } +} + +private struct StyleRow: View { + @Environment(AppStore.self) private var store + let mode: SpottingMode + let title: String + let badge: String? + let description: String + let detail: String + @Binding var hovered: SpottingMode? + + var isHovered: Bool { hovered == mode } + + var body: some View { + Button { + store.spottingMode = mode + store.selectedSurface = .research + } label: { + HStack(alignment: .top, spacing: 14) { + // Stat preview block + VStack(alignment: .trailing, spacing: 2) { + Text(mode == .stats ? "5.2" : mode == .story ? "W/L" : "4-3") + .font(.system(size: 18, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + Text(mode == .stats ? "xG" : mode == .story ? "Cup Final" : "Formation") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + .frame(width: 60) + + VStack(alignment: .leading, spacing: 4) { + HStack(spacing: 8) { + Text(title) + .font(Typography.sectionHead) + .foregroundStyle(Color.textPrimary) + if let badge { + Text(badge) + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.bgBase) + .padding(.horizontal, 5) + .padding(.vertical, 2) + .background(Color.esoteric, in: RoundedRectangle(cornerRadius: 2)) + } + } + Text(description) + .font(Typography.body) + .foregroundStyle(Color.textMuted) + Text(detail) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + + Spacer() + + Image(systemName: "chevron.right") + .font(.system(size: 12, weight: .medium)) + .foregroundStyle(isHovered ? Color.textPrimary : Color.textSubtle) + } + .padding(.horizontal, 18) + .padding(.vertical, 14) + .background(isHovered ? Color.bgHover : Color.bgRaised) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + .onHover { isHovered in hovered = isHovered ? mode : nil } + } +} diff --git a/BroadcastBrain/Views/Components/Tokens.swift b/BroadcastBrain/Views/Components/Tokens.swift index fa0b2d0b..2a816465 100644 --- a/BroadcastBrain/Views/Components/Tokens.swift +++ b/BroadcastBrain/Views/Components/Tokens.swift @@ -23,6 +23,7 @@ extension Color { static let live = Color(hex: "#EF4444") static let verified = Color(hex: "#10B981") static let esoteric = Color(hex: "#F59E0B") + static let tactical = Color(hex: "#F97316") } enum Typography { diff --git a/BroadcastBrain/Views/ResearchCenterView.swift b/BroadcastBrain/Views/ResearchCenterView.swift index 63549b3c..6b843153 100644 --- a/BroadcastBrain/Views/ResearchCenterView.swift +++ b/BroadcastBrain/Views/ResearchCenterView.swift @@ -13,9 +13,22 @@ struct ResearchCenterView: View { latencyMs: store.lastLatencyMs ) - HSplitView { - notesColumn - chatColumn + if store.spottingMode == nil { + ZStack { + Color.bgBase + CommentatorStylePickerView() + } + } else if store.spottingMode == .stats { + StatsFirstSpottingBoardView() + } else if store.spottingMode == .story { + StoryFirstSpottingBoardView() + } else if store.spottingMode == .tactical { + TacticalSpottingBoardView() + } else { + HSplitView { + notesColumn + chatColumn + } } } .background(Color.bgBase) diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index 41c049f7..cfcaeb36 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -19,6 +19,29 @@ struct SidebarView: View { Divider().background(Color.bbBorder) + Button(action: { store.presentSetup() }) { + HStack(spacing: 8) { + Image(systemName: "arrow.trianglehead.2.clockwise") + .foregroundStyle(Color.textMuted) + .font(.system(size: 12)) + VStack(alignment: .leading, spacing: 1) { + Text("NEW MATCH") + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + if let title = store.matchCache?.title { + Text(title.components(separatedBy: " · ").first ?? title) + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + .lineLimit(1) + } + } + Spacer() + } + .padding(12) + } + .buttonStyle(.plain) + .background(Color.bgBase) + Button(action: { store.newSession() }) { HStack { Image(systemName: "plus.circle") diff --git a/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift b/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift new file mode 100644 index 00000000..94fc29a5 --- /dev/null +++ b/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift @@ -0,0 +1,372 @@ +import SwiftUI + +enum BoardDensity: String, CaseIterable { case compact = "COMPACT", standard = "STANDARD", full = "FULL" } + +struct StatsFirstSpottingBoardView: View { + @Environment(AppStore.self) private var store + @State private var density: BoardDensity = .standard + @State private var leftFilter: String = "" + @State private var rightFilter: String = "" + @State private var pinnedIds: Set = [] + + private var teams: (left: String, right: String) { + let parts = store.currentSession.title.components(separatedBy: " vs ") + let l = parts.first?.components(separatedBy: " ·").first?.trimmingCharacters(in: .whitespaces) ?? "Home" + let r = parts.dropFirst().first?.components(separatedBy: " ·").first?.trimmingCharacters(in: .whitespaces) ?? "Away" + return (l, r) + } + + var body: some View { + VStack(spacing: 0) { + StatusBarView( + matchTitle: store.currentSession.title, + isAirplane: true, + latencyMs: store.lastLatencyMs + ) + subHeader + ZStack { + DottedGrid() + HStack(alignment: .top, spacing: 0) { + teamColumn( + teamName: teams.left, + accentHex: "#7AB8E3", + filter: $leftFilter + ) + Rectangle().fill(Color.bbBorder).frame(width: 1) + teamColumn( + teamName: teams.right, + accentHex: "#D06060", + filter: $rightFilter + ) + } + } + } + .background(Color.bgBase) + } + + // MARK: - Sub-header + + private var subHeader: some View { + HStack(spacing: 0) { + // Left cluster + HStack(spacing: 10) { + Text("SPOTTING BOARD") + .font(Typography.sectionHead) + .foregroundStyle(Color.textSubtle) + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + Circle().fill(Color.verified).frame(width: 6, height: 6) + Text("STATS-FIRST") + .font(Typography.chip) + .foregroundStyle(Color.verified) + Image(systemName: "checkmark") + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .foregroundStyle(Color.verified) + } + .padding(.leading, 20) + + Spacer() + + // Right cluster + HStack(spacing: 0) { + styleButton + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + casesButton + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + densityPicker + } + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + .clipShape(RoundedRectangle(cornerRadius: 4)) + .padding(.trailing, 20) + } + .frame(height: 44) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + private var styleButton: some View { + Button { + store.spottingMode = nil + } label: { + Text("MY STYLE") + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + .padding(.horizontal, 12) + .padding(.vertical, 6) + .background(Color.bgHover) + } + .buttonStyle(.plain) + } + + private var casesButton: some View { + Button {} label: { + Text("CASES") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 12) + .padding(.vertical, 6) + } + .buttonStyle(.plain) + } + + private var densityPicker: some View { + HStack(spacing: 0) { + ForEach(BoardDensity.allCases, id: \.self) { d in + Button { density = d } label: { + Text(d.rawValue) + .font(Typography.chip) + .foregroundStyle(density == d ? Color.textPrimary : Color.textSubtle) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(density == d ? Color.bgHover : Color.clear) + } + .buttonStyle(.plain) + if d != BoardDensity.allCases.last { + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + } + } + } + } + + // MARK: - Team column + + private func teamColumn(teamName: String, accentHex: String, filter: Binding) -> some View { + let accent = Color(hex: accentHex) + let allPlayers = (store.matchCache?.players ?? []).filter { $0.team == teamName } + let query = filter.wrappedValue.lowercased() + let players = query.isEmpty ? allPlayers : allPlayers.filter { + $0.name.lowercased().contains(query) || $0.position.lowercased().contains(query) + } + let pinned = players.filter { pinnedIds.contains($0.name) } + let unpinned = players.filter { !pinnedIds.contains($0.name) } + + return VStack(alignment: .leading, spacing: 0) { + // Column header + columnHeader(teamName: teamName, accent: accent, playerCount: allPlayers.count) + + // Filter bar + filterBar(placeholder: "FILTER \(teamName.uppercased()) PLAYERS...", text: filter) + + // Player list + ScrollView { + LazyVStack(spacing: 6) { + ForEach(pinned + unpinned, id: \.name) { player in + StatsPlayerCard( + player: player, + density: density, + isPinned: pinnedIds.contains(player.name), + onTogglePin: { + if pinnedIds.contains(player.name) { + pinnedIds.remove(player.name) + } else { + pinnedIds.insert(player.name) + } + } + ) + } + } + .padding(12) + } + } + .frame(maxWidth: .infinity) + .background(Color.bgBase) + } + + private func columnHeader(teamName: String, accent: Color, playerCount: Int) -> some View { + HStack(spacing: 8) { + Circle().fill(accent).frame(width: 8, height: 8) + Text(teamName.uppercased()) + .font(.system(size: 13, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + Text(String(teamName.prefix(3)).uppercased()) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 6) + .padding(.vertical, 2) + .background(accent.opacity(0.15), in: RoundedRectangle(cornerRadius: 3)) + + Spacer() + Text("\(playerCount) PLAYERS") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + SportradarBadge() + } + .padding(.horizontal, 12) + .padding(.vertical, 10) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + private func filterBar(placeholder: String, text: Binding) -> some View { + HStack(spacing: 8) { + Image(systemName: "line.3.horizontal.decrease") + .font(.system(size: 11)) + .foregroundStyle(Color.textSubtle) + TextField(placeholder, text: text) + .textFieldStyle(.plain) + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + } + .padding(.horizontal, 12) + .padding(.vertical, 8) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } +} + +// MARK: - Player Card + +private struct StatsPlayerCard: View { + let player: Player + let density: BoardDensity + let isPinned: Bool + let onTogglePin: () -> Void + + @State private var hovered = false + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + cardHeader + if density != .compact { + Divider().background(Color.bbBorder).padding(.horizontal, 12) + statsGrid.padding(.horizontal, 12).padding(.top, 10).padding(.bottom, 8) + } + if density == .full { + Divider().background(Color.bbBorder).padding(.horizontal, 12) + fullExtra.padding(.horizontal, 12).padding(.vertical, 8) + } + HStack { + SportradarBadge() + Spacer() + } + .padding(.horizontal, 12) + .padding(.bottom, 8) + } + .background(hovered ? Color.bgHover : Color.bgRaised) + .overlay( + RoundedRectangle(cornerRadius: 5) + .stroke(isPinned ? Color.verified.opacity(0.5) : Color.bbBorder, lineWidth: isPinned ? 1.5 : 1) + ) + .clipShape(RoundedRectangle(cornerRadius: 5)) + .onHover { hovered = $0 } + } + + // Jersey + name + pin + edit + private var cardHeader: some View { + HStack(alignment: .top, spacing: 8) { + Text(player.jersey) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .frame(width: 20, alignment: .leading) + + VStack(alignment: .leading, spacing: 3) { + HStack(spacing: 6) { + Text(player.name.uppercased()) + .font(.system(size: 13, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + .lineLimit(1) + .minimumScaleFactor(0.8) + + if isPinned { + HStack(spacing: 3) { + Image(systemName: "pin.fill") + .font(.system(size: 8)) + Text("PINNED") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + } + .foregroundStyle(Color.bgBase) + .padding(.horizontal, 5) + .padding(.vertical, 2) + .background(Color.verified, in: RoundedRectangle(cornerRadius: 2)) + } + + Spacer() + + Button(action: onTogglePin) { + Image(systemName: isPinned ? "pin.slash" : "pin") + .font(.system(size: 11)) + .foregroundStyle(isPinned ? Color.verified : Color.textSubtle) + } + .buttonStyle(.plain) + } + + // Position tags + let tags = positionTags + if !tags.isEmpty { + HStack(spacing: 4) { + ForEach(tags, id: \.self) { tag in + Text(tag) + .font(.system(size: 9, weight: .medium, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + } + } + } + } + } + .padding(.horizontal, 12) + .padding(.top, 10) + .padding(.bottom, density == .compact ? 8 : 6) + } + + // Three big stat columns + private var statsGrid: some View { + let slots = statSlots + return HStack(alignment: .top, spacing: 0) { + ForEach(slots.indices, id: \.self) { i in + let slot = slots[i] + VStack(alignment: .leading, spacing: 2) { + Text(slot.value) + .font(.system(size: 22, weight: .medium, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + .lineLimit(1) + .minimumScaleFactor(0.6) + Text(slot.label) + .font(.system(size: 9, weight: .regular, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + .lineLimit(2) + } + .frame(maxWidth: .infinity, alignment: .leading) + if i < slots.count - 1 { + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 36) + .padding(.horizontal, 8) + } + } + } + } + + // Tactical note shown in full density + private var fullExtra: some View { + HStack(alignment: .top, spacing: 6) { + Image(systemName: "arrow.triangle.branch") + .font(.system(size: 10)) + .foregroundStyle(Color.esoteric) + .padding(.top, 1) + Text(player.keyStats["tactical"] ?? "—") + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + .fixedSize(horizontal: false, vertical: true) + } + } + + // Parse "5.2 xG · Top-3 this WC" → ("5.2", "xG") + private var statSlots: [(value: String, label: String)] { + let keys = ["stat1", "stat2", "stat3"] + return keys.compactMap { key -> (String, String)? in + guard let raw = player.keyStats[key], !raw.isEmpty else { return nil } + let clean = raw.components(separatedBy: " · ").first ?? raw + let parts = clean.components(separatedBy: " ") + let val = parts.first ?? "—" + let lbl = parts.dropFirst().joined(separator: " ") + return (val.isEmpty ? "—" : val, lbl.isEmpty ? key : lbl) + } + } + + private var positionTags: [String] { + var tags = [player.position] + if let s1 = player.keyStats["stat1"] { + // Pull highlighted segment after · + let parts = s1.components(separatedBy: " · ") + if parts.count > 1 { tags.append(parts[1]) } + } + return tags.filter { !$0.isEmpty } + } +} diff --git a/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift b/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift new file mode 100644 index 00000000..fa49129f --- /dev/null +++ b/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift @@ -0,0 +1,401 @@ +import SwiftUI + +struct StoryFirstSpottingBoardView: View { + @Environment(AppStore.self) private var store + @State private var leftFilter: String = "" + @State private var rightFilter: String = "" + @State private var pinnedIds: Set = [] + @State private var expandedIds: Set = [] + + private var teams: (left: String, right: String) { + let parts = store.currentSession.title.components(separatedBy: " vs ") + let l = parts.first?.components(separatedBy: " ·").first?.trimmingCharacters(in: .whitespaces) ?? "Home" + let r = parts.dropFirst().first?.components(separatedBy: " ·").first?.trimmingCharacters(in: .whitespaces) ?? "Away" + return (l, r) + } + + var body: some View { + VStack(spacing: 0) { + StatusBarView( + matchTitle: store.currentSession.title, + isAirplane: true, + latencyMs: store.lastLatencyMs + ) + subHeader + ZStack { + DottedGrid() + HStack(alignment: .top, spacing: 0) { + teamColumn(teamName: teams.left, accentHex: "#7AB8E3", filter: $leftFilter) + Rectangle().fill(Color.bbBorder).frame(width: 1) + teamColumn(teamName: teams.right, accentHex: "#D06060", filter: $rightFilter) + } + } + } + .background(Color.bgBase) + } + + // MARK: Sub-header + + private var subHeader: some View { + HStack(spacing: 0) { + HStack(spacing: 10) { + Text("SPOTTING BOARD") + .font(Typography.sectionHead) + .foregroundStyle(Color.textSubtle) + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + Circle().fill(Color.esoteric).frame(width: 6, height: 6) + Text("STORY-FIRST") + .font(Typography.chip) + .foregroundStyle(Color.esoteric) + Image(systemName: "checkmark") + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .foregroundStyle(Color.esoteric) + } + .padding(.leading, 20) + + Spacer() + + HStack(spacing: 0) { + Button { store.spottingMode = nil } label: { + Text("MY STYLE") + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + .padding(.horizontal, 12) + .padding(.vertical, 6) + .background(Color.bgHover) + } + .buttonStyle(.plain) + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + Button {} label: { + Text("CASES") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 12) + .padding(.vertical, 6) + } + .buttonStyle(.plain) + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + strandPicker + } + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + .clipShape(RoundedRectangle(cornerRadius: 4)) + .padding(.trailing, 20) + } + .frame(height: 44) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + @State private var strandFilter: StoryStrand = .all + + private var strandPicker: some View { + HStack(spacing: 0) { + ForEach(StoryStrand.allCases, id: \.self) { s in + Button { strandFilter = s } label: { + Text(s.label) + .font(Typography.chip) + .foregroundStyle(strandFilter == s ? Color.textPrimary : Color.textSubtle) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(strandFilter == s ? Color.bgHover : Color.clear) + } + .buttonStyle(.plain) + if s != StoryStrand.allCases.last { + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + } + } + } + } + + // MARK: Team column + + private func teamColumn(teamName: String, accentHex: String, filter: Binding) -> some View { + let accent = Color(hex: accentHex) + let all = (store.matchCache?.players ?? []).filter { $0.team == teamName } + let query = filter.wrappedValue.lowercased() + var filtered = query.isEmpty ? all : all.filter { + $0.name.lowercased().contains(query) || $0.position.lowercased().contains(query) + } + if strandFilter != .all { + filtered = filtered.filter { strandFilter.matches($0) } + } + let pinned = filtered.filter { pinnedIds.contains($0.name) } + let unpinned = filtered.filter { !pinnedIds.contains($0.name) } + + return VStack(alignment: .leading, spacing: 0) { + columnHeader(teamName: teamName, accent: accent, playerCount: all.count) + filterBar(placeholder: "FILTER \(teamName.uppercased()) PLAYERS...", text: filter) + ScrollView { + LazyVStack(spacing: 8) { + ForEach(pinned + unpinned, id: \.name) { player in + StoryPlayerCard( + player: player, + isPinned: pinnedIds.contains(player.name), + isExpanded: expandedIds.contains(player.name), + onTogglePin: { + if pinnedIds.contains(player.name) { pinnedIds.remove(player.name) } + else { pinnedIds.insert(player.name) } + }, + onToggleExpand: { + if expandedIds.contains(player.name) { expandedIds.remove(player.name) } + else { expandedIds.insert(player.name) } + } + ) + } + } + .padding(12) + } + } + .frame(maxWidth: .infinity) + .background(Color.bgBase) + } + + private func columnHeader(teamName: String, accent: Color, playerCount: Int) -> some View { + HStack(spacing: 8) { + Circle().fill(accent).frame(width: 8, height: 8) + Text(teamName.uppercased()) + .font(.system(size: 13, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + Text(String(teamName.prefix(3)).uppercased()) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 6).padding(.vertical, 2) + .background(accent.opacity(0.15), in: RoundedRectangle(cornerRadius: 3)) + Spacer() + Text("\(playerCount) PLAYERS") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + SportradarBadge() + } + .padding(.horizontal, 12).padding(.vertical, 10) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + private func filterBar(placeholder: String, text: Binding) -> some View { + HStack(spacing: 8) { + Image(systemName: "line.3.horizontal.decrease") + .font(.system(size: 11)).foregroundStyle(Color.textSubtle) + TextField(placeholder, text: text) + .textFieldStyle(.plain) + .font(Typography.chip).foregroundStyle(Color.textMuted) + } + .padding(.horizontal, 12).padding(.vertical, 8) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } +} + +// MARK: - Story strand filter + +enum StoryStrand: CaseIterable { + case all, arcs, milestones, rivalries + + var label: String { + switch self { + case .all: return "ALL" + case .arcs: return "ARCS" + case .milestones: return "MILESTONES" + case .rivalries: return "RIVALRIES" + } + } + + func matches(_ player: Player) -> Bool { + switch self { + case .all: return true + case .arcs: + return player.keyStats["storyHero"] != nil + case .milestones: + let hero = (player.keyStats["storyHero"] ?? "").lowercased() + return hero.contains("first") || hero.contains("record") || hero.contains("final") || hero.contains("hat-trick") + case .rivalries: + return (player.keyStats["stat4"] ?? "").contains("vs") || (player.keyStats["storyHero"] ?? "").lowercased().contains("vs") + } + } +} + +// MARK: - Story Player Card + +private struct StoryPlayerCard: View { + let player: Player + let isPinned: Bool + let isExpanded: Bool + let onTogglePin: () -> Void + let onToggleExpand: () -> Void + + @State private var hovered = false + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + cardHeader + Divider().background(Color.bbBorder).padding(.horizontal, 12) + storyBody + if isExpanded { expandedStats } + cardFooter + } + .background(hovered ? Color.bgHover : Color.bgRaised) + .overlay( + RoundedRectangle(cornerRadius: 5) + .stroke(isPinned ? Color.esoteric.opacity(0.6) : Color.bbBorder, + lineWidth: isPinned ? 1.5 : 1) + ) + .clipShape(RoundedRectangle(cornerRadius: 5)) + .onHover { hovered = $0 } + } + + // Jersey + name + pin + expand + private var cardHeader: some View { + HStack(alignment: .top, spacing: 8) { + Text(player.jersey) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .frame(width: 20, alignment: .leading) + + VStack(alignment: .leading, spacing: 3) { + HStack(spacing: 6) { + Text(player.name.uppercased()) + .font(.system(size: 13, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + .lineLimit(1).minimumScaleFactor(0.8) + + if isPinned { + HStack(spacing: 3) { + Image(systemName: "pin.fill").font(.system(size: 8)) + Text("PINNED").font(.system(size: 9, weight: .semibold, design: .monospaced)) + } + .foregroundStyle(Color.bgBase) + .padding(.horizontal, 5).padding(.vertical, 2) + .background(Color.esoteric, in: RoundedRectangle(cornerRadius: 2)) + } + + Spacer() + + Button(action: onTogglePin) { + Image(systemName: isPinned ? "pin.slash" : "pin") + .font(.system(size: 11)) + .foregroundStyle(isPinned ? Color.esoteric : Color.textSubtle) + } + .buttonStyle(.plain) + } + + HStack(spacing: 4) { + Text(player.position) + .font(.system(size: 9, weight: .medium, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + if hasStory { + Text("·") + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + Text("HAS ARC") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.esoteric) + } + } + } + } + .padding(.horizontal, 12).padding(.top, 10).padding(.bottom, 8) + } + + // The main story beat + private var storyBody: some View { + VStack(alignment: .leading, spacing: 8) { + // Headline arc + Text(headline) + .font(.system(size: 14, weight: .medium, design: .monospaced)) + .foregroundStyle(hasStory ? Color.textPrimary : Color.textMuted) + .italic() + .fixedSize(horizontal: false, vertical: true) + .lineSpacing(3) + + // Context lines + VStack(alignment: .leading, spacing: 4) { + ForEach(contextLines, id: \.self) { line in + HStack(alignment: .top, spacing: 6) { + Rectangle() + .fill(Color.esoteric.opacity(0.6)) + .frame(width: 2, height: 10) + .padding(.top, 3) + Text(line) + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + .fixedSize(horizontal: false, vertical: true) + } + } + } + + // Expand / collapse toggle + if hasExpandableStats { + Button(action: onToggleExpand) { + HStack(spacing: 4) { + Text(isExpanded ? "HIDE STATS" : "SHOW STATS") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + Image(systemName: isExpanded ? "chevron.up" : "chevron.down") + .font(.system(size: 8, weight: .semibold)) + .foregroundStyle(Color.textSubtle) + } + } + .buttonStyle(.plain) + } + } + .padding(.horizontal, 12).padding(.vertical, 10) + } + + // Inline stats revealed on expand + private var expandedStats: some View { + VStack(alignment: .leading, spacing: 6) { + Divider().background(Color.bbBorder).padding(.horizontal, 12) + VStack(alignment: .leading, spacing: 4) { + ForEach(allStatLines, id: \.self) { line in + HStack(spacing: 6) { + Image(systemName: "chart.bar.fill") + .font(.system(size: 9)) + .foregroundStyle(Color.verified) + Text(line) + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + } + } + } + .padding(.horizontal, 12).padding(.vertical, 8) + } + } + + private var cardFooter: some View { + HStack { + SportradarBadge() + Spacer() + } + .padding(.horizontal, 12).padding(.bottom, 8) + } + + // MARK: Helpers + + private var hasStory: Bool { player.keyStats["storyHero"] != nil } + + private var headline: String { + if let hero = player.keyStats["storyHero"] { return hero } + if let s1 = player.keyStats["stat1"] { return s1 } + return "No narrative arc seeded." + } + + private var contextLines: [String] { + var lines: [String] = [] + if player.keyStats["storyHero"] != nil { + if let s1 = player.keyStats["stat1"] { lines.append(s1) } + if let s2 = player.keyStats["stat2"] { lines.append(s2) } + } else { + if let s2 = player.keyStats["stat2"] { lines.append(s2) } + if let s3 = player.keyStats["stat3"] { lines.append(s3) } + } + return lines + } + + private var hasExpandableStats: Bool { + player.keyStats["stat1"] != nil || player.keyStats["stat2"] != nil + } + + private var allStatLines: [String] { + ["stat1", "stat2", "stat3", "stat4"].compactMap { player.keyStats[$0] } + } +} diff --git a/BroadcastBrain/Views/TacticalSpottingBoardView.swift b/BroadcastBrain/Views/TacticalSpottingBoardView.swift new file mode 100644 index 00000000..0e5b4955 --- /dev/null +++ b/BroadcastBrain/Views/TacticalSpottingBoardView.swift @@ -0,0 +1,374 @@ +import SwiftUI + +struct TacticalSpottingBoardView: View { + @Environment(AppStore.self) private var store + @State private var leftFilter: String = "" + @State private var rightFilter: String = "" + @State private var pinnedIds: Set = [] + @State private var density: BoardDensity = .standard + + private var teams: (left: String, right: String) { + let parts = store.currentSession.title.components(separatedBy: " vs ") + let l = parts.first?.components(separatedBy: " ·").first?.trimmingCharacters(in: .whitespaces) ?? "Home" + let r = parts.dropFirst().first?.components(separatedBy: " ·").first?.trimmingCharacters(in: .whitespaces) ?? "Away" + return (l, r) + } + + // Known formations for the 2022 WC Final; derived from title as fallback + private let formations: [String: (code: String, shape: String)] = [ + "Argentina": ("ARG", "4-4-2"), + "France": ("FRA", "4-2-3-1"), + ] + + var body: some View { + VStack(spacing: 0) { + StatusBarView( + matchTitle: store.currentSession.title, + isAirplane: true, + latencyMs: store.lastLatencyMs + ) + subHeader + ZStack { + DottedGrid() + HStack(alignment: .top, spacing: 0) { + teamColumn(teamName: teams.left, accentHex: "#7AB8E3", filter: $leftFilter) + Rectangle().fill(Color.bbBorder).frame(width: 1) + teamColumn(teamName: teams.right, accentHex: "#D06060", filter: $rightFilter) + } + } + } + .background(Color.bgBase) + } + + // MARK: Sub-header + + private var subHeader: some View { + HStack(spacing: 0) { + HStack(spacing: 10) { + Text("SPOTTING BOARD") + .font(Typography.sectionHead) + .foregroundStyle(Color.textSubtle) + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + Circle().fill(Color.tactical).frame(width: 6, height: 6) + Text("TACTICAL") + .font(Typography.chip) + .foregroundStyle(Color.tactical) + Image(systemName: "checkmark") + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .foregroundStyle(Color.tactical) + } + .padding(.leading, 20) + + Spacer() + + HStack(spacing: 0) { + Button { store.spottingMode = nil } label: { + Text("MY STYLE") + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + .padding(.horizontal, 12).padding(.vertical, 6) + .background(Color.bgHover) + } + .buttonStyle(.plain) + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + Button {} label: { + Text("CASES") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 12).padding(.vertical, 6) + } + .buttonStyle(.plain) + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + densityPicker + } + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + .clipShape(RoundedRectangle(cornerRadius: 4)) + .padding(.trailing, 20) + } + .frame(height: 44) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + private var densityPicker: some View { + HStack(spacing: 0) { + ForEach(BoardDensity.allCases, id: \.self) { d in + Button { density = d } label: { + Text(d.rawValue) + .font(Typography.chip) + .foregroundStyle(density == d ? Color.textPrimary : Color.textSubtle) + .padding(.horizontal, 10).padding(.vertical, 6) + .background(density == d ? Color.bgHover : Color.clear) + } + .buttonStyle(.plain) + if d != BoardDensity.allCases.last { + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + } + } + } + } + + // MARK: Team column + + private func teamColumn(teamName: String, accentHex: String, filter: Binding) -> some View { + let accent = Color(hex: accentHex) + let all = (store.matchCache?.players ?? []).filter { $0.team == teamName } + let query = filter.wrappedValue.lowercased() + let players = query.isEmpty ? all : all.filter { + $0.name.lowercased().contains(query) || $0.position.lowercased().contains(query) + } + let pinned = players.filter { pinnedIds.contains($0.name) } + let unpinned = players.filter { !pinnedIds.contains($0.name) } + let meta = formations[teamName] + + return VStack(alignment: .leading, spacing: 0) { + columnHeader(teamName: teamName, accent: accent, meta: meta, playerCount: all.count) + filterBar(placeholder: "FILTER \(teamName.uppercased()) PLAYERS...", text: filter) + ScrollView { + LazyVStack(spacing: 6) { + ForEach(pinned + unpinned, id: \.name) { player in + TacticalPlayerCard( + player: player, + density: density, + isPinned: pinnedIds.contains(player.name), + onTogglePin: { + if pinnedIds.contains(player.name) { pinnedIds.remove(player.name) } + else { pinnedIds.insert(player.name) } + } + ) + } + } + .padding(12) + } + } + .frame(maxWidth: .infinity) + .background(Color.bgBase) + } + + private func columnHeader(teamName: String, accent: Color, meta: (code: String, shape: String)?, playerCount: Int) -> some View { + HStack(spacing: 8) { + Circle().fill(accent).frame(width: 8, height: 8) + Text(teamName.uppercased()) + .font(.system(size: 13, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + if let meta { + Text(meta.code) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 6).padding(.vertical, 2) + .background(accent.opacity(0.15), in: RoundedRectangle(cornerRadius: 3)) + Text(meta.shape) + .font(Typography.chip) + .foregroundStyle(Color.tactical) + .padding(.horizontal, 6).padding(.vertical, 2) + .background(Color.tactical.opacity(0.12), in: RoundedRectangle(cornerRadius: 3)) + } + Spacer() + Text("\(playerCount) PLAYERS") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + SportradarBadge() + } + .padding(.horizontal, 12).padding(.vertical, 10) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + private func filterBar(placeholder: String, text: Binding) -> some View { + HStack(spacing: 8) { + Image(systemName: "line.3.horizontal.decrease") + .font(.system(size: 11)).foregroundStyle(Color.textSubtle) + TextField(placeholder, text: text) + .textFieldStyle(.plain) + .font(Typography.chip).foregroundStyle(Color.textMuted) + } + .padding(.horizontal, 12).padding(.vertical, 8) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } +} + +// MARK: - Press zone + +private enum PressZone: String { + case high = "HIGH", mid = "MID", passive = "PASSIVE" + + var color: Color { + switch self { + case .high: return Color.verified + case .mid: return Color.esoteric + case .passive: return Color.textSubtle + } + } + + static func from(position: String, tactical: String?) -> PressZone { + let tac = (tactical ?? "").lowercased() + if tac.contains("press") || tac.contains("high line") { return .high } + if tac.contains("screens") || tac.contains("deep") || tac.contains("drops") { return .passive } + switch position { + case "FW": return .high + case "MF": return .mid + default: return .passive + } + } +} + +// MARK: - Tactical Player Card + +private struct TacticalPlayerCard: View { + let player: Player + let density: BoardDensity + let isPinned: Bool + let onTogglePin: () -> Void + + @State private var hovered = false + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + cardHeader + Divider().background(Color.bbBorder).padding(.horizontal, 12) + tacticalNote + if density != .compact { bottomStats } + if density == .full { statLines } + footerRow + } + .background(hovered ? Color.bgHover : Color.bgRaised) + .overlay( + RoundedRectangle(cornerRadius: 5) + .stroke(isPinned ? Color.tactical.opacity(0.6) : Color.bbBorder, + lineWidth: isPinned ? 1.5 : 1) + ) + .clipShape(RoundedRectangle(cornerRadius: 5)) + .onHover { hovered = $0 } + } + + private var cardHeader: some View { + HStack(alignment: .top, spacing: 8) { + Text(player.jersey) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .frame(width: 20, alignment: .leading) + + VStack(alignment: .leading, spacing: 3) { + HStack(spacing: 6) { + Text(player.name.uppercased()) + .font(.system(size: 13, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + .lineLimit(1).minimumScaleFactor(0.8) + + if isPinned { + HStack(spacing: 3) { + Image(systemName: "pin.fill").font(.system(size: 8)) + Text("PINNED").font(.system(size: 9, weight: .semibold, design: .monospaced)) + } + .foregroundStyle(Color.bgBase) + .padding(.horizontal, 5).padding(.vertical, 2) + .background(Color.tactical, in: RoundedRectangle(cornerRadius: 2)) + } + + Spacer() + + Button(action: onTogglePin) { + Image(systemName: isPinned ? "pin.slash" : "pin") + .font(.system(size: 11)) + .foregroundStyle(isPinned ? Color.tactical : Color.textSubtle) + } + .buttonStyle(.plain) + } + + // Position + press zone inline + HStack(spacing: 6) { + Text(player.position) + .font(.system(size: 9, weight: .medium, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + let zone = PressZone.from(position: player.position, tactical: player.keyStats["tactical"]) + Text("·") + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + Text("PRESS \(zone.rawValue)") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .foregroundStyle(zone.color) + } + } + } + .padding(.horizontal, 12).padding(.top, 10).padding(.bottom, 8) + } + + private var tacticalNote: some View { + Text(player.keyStats["tactical"] ?? "No tactical note.") + .font(.system(size: 12, weight: .regular, design: .monospaced)) + .foregroundStyle(Color.textMuted) + .italic() + .fixedSize(horizontal: false, vertical: true) + .lineSpacing(3) + .padding(.horizontal, 12).padding(.vertical, 10) + } + + // KEY ACTIONS | KEY PASSES | PRESS ZONE + private var bottomStats: some View { + let zone = PressZone.from(position: player.position, tactical: player.keyStats["tactical"]) + let actions = extractNumber(from: player.keyStats["stat1"]) + let passes = extractNumber(from: player.keyStats["stat2"]) + + return HStack(spacing: 0) { + tacticalStatCell(value: actions ?? "—", label: "KEY ACTIONS") + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 30) + tacticalStatCell(value: passes ?? "—", label: "KEY PASSES") + Rectangle().fill(Color.bbBorder).frame(width: 1, height: 30) + VStack(alignment: .leading, spacing: 2) { + Text(zone.rawValue) + .font(.system(size: 14, weight: .semibold, design: .monospaced)) + .foregroundStyle(zone.color) + Text("PRESS ZONE") + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, 12) + } + .padding(.vertical, 8) + .background(Color.bgSubtle) + .overlay(alignment: .top) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + // Full stat lines in expanded density + private var statLines: some View { + VStack(alignment: .leading, spacing: 4) { + ForEach(["stat1","stat2","stat3","stat4"].compactMap({ player.keyStats[$0] }), id: \.self) { line in + HStack(spacing: 6) { + Rectangle().fill(Color.tactical).frame(width: 2, height: 10).padding(.top, 2) + Text(line) + .font(Typography.chip).foregroundStyle(Color.textMuted) + .fixedSize(horizontal: false, vertical: true) + } + } + } + .padding(.horizontal, 12).padding(.vertical, 8) + .overlay(alignment: .top) { Rectangle().fill(Color.bbBorder).frame(height: 1) } + } + + private var footerRow: some View { + HStack { SportradarBadge(); Spacer() } + .padding(.horizontal, 12).padding(.vertical, 6) + } + + private func tacticalStatCell(value: String, label: String) -> some View { + VStack(alignment: .leading, spacing: 2) { + Text(value) + .font(.system(size: 14, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + Text(label) + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + } + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal, 12) + } + + // Extract leading number from strings like "5.2 xG · Top-3" → "5.2", "86% tackle" → "86%" + private func extractNumber(from raw: String?) -> String? { + guard let raw, !raw.isEmpty else { return nil } + let first = raw.components(separatedBy: " ").first ?? "" + return first.isEmpty ? nil : first + } +} diff --git a/BroadcastBrain/Views/TeamSetupView.swift b/BroadcastBrain/Views/TeamSetupView.swift new file mode 100644 index 00000000..c9484604 --- /dev/null +++ b/BroadcastBrain/Views/TeamSetupView.swift @@ -0,0 +1,239 @@ +import SwiftUI + +struct TeamSetupView: View { + @Environment(AppStore.self) private var store + @State private var teamInput: String = "" + @State private var fetchService = GameFetchService() + @State private var error: String? = nil + @State private var isFetching = false + @FocusState private var focused: Bool + + var body: some View { + ZStack { + Color.bgBase.ignoresSafeArea() + DottedGrid() + + VStack(spacing: 0) { + Spacer() + card + Spacer() + } + .padding(40) + } + } + + private var card: some View { + VStack(alignment: .leading, spacing: 0) { + // Header + HStack(spacing: 8) { + Text("BROADCASTBRAIN") + .font(.system(size: 11, weight: .bold, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + Spacer() + HStack(spacing: 4) { + Circle().fill(Color.verified).frame(width: 6, height: 6) + Text("AIRPLANE MODE SAFE") + .font(Typography.chip) + .foregroundStyle(Color.verified) + } + } + .padding(.horizontal, 28).padding(.top, 28).padding(.bottom, 20) + + Divider().background(Color.bbBorder) + + // Main content + VStack(alignment: .leading, spacing: 20) { + VStack(alignment: .leading, spacing: 6) { + Text("Set up tonight's match.") + .font(.system(size: 22, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + Text("Enter a team name — we'll fetch the roster, next game, and storylines.") + .font(Typography.body) + .foregroundStyle(Color.textMuted) + } + + // Input + HStack(spacing: 10) { + Image(systemName: "magnifyingglass") + .font(.system(size: 13)) + .foregroundStyle(Color.textSubtle) + TextField("e.g. Manchester City, Lakers, Yankees…", text: $teamInput) + .textFieldStyle(.plain) + .font(.system(size: 15, weight: .regular, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + .focused($focused) + .disabled(isFetching) + .onSubmit { startFetch() } + } + .padding(14) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke( + focused ? Color.verified.opacity(0.6) : Color.bbBorder, lineWidth: 1)) + + // Progress / error + if isFetching { + progressView + } else if let err = error { + HStack(spacing: 8) { + Image(systemName: "exclamationmark.triangle") + .font(.system(size: 11)) + .foregroundStyle(Color.live) + Text(err) + .font(Typography.chip) + .foregroundStyle(Color.live) + } + } + + // Actions + HStack(spacing: 10) { + Button(action: startFetch) { + HStack(spacing: 6) { + if isFetching { + ProgressView().scaleEffect(0.7).frame(width: 14, height: 14) + } else { + Image(systemName: "arrow.down.circle.fill") + .font(.system(size: 13)) + } + Text(isFetching ? "BUILDING CACHE…" : "BUILD CACHE") + .font(Typography.sectionHead) + } + .foregroundStyle(canFetch ? Color.bgBase : Color.textSubtle) + .padding(.horizontal, 18).padding(.vertical, 10) + .background(canFetch ? Color.verified : Color.bgSubtle, + in: RoundedRectangle(cornerRadius: 4)) + } + .buttonStyle(.plain) + .disabled(!canFetch) + + // Only show skip if a cache already exists + if store.matchCache != nil { + Button("KEEP CURRENT MATCH") { + store.showingSetup = false + } + .buttonStyle(.plain) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + } + } + .padding(28) + + // Quick-pick suggestions + Divider().background(Color.bbBorder) + quickPicks + } + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 8)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.bbBorder, lineWidth: 1)) + .frame(maxWidth: 560) + .onAppear { focused = true } + } + + private var progressView: some View { + VStack(alignment: .leading, spacing: 6) { + ForEach(FetchStep.allCases, id: \.self) { s in + HStack(spacing: 8) { + stepIcon(s) + VStack(alignment: .leading, spacing: 1) { + Text(s.rawValue) + .font(Typography.chip) + .foregroundStyle(labelColor(s)) + if fetchService.step == s && !fetchService.stepDetail.isEmpty { + Text(fetchService.stepDetail) + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + } + } + } + } + } + .padding(14) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + } + + @ViewBuilder + private func stepIcon(_ s: FetchStep) -> some View { + let current = fetchService.step + let idx = FetchStep.allCases.firstIndex(of: s) ?? 0 + let curIdx = FetchStep.allCases.firstIndex(of: current) ?? 0 + if idx < curIdx { + Image(systemName: "checkmark.circle.fill") + .font(.system(size: 11)).foregroundStyle(Color.verified) + } else if idx == curIdx { + ProgressView().scaleEffect(0.6).frame(width: 11, height: 11) + } else { + Circle().stroke(Color.bbBorder, lineWidth: 1).frame(width: 9, height: 9) + .padding(1) + } + } + + private func labelColor(_ s: FetchStep) -> Color { + let idx = FetchStep.allCases.firstIndex(of: s) ?? 0 + let curIdx = FetchStep.allCases.firstIndex(of: fetchService.step) ?? 0 + if idx < curIdx { return Color.verified } + if idx == curIdx { return Color.textPrimary } + return Color.textSubtle + } + + private var quickPicks: some View { + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 6) { + Text("QUICK PICK:") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + ForEach(suggestions, id: \.self) { team in + Button(team) { + teamInput = team + startFetch() + } + .buttonStyle(.plain) + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + .padding(.horizontal, 10).padding(.vertical, 5) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 3)) + .overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.bbBorder, lineWidth: 1)) + .disabled(isFetching) + } + } + .padding(.horizontal, 28).padding(.vertical, 14) + } + } + + private let suggestions = [ + "Manchester City","Arsenal","Real Madrid", + "Los Angeles Lakers","Boston Celtics", + "New York Yankees","Los Angeles Dodgers", + "Toronto Maple Leafs","Edmonton Oilers", + ] + + private var canFetch: Bool { + !isFetching && !teamInput.trimmingCharacters(in: .whitespaces).isEmpty + } + + private func startFetch() { + let name = teamInput.trimmingCharacters(in: .whitespaces) + guard !name.isEmpty, !isFetching else { return } + error = nil + isFetching = true + Task { + do { + let cache = try await fetchService.buildMatchCache(teamName: name) + await MainActor.run { + store.loadMatchCache(cache) + isFetching = false + } + } catch { + await MainActor.run { + self.error = error.localizedDescription + isFetching = false + } + } + } + } +} + +extension FetchStep: CaseIterable { + static var allCases: [FetchStep] { + [.detectingSport, .findingGame, .fetchingRosters, .fetchingNews, .buildingCache, .done] + } +} diff --git a/project.yml b/project.yml index 6b4975c2..2497a323 100644 --- a/project.yml +++ b/project.yml @@ -44,7 +44,7 @@ targets: com.apple.security.app-sandbox: true com.apple.security.device.audio-input: true com.apple.security.files.user-selected.read-write: true - com.apple.security.network.client: false + com.apple.security.network.client: true settings: base: PRODUCT_BUNDLE_IDENTIFIER: com.broadcastbrain.mac diff --git a/src/data/FetchGame.swift b/src/data/FetchGame.swift new file mode 100644 index 00000000..8e1062c6 --- /dev/null +++ b/src/data/FetchGame.swift @@ -0,0 +1,1000 @@ +#!/usr/bin/env swift +/** + * FetchGame.swift — BroadcastBrain overnight game cache builder. + * + * WHAT THIS SCRIPT DOES: + * Run it the night before a game with a team name. It pulls everything the + * spotting board needs — next game details, both rosters, player stats, + * news headlines, and injury reports — then writes it all to + * assets/game_cache.json so the app works in airplane mode during the demo. + * + * HOW IT GETS THE DATA (no paid APIs, no API keys): + * Sport │ API used + * ─────────────┼──────────────────────────────────────── + * Soccer │ ESPN unofficial (site.api.espn.com) + * Basketball │ ESPN unofficial (site.api.espn.com) + * Baseball │ MLB official (statsapi.mlb.com) + * Hockey │ NHL official (api-web.nhle.com) + * News/injury │ Google News RSS (news.google.com/rss) + * + * USAGE: + * swift src/data/FetchGame.swift "Manchester City" + * swift src/data/FetchGame.swift "Los Angeles Lakers" + * swift src/data/FetchGame.swift "New York Yankees" + * swift src/data/FetchGame.swift "Toronto Maple Leafs" + * + * OUTPUT: + * assets/game_cache.json + */ + +import Foundation + +// MARK: - Types + +struct PlayerStats: Codable { + var season: [String: String] + var formLast5: [String: String] + var vsOpponent: [String: String] + enum CodingKeys: String, CodingKey { + case season + case formLast5 = "form_last_5" + case vsOpponent = "vs_opponent" + } +} + +struct Player: Codable { + var id: String + var teamId: String + var shirtNumber: Int + var name: String + var position: String + var age: Int + var stats: PlayerStats + var storyline: String + var matchupNote: String + var topStats: [String] + var status: PlayerStatus + var newsHeadlines: [String] + enum PlayerStatus: String, Codable { case fit, doubtful, injured, suspended } + enum CodingKeys: String, CodingKey { + case id, name, position, age, stats, storyline, status + case teamId = "team_id" + case shirtNumber = "shirt_number" + case matchupNote = "matchup_note" + case topStats = "top_stats" + case newsHeadlines = "news_headlines" + } +} + +struct Team: Codable { + var id: String + var name: String + var colorHex: String + var record: [String: String] + enum CodingKeys: String, CodingKey { + case id, name, record + case colorHex = "color_hex" + } +} + +struct MatchInfo: Codable { + var id: String + var homeTeam: String + var awayTeam: String + var competition: String + var venue: String + var kickoffISO: String + enum CodingKeys: String, CodingKey { + case id, competition, venue + case homeTeam = "home_team" + case awayTeam = "away_team" + case kickoffISO = "kickoff_iso" + } +} + +struct TeamsPayload: Codable { + var home: Team + var away: Team +} + +struct GameCache: Codable { + var match: MatchInfo + var teams: TeamsPayload + var players: [Player] + var storylines: [String] + var source: String + var generatedAt: String + enum CodingKeys: String, CodingKey { + case match, teams, players, storylines, source + case generatedAt = "generated_at" + } +} + +struct GameInfo { + var eventId: String + var homeTeam: String + var awayTeam: String + var homeId: String + var awayId: String + var venue: String + var dateISO: String + var competition: String +} + +struct RawPlayer { + var id: String + var name: String + var number: Int? + var position: String + var age: Int? +} + +typealias SportEntry = (sport: String, league: String, display: String) + +// MARK: - Constants + +let KNOWN_TEAMS: [String: SportEntry] = [ + // Soccer – Premier League + "manchester city": ("soccer", "eng.1", "Premier League"), + "manchester united": ("soccer", "eng.1", "Premier League"), + "liverpool": ("soccer", "eng.1", "Premier League"), + "arsenal": ("soccer", "eng.1", "Premier League"), + "chelsea": ("soccer", "eng.1", "Premier League"), + "tottenham": ("soccer", "eng.1", "Premier League"), + "spurs": ("soccer", "eng.1", "Premier League"), + "newcastle": ("soccer", "eng.1", "Premier League"), + "aston villa": ("soccer", "eng.1", "Premier League"), + "west ham": ("soccer", "eng.1", "Premier League"), + "brighton": ("soccer", "eng.1", "Premier League"), + "everton": ("soccer", "eng.1", "Premier League"), + "fulham": ("soccer", "eng.1", "Premier League"), + "brentford": ("soccer", "eng.1", "Premier League"), + "nottingham forest": ("soccer", "eng.1", "Premier League"), + "wolves": ("soccer", "eng.1", "Premier League"), + "wolverhampton": ("soccer", "eng.1", "Premier League"), + "crystal palace": ("soccer", "eng.1", "Premier League"), + "leicester": ("soccer", "eng.1", "Premier League"), + "ipswich": ("soccer", "eng.1", "Premier League"), + "southampton": ("soccer", "eng.1", "Premier League"), + "leeds": ("soccer", "eng.1", "Premier League"), + // Soccer – La Liga + "real madrid": ("soccer", "esp.1", "La Liga"), + "barcelona": ("soccer", "esp.1", "La Liga"), + "atletico madrid": ("soccer", "esp.1", "La Liga"), + "athletic bilbao": ("soccer", "esp.1", "La Liga"), + "real sociedad": ("soccer", "esp.1", "La Liga"), + "villarreal": ("soccer", "esp.1", "La Liga"), + "sevilla": ("soccer", "esp.1", "La Liga"), + "betis": ("soccer", "esp.1", "La Liga"), + // Soccer – Bundesliga + "bayern munich": ("soccer", "ger.1", "Bundesliga"), + "borussia dortmund": ("soccer", "ger.1", "Bundesliga"), + "bayer leverkusen": ("soccer", "ger.1", "Bundesliga"), + "rb leipzig": ("soccer", "ger.1", "Bundesliga"), + "eintracht frankfurt": ("soccer", "ger.1", "Bundesliga"), + // Soccer – Serie A + "juventus": ("soccer", "ita.1", "Serie A"), + "inter milan": ("soccer", "ita.1", "Serie A"), + "ac milan": ("soccer", "ita.1", "Serie A"), + "napoli": ("soccer", "ita.1", "Serie A"), + "roma": ("soccer", "ita.1", "Serie A"), + "lazio": ("soccer", "ita.1", "Serie A"), + "atalanta": ("soccer", "ita.1", "Serie A"), + "fiorentina": ("soccer", "ita.1", "Serie A"), + // Soccer – Ligue 1 + "paris saint-germain": ("soccer", "fra.1", "Ligue 1"), + "psg": ("soccer", "fra.1", "Ligue 1"), + "monaco": ("soccer", "fra.1", "Ligue 1"), + "marseille": ("soccer", "fra.1", "Ligue 1"), + "lyon": ("soccer", "fra.1", "Ligue 1"), + "nice": ("soccer", "fra.1", "Ligue 1"), + "lille": ("soccer", "fra.1", "Ligue 1"), + // Soccer – MLS + "inter miami": ("soccer", "usa.1", "MLS"), + "la galaxy": ("soccer", "usa.1", "MLS"), + "lafc": ("soccer", "usa.1", "MLS"), + "seattle sounders": ("soccer", "usa.1", "MLS"), + "portland timbers": ("soccer", "usa.1", "MLS"), + "new york city": ("soccer", "usa.1", "MLS"), + "new york red bulls": ("soccer", "usa.1", "MLS"), + "atlanta united": ("soccer", "usa.1", "MLS"), + // NBA + "los angeles lakers": ("basketball", "nba", "NBA"), + "lakers": ("basketball", "nba", "NBA"), + "golden state warriors": ("basketball", "nba", "NBA"), + "warriors": ("basketball", "nba", "NBA"), + "boston celtics": ("basketball", "nba", "NBA"), + "celtics": ("basketball", "nba", "NBA"), + "miami heat": ("basketball", "nba", "NBA"), + "chicago bulls": ("basketball", "nba", "NBA"), + "brooklyn nets": ("basketball", "nba", "NBA"), + "new york knicks": ("basketball", "nba", "NBA"), + "knicks": ("basketball", "nba", "NBA"), + "dallas mavericks": ("basketball", "nba", "NBA"), + "mavs": ("basketball", "nba", "NBA"), + "milwaukee bucks": ("basketball", "nba", "NBA"), + "denver nuggets": ("basketball", "nba", "NBA"), + "phoenix suns": ("basketball", "nba", "NBA"), + "philadelphia 76ers": ("basketball", "nba", "NBA"), + "cleveland cavaliers": ("basketball", "nba", "NBA"), + "oklahoma city thunder": ("basketball", "nba", "NBA"), + "houston rockets": ("basketball", "nba", "NBA"), + "memphis grizzlies": ("basketball", "nba", "NBA"), + "sacramento kings": ("basketball", "nba", "NBA"), + "minnesota timberwolves":("basketball", "nba", "NBA"), + "indiana pacers": ("basketball", "nba", "NBA"), + "new orleans pelicans": ("basketball", "nba", "NBA"), + "toronto raptors": ("basketball", "nba", "NBA"), + "atlanta hawks": ("basketball", "nba", "NBA"), + "orlando magic": ("basketball", "nba", "NBA"), + "washington wizards": ("basketball", "nba", "NBA"), + "detroit pistons": ("basketball", "nba", "NBA"), + "charlotte hornets": ("basketball", "nba", "NBA"), + "portland trail blazers":("basketball", "nba", "NBA"), + "san antonio spurs": ("basketball", "nba", "NBA"), + "utah jazz": ("basketball", "nba", "NBA"), + // MLB + "new york yankees": ("baseball", "mlb", "MLB"), + "yankees": ("baseball", "mlb", "MLB"), + "los angeles dodgers": ("baseball", "mlb", "MLB"), + "dodgers": ("baseball", "mlb", "MLB"), + "boston red sox": ("baseball", "mlb", "MLB"), + "red sox": ("baseball", "mlb", "MLB"), + "chicago cubs": ("baseball", "mlb", "MLB"), + "san francisco giants": ("baseball", "mlb", "MLB"), + "new york mets": ("baseball", "mlb", "MLB"), + "mets": ("baseball", "mlb", "MLB"), + "houston astros": ("baseball", "mlb", "MLB"), + "astros": ("baseball", "mlb", "MLB"), + "atlanta braves": ("baseball", "mlb", "MLB"), + "braves": ("baseball", "mlb", "MLB"), + "philadelphia phillies": ("baseball", "mlb", "MLB"), + "phillies": ("baseball", "mlb", "MLB"), + "st. louis cardinals": ("baseball", "mlb", "MLB"), + "cardinals": ("baseball", "mlb", "MLB"), + "seattle mariners": ("baseball", "mlb", "MLB"), + "mariners": ("baseball", "mlb", "MLB"), + "chicago white sox": ("baseball", "mlb", "MLB"), + "minnesota twins": ("baseball", "mlb", "MLB"), + "cleveland guardians": ("baseball", "mlb", "MLB"), + "miami marlins": ("baseball", "mlb", "MLB"), + "tampa bay rays": ("baseball", "mlb", "MLB"), + "toronto blue jays": ("baseball", "mlb", "MLB"), + "blue jays": ("baseball", "mlb", "MLB"), + "baltimore orioles": ("baseball", "mlb", "MLB"), + "orioles": ("baseball", "mlb", "MLB"), + "texas rangers": ("baseball", "mlb", "MLB"), + "kansas city royals": ("baseball", "mlb", "MLB"), + "royals": ("baseball", "mlb", "MLB"), + "oakland athletics": ("baseball", "mlb", "MLB"), + "athletics": ("baseball", "mlb", "MLB"), + "colorado rockies": ("baseball", "mlb", "MLB"), + "rockies": ("baseball", "mlb", "MLB"), + "san diego padres": ("baseball", "mlb", "MLB"), + "padres": ("baseball", "mlb", "MLB"), + "cincinnati reds": ("baseball", "mlb", "MLB"), + "pittsburgh pirates": ("baseball", "mlb", "MLB"), + "detroit tigers": ("baseball", "mlb", "MLB"), + "tigers": ("baseball", "mlb", "MLB"), + "arizona diamondbacks": ("baseball", "mlb", "MLB"), + "milwaukee brewers": ("baseball", "mlb", "MLB"), + "brewers": ("baseball", "mlb", "MLB"), + "washington nationals": ("baseball", "mlb", "MLB"), + "los angeles angels": ("baseball", "mlb", "MLB"), + "angels": ("baseball", "mlb", "MLB"), + // NHL + "toronto maple leafs": ("hockey", "nhl", "NHL"), + "leafs": ("hockey", "nhl", "NHL"), + "montreal canadiens": ("hockey", "nhl", "NHL"), + "canadiens": ("hockey", "nhl", "NHL"), + "boston bruins": ("hockey", "nhl", "NHL"), + "bruins": ("hockey", "nhl", "NHL"), + "new york rangers": ("hockey", "nhl", "NHL"), + "edmonton oilers": ("hockey", "nhl", "NHL"), + "oilers": ("hockey", "nhl", "NHL"), + "colorado avalanche": ("hockey", "nhl", "NHL"), + "avalanche": ("hockey", "nhl", "NHL"), + "tampa bay lightning": ("hockey", "nhl", "NHL"), + "lightning": ("hockey", "nhl", "NHL"), + "vegas golden knights": ("hockey", "nhl", "NHL"), + "golden knights": ("hockey", "nhl", "NHL"), + "carolina hurricanes": ("hockey", "nhl", "NHL"), + "hurricanes": ("hockey", "nhl", "NHL"), + "florida panthers": ("hockey", "nhl", "NHL"), + "panthers": ("hockey", "nhl", "NHL"), + "dallas stars": ("hockey", "nhl", "NHL"), + "stars": ("hockey", "nhl", "NHL"), + "new york islanders": ("hockey", "nhl", "NHL"), + "islanders": ("hockey", "nhl", "NHL"), + "new jersey devils": ("hockey", "nhl", "NHL"), + "devils": ("hockey", "nhl", "NHL"), + "pittsburgh penguins": ("hockey", "nhl", "NHL"), + "penguins": ("hockey", "nhl", "NHL"), + "detroit red wings": ("hockey", "nhl", "NHL"), + "red wings": ("hockey", "nhl", "NHL"), + "nashville predators": ("hockey", "nhl", "NHL"), + "predators": ("hockey", "nhl", "NHL"), + "minnesota wild": ("hockey", "nhl", "NHL"), + "wild": ("hockey", "nhl", "NHL"), + "winnipeg jets": ("hockey", "nhl", "NHL"), + "jets": ("hockey", "nhl", "NHL"), + "st. louis blues": ("hockey", "nhl", "NHL"), + "blues": ("hockey", "nhl", "NHL"), + "seattle kraken": ("hockey", "nhl", "NHL"), + "kraken": ("hockey", "nhl", "NHL"), + "chicago blackhawks": ("hockey", "nhl", "NHL"), + "blackhawks": ("hockey", "nhl", "NHL"), + "ottawa senators": ("hockey", "nhl", "NHL"), + "senators": ("hockey", "nhl", "NHL"), + "calgary flames": ("hockey", "nhl", "NHL"), + "flames": ("hockey", "nhl", "NHL"), + "vancouver canucks": ("hockey", "nhl", "NHL"), + "canucks": ("hockey", "nhl", "NHL"), + "buffalo sabres": ("hockey", "nhl", "NHL"), + "sabres": ("hockey", "nhl", "NHL"), + "san jose sharks": ("hockey", "nhl", "NHL"), + "sharks": ("hockey", "nhl", "NHL"), + "philadelphia flyers": ("hockey", "nhl", "NHL"), + "flyers": ("hockey", "nhl", "NHL"), + "anaheim ducks": ("hockey", "nhl", "NHL"), + "ducks": ("hockey", "nhl", "NHL"), + "columbus blue jackets": ("hockey", "nhl", "NHL"), + "washington capitals": ("hockey", "nhl", "NHL"), + "capitals": ("hockey", "nhl", "NHL"), +] + +let ESPN_LEAGUES: [(String, String)] = [ + ("soccer", "eng.1"), ("soccer", "esp.1"), ("soccer", "ger.1"), + ("soccer", "ita.1"), ("soccer", "fra.1"), ("soccer", "usa.1"), + ("basketball", "nba"), +] + +let TEAM_COLORS: [String: String] = [ + "manchester city": "#6CABDD", "manchester united": "#DA291C", + "liverpool": "#C8102E", "arsenal": "#EF0107", + "chelsea": "#034694", "tottenham": "#132257", + "newcastle": "#241F20", "aston villa": "#95BFE5", + "real madrid": "#FEBE10", "barcelona": "#A50044", + "atletico madrid": "#CB3524", "juventus": "#000000", + "inter milan": "#010E80", "ac milan": "#FB090B", + "napoli": "#087AC6", "paris saint-germain": "#004170", + "bayern munich": "#DC052D", "borussia dortmund": "#FDE100", + "los angeles lakers": "#552583", "golden state warriors": "#1D428A", + "boston celtics": "#007A33", "chicago bulls": "#CE1141", + "miami heat": "#98002E", "brooklyn nets": "#000000", + "new york yankees": "#003087","los angeles dodgers": "#005A9C", + "boston red sox": "#BD3039", "chicago cubs": "#0E3386", + "houston astros": "#002D62", "atlanta braves": "#CE1141", + "toronto maple leafs": "#003E7E", "montreal canadiens": "#AF1E2D", + "boston bruins": "#FFB81C", "edmonton oilers": "#FF4C00", + "colorado avalanche": "#6F263D", "tampa bay lightning": "#002868", + "default": "#1A1A2E", +] + +let NHL_ABBREVS: [String: String] = [ + "toronto": "TOR", "maple leafs": "TOR", "leafs": "TOR", + "montreal": "MTL", "canadiens": "MTL", + "boston": "BOS", "bruins": "BOS", + "new york rangers": "NYR", "rangers": "NYR", + "new york islanders": "NYI", "islanders": "NYI", + "new jersey": "NJD", "devils": "NJD", + "philadelphia": "PHI", "flyers": "PHI", + "pittsburgh": "PIT", "penguins": "PIT", + "buffalo": "BUF", "sabres": "BUF", + "detroit": "DET", "red wings": "DET", + "ottawa": "OTT", "senators": "OTT", + "carolina": "CAR", "hurricanes": "CAR", + "washington": "WSH", "capitals": "WSH", + "columbus": "CBJ", "blue jackets": "CBJ", + "florida": "FLA", "panthers": "FLA", + "tampa bay": "TBL","lightning": "TBL", + "nashville": "NSH","predators": "NSH", + "chicago": "CHI", "blackhawks": "CHI", + "st. louis": "STL","blues": "STL", + "minnesota": "MIN","wild": "MIN", + "winnipeg": "WPG", "jets": "WPG", + "dallas": "DAL", "stars": "DAL", + "colorado": "COL", "avalanche": "COL", + "edmonton": "EDM", "oilers": "EDM", + "calgary": "CGY", "flames": "CGY", + "vancouver": "VAN","canucks": "VAN", + "seattle": "SEA", "kraken": "SEA", + "vegas": "VGK", "golden knights": "VGK", + "utah": "UTA", "arizona": "UTA", + "san jose": "SJS", "sharks": "SJS", + "anaheim": "ANA", "ducks": "ANA", + "los angeles": "LAK", "kings": "LAK", +] + +// MARK: - HTTP Helpers + +let HTTP_HEADERS: [String: String] = [ + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36", + "Accept-Language": "en-US,en;q=0.9", +] + +func logErr(_ msg: String) { + fputs(" \(msg)\n", stderr) +} + +func getJSON(url: URL) async -> Any? { + try? await Task.sleep(nanoseconds: 500_000_000) + var req = URLRequest(url: url) + for (k, v) in HTTP_HEADERS { req.setValue(v, forHTTPHeaderField: k) } + guard let (data, resp) = try? await URLSession.shared.data(for: req), + (resp as? HTTPURLResponse)?.statusCode == 200 else { + logErr("[http] failed: \(url.absoluteString.suffix(80))") + return nil + } + return try? JSONSerialization.jsonObject(with: data) +} + +func getXML(url: URL) async -> String? { + try? await Task.sleep(nanoseconds: 500_000_000) + var req = URLRequest(url: url) + for (k, v) in HTTP_HEADERS { req.setValue(v, forHTTPHeaderField: k) } + guard let (data, resp) = try? await URLSession.shared.data(for: req), + (resp as? HTTPURLResponse)?.statusCode == 200 else { return nil } + return String(data: data, encoding: .utf8) +} + +// MARK: - Sport Detection + +func detectSport(teamName: String) async -> SportEntry { + let lower = teamName.lowercased().trimmingCharacters(in: .whitespaces) + for (key, entry) in KNOWN_TEAMS { + if key.contains(lower) || lower.contains(key) { + logErr("[detect] matched known team: '\(key)' → \(entry.display)") + return entry + } + } + logErr("[detect] not in known list, searching ESPN leagues...") + for (sport, league) in ESPN_LEAGUES { + guard let url = URL(string: "https://site.api.espn.com/apis/site/v2/sports/\(sport)/\(league)/teams"), + let data = await getJSON(url: url) as? [String: Any], + let teams = (data["sports"] as? [[String: Any]])?.first?["leagues"] as? [[String: Any]], + let entries = teams.first?["teams"] as? [[String: Any]] else { continue } + for entry in entries { + let t = entry["team"] as? [String: Any] ?? [:] + let name = (t["displayName"] as? String ?? "").lowercased() + let nick = (t["nickname"] as? String ?? "").lowercased() + if lower.contains(name) || name.contains(lower) || nick.contains(lower) { + logErr("[detect] ESPN match: \(t["displayName"] as? String ?? "") in \(league)") + return (sport, league, league.uppercased()) + } + } + } + logErr("[detect] could not detect sport, defaulting to PL soccer") + return ("soccer", "eng.1", "Premier League") +} + +// MARK: - ESPN (soccer + basketball) + +let ESPN_BASE = "https://site.api.espn.com/apis/site/v2/sports" +let ESPN_CORE = "https://sports.core.api.espn.com/v2/sports" + +func espnFindTeamId(teamName: String, sport: String, league: String) async -> String? { + guard let url = URL(string: "\(ESPN_BASE)/\(sport)/\(league)/teams"), + let data = await getJSON(url: url) as? [String: Any], + let teams = ((data["sports"] as? [[String: Any]])?.first?["leagues"] as? [[String: Any]])?.first?["teams"] as? [[String: Any]] else { return nil } + let lower = teamName.lowercased() + var bestId: String? = nil + var bestScore = 0 + for entry in teams { + let t = entry["team"] as? [String: Any] ?? [:] + let name = (t["displayName"] as? String ?? "").lowercased() + let nick = (t["nickname"] as? String ?? "").lowercased() + let slug = (t["slug"] as? String ?? "").lowercased() + var score = 0 + if lower == name { score = 100 } + else if lower.contains(name) || name.contains(lower){ score = 80 } + else if nick.contains(lower) || lower.contains(nick){ score = 60 } + else if slug.contains(lower) { score = 50 } + else if lower.split(separator: " ").filter({ $0.count > 3 }).contains(where: { name.contains($0) }) { score = 30 } + if score > bestScore { bestScore = score; bestId = t["id"] as? String } + } + logErr("[espn] team ID = \(bestId ?? "nil") (score=\(bestScore))") + return bestId +} + +func espnNextGame(teamId: String, sport: String, league: String) async -> GameInfo? { + guard let url = URL(string: "\(ESPN_BASE)/\(sport)/\(league)/teams/\(teamId)/schedule"), + let data = await getJSON(url: url) as? [String: Any], + let events = data["events"] as? [[String: Any]] else { return nil } + for event in events { + guard let comp = (event["competitions"] as? [[String: Any]])?.first else { continue } + let state = ((comp["status"] as? [String: Any])?["type"] as? [String: Any])?["state"] as? String ?? "" + guard state == "pre" else { continue } + let competitors = comp["competitors"] as? [[String: Any]] ?? [] + let home = competitors.first(where: { ($0["homeAway"] as? String) == "home" }) ?? [:] + let away = competitors.first(where: { ($0["homeAway"] as? String) == "away" }) ?? [:] + let homeTeam = home["team"] as? [String: Any] ?? [:] + let awayTeam = away["team"] as? [String: Any] ?? [:] + return GameInfo( + eventId: event["id"] as? String ?? "", + homeTeam: homeTeam["displayName"] as? String ?? "", + awayTeam: awayTeam["displayName"] as? String ?? "", + homeId: homeTeam["id"] as? String ?? "", + awayId: awayTeam["id"] as? String ?? "", + venue: (comp["venue"] as? [String: Any])?["fullName"] as? String ?? "TBD", + dateISO: event["date"] as? String ?? "", + competition: (data["season"] as? [String: Any])?["displayName"] as? String ?? "" + ) + } + return nil +} + +func espnRoster(teamId: String, sport: String, league: String) async -> [RawPlayer] { + guard let url = URL(string: "\(ESPN_BASE)/\(sport)/\(league)/teams/\(teamId)/roster"), + let data = await getJSON(url: url) as? [String: Any], + let athletes = data["athletes"] as? [[String: Any]] else { return [] } + var players: [RawPlayer] = [] + for item in athletes { + if let items = item["items"] as? [[String: Any]] { + players.append(contentsOf: items.map(parseEspnAthlete)) + } else { + players.append(parseEspnAthlete(item)) + } + } + logErr("[espn] roster: \(players.count) players") + return players +} + +func parseEspnAthlete(_ a: [String: Any]) -> RawPlayer { + RawPlayer( + id: a["id"] as? String ?? "", + name: a["displayName"] as? String ?? a["fullName"] as? String ?? "", + number: Int(a["jersey"] as? String ?? ""), + position: (a["position"] as? [String: Any])?["abbreviation"] as? String ?? "", + age: a["age"] as? Int + ) +} + +func espnPlayerStats(playerId: String, sport: String, league: String) async -> [String: String] { + guard let url = URL(string: "\(ESPN_CORE)/\(sport)/leagues/\(league)/athletes/\(playerId)/statistics/0"), + let data = await getJSON(url: url) as? [String: Any], + let categories = (data["splits"] as? [String: Any])?["categories"] as? [[String: Any]] else { return [:] } + var stats: [String: String] = [:] + for cat in categories { + for stat in (cat["stats"] as? [[String: Any]] ?? []) { + let name = stat["displayName"] as? String ?? "" + let value = stat["displayValue"] as? String ?? "—" + if !name.isEmpty && !["", "0", "0.0"].contains(value) { stats[name] = value } + } + } + return stats +} + +func espnTeamNews(teamId: String, sport: String, league: String) async -> [String] { + guard let url = URL(string: "\(ESPN_BASE)/\(sport)/\(league)/news?team=\(teamId)&limit=10"), + let data = await getJSON(url: url) as? [String: Any], + let articles = data["articles"] as? [[String: Any]] else { return [] } + return articles.compactMap { ($0["headline"] as? String)?.trimmingCharacters(in: .whitespaces) } + .filter { !$0.isEmpty }.prefix(6).map { $0 } +} + +// MARK: - MLB + +let MLB_BASE = "https://statsapi.mlb.com/api/v1" + +func mlbFindTeamId(teamName: String) async -> String? { + guard let url = URL(string: "\(MLB_BASE)/teams?sportId=1"), + let data = await getJSON(url: url) as? [String: Any], + let teams = data["teams"] as? [[String: Any]] else { return nil } + let lower = teamName.lowercased() + for team in teams { + let name = (team["name"] as? String ?? "").lowercased() + let short = (team["teamName"] as? String ?? "").lowercased() + if lower.contains(name) || name.contains(lower) || lower.contains(short) { + let id = String(team["id"] as? Int ?? 0) + logErr("[mlb] team ID = \(id) (\(team["name"] as? String ?? ""))") + return id + } + } + return nil +} + +func mlbNextGame(teamId: String) async -> GameInfo? { + guard let url = URL(string: "\(MLB_BASE)/schedule/games/?sportId=1&teamId=\(teamId)"), + let data = await getJSON(url: url) as? [String: Any], + let dates = data["dates"] as? [[String: Any]], !dates.isEmpty, + let game = (dates[0]["games"] as? [[String: Any]])?.first else { return nil } + let homeTeam = (game["teams"] as? [String: Any])?["home"] as? [String: Any] + let awayTeam = (game["teams"] as? [String: Any])?["away"] as? [String: Any] + return GameInfo( + eventId: String(game["gamePk"] as? Int ?? 0), + homeTeam: (homeTeam?["team"] as? [String: Any])?["name"] as? String ?? "", + awayTeam: (awayTeam?["team"] as? [String: Any])?["name"] as? String ?? "", + homeId: String((homeTeam?["team"] as? [String: Any])?["id"] as? Int ?? 0), + awayId: String((awayTeam?["team"] as? [String: Any])?["id"] as? Int ?? 0), + venue: (game["venue"] as? [String: Any])?["name"] as? String ?? "TBD", + dateISO: game["gameDate"] as? String ?? "", + competition: "MLB" + ) +} + +func mlbRoster(teamId: String) async -> [RawPlayer] { + guard let url = URL(string: "\(MLB_BASE)/teams/\(teamId)/roster?season=2026&rosterType=active"), + let data = await getJSON(url: url) as? [String: Any], + let roster = data["roster"] as? [[String: Any]] else { return [] } + let players = roster.map { entry -> RawPlayer in + let person = entry["person"] as? [String: Any] ?? [:] + return RawPlayer( + id: String(person["id"] as? Int ?? 0), + name: person["fullName"] as? String ?? "", + number: Int(entry["jerseyNumber"] as? String ?? ""), + position: (entry["position"] as? [String: Any])?["abbreviation"] as? String ?? "", + age: nil + ) + } + logErr("[mlb] roster: \(players.count) players") + return players +} + +func mlbPlayerStats(playerId: String) async -> [String: String] { + for group in ["hitting", "pitching"] { + guard let url = URL(string: "\(MLB_BASE)/people/\(playerId)/stats?stats=season&season=2026&group=\(group)"), + let data = await getJSON(url: url) as? [String: Any], + let splits = (data["stats"] as? [[String: Any]])?.first?["splits"] as? [[String: Any]], + !splits.isEmpty, + let stat = splits[0]["stat"] as? [String: Any] else { continue } + var result: [String: String] = [:] + for (k, v) in stat { + let s = "\(v)" + if !["0", "0.0", ".000", "", "null"].contains(s) { result[k] = s } + } + if !result.isEmpty { return result } + } + return [:] +} + +// MARK: - NHL + +let NHL_BASE = "https://api-web.nhle.com/v1" + +func nhlAbbrev(teamName: String) -> String? { + let lower = teamName.lowercased() + for (key, abbrev) in NHL_ABBREVS { + if lower.contains(key) { return abbrev } + } + return nil +} + +func nhlNextGame(abbrev: String) async -> GameInfo? { + guard let url = URL(string: "\(NHL_BASE)/club-schedule-season/\(abbrev)/now"), + let data = await getJSON(url: url) as? [String: Any], + let games = data["games"] as? [[String: Any]] else { return nil } + for game in games { + let state = game["gameState"] as? String ?? "" + guard ["FUT", "PRE"].contains(state) else { continue } + let home = game["homeTeam"] as? [String: Any] ?? [:] + let away = game["awayTeam"] as? [String: Any] ?? [:] + let homeName = [home["placeName"] as? [String: Any], home["commonName"] as? [String: Any]] + .compactMap { $0?["default"] as? String }.joined(separator: " ").trimmingCharacters(in: .whitespaces) + let awayName = [away["placeName"] as? [String: Any], away["commonName"] as? [String: Any]] + .compactMap { $0?["default"] as? String }.joined(separator: " ").trimmingCharacters(in: .whitespaces) + return GameInfo( + eventId: String(game["id"] as? Int ?? 0), + homeTeam: homeName, + awayTeam: awayName, + homeId: home["abbrev"] as? String ?? "", + awayId: away["abbrev"] as? String ?? "", + venue: (game["venue"] as? [String: Any])?["default"] as? String ?? "TBD", + dateISO: game["gameDate"] as? String ?? "", + competition: "NHL" + ) + } + return nil +} + +func nhlRoster(abbrev: String) async -> [RawPlayer] { + guard let url = URL(string: "\(NHL_BASE)/roster/\(abbrev)/current"), + let data = await getJSON(url: url) as? [String: Any] else { return [] } + var players: [RawPlayer] = [] + for group in ["forwards", "defensemen", "goalies"] { + for p in (data[group] as? [[String: Any]] ?? []) { + let firstName = (p["firstName"] as? [String: Any])?["default"] as? String ?? "" + let lastName = (p["lastName"] as? [String: Any])?["default"] as? String ?? "" + let birthDate = p["birthDate"] as? String ?? "" + players.append(RawPlayer( + id: String(p["id"] as? Int ?? 0), + name: "\(firstName) \(lastName)".trimmingCharacters(in: .whitespaces), + number: p["sweaterNumber"] as? Int, + position: p["positionCode"] as? String ?? "", + age: birthDate.isEmpty ? nil : calcAge(birthDate: birthDate) + )) + } + } + logErr("[nhl] roster: \(players.count) players") + return players +} + +func nhlPlayerStats(playerId: String) async -> [String: String] { + guard let url = URL(string: "\(NHL_BASE)/player/\(playerId)/landing"), + let data = await getJSON(url: url) as? [String: Any], + let totals = data["seasonTotals"] as? [[String: Any]], !totals.isEmpty else { return [:] } + let latest = totals[totals.count - 1] + let keys = ["goals","assists","points","plusMinus","pim","shots", + "gamesPlayed","savePctg","goalsAgainstAvg","shutouts","wins"] + var stats: [String: String] = [:] + for key in keys { + if let val = latest[key], "\(val)" != "0" { stats[key] = "\(val)" } + } + return stats +} + +// MARK: - Google News RSS + +func googleNews(query: String, maxResults: Int = 5) async -> [String] { + guard let encoded = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), + let url = URL(string: "https://news.google.com/rss/search?q=\(encoded)&hl=en-US&gl=US&ceid=US:en"), + let xml = await getXML(url: url) else { return [] } + var headlines: [String] = [] + let pattern = try! NSRegularExpression(pattern: "<!\\[CDATA\\[(.*?)\\]\\]>|(.*?)") + let range = NSRange(xml.startIndex..., in: xml) + for match in pattern.matches(in: xml, range: range) { + let raw: String + if let r = Range(match.range(at: 1), in: xml) { raw = String(xml[r]).trimmingCharacters(in: .whitespaces) } + else if let r = Range(match.range(at: 2), in: xml) { raw = String(xml[r]).trimmingCharacters(in: .whitespaces) } + else { continue } + guard !raw.isEmpty, raw != "Google News" else { continue } + let clean = raw.replacingOccurrences(of: "\\s*-\\s*[^-]+$", with: "", options: .regularExpression) + .trimmingCharacters(in: .whitespaces) + if !clean.isEmpty { headlines.append(clean) } + if headlines.count >= maxResults { break } + } + return headlines +} + +func fetchNewsForTeam(_ teamName: String) async -> [String] { await googleNews(query: "\(teamName) news 2026", maxResults: 6) } +func fetchNewsForPlayer(_ name: String, _ team: String) async -> [String] { await googleNews(query: "\(name) \(team) 2026", maxResults: 3) } +func fetchInjuryReport(_ teamName: String) async -> [String] { await googleNews(query: "\(teamName) injury suspended doubtful out 2026", maxResults: 8) } + +// MARK: - Storyline / Status + +func makeStoryline(name: String, position: String, stats: [String: String], news: [String], status: String) -> String { + if ["injured", "doubtful", "suspended"].contains(status) { + return "\(name) is listed as \(status) — his availability is the key team news heading in." + } + if let headline = news.first { + let clean = headline.replacingOccurrences(of: "\\s*-\\s*[^-]+$", with: "", options: .regularExpression).trimmingCharacters(in: .whitespaces) + if clean.count > 10 { return clean } + } + if let (key, val) = stats.first { + return "\(name) brings \(val) \(key) into this matchup — one of the key figures to watch." + } + return "\(name) is a key \(position) piece in this lineup — watch how they influence the game." +} + +func makeMatchupNote(name: String, opponent: String) -> String { + "\(name) faces \(opponent) — a key individual battle to monitor throughout." +} + +func inferStatus(playerName: String, injuryHeadlines: [String]) -> Player.PlayerStatus { + let parts = playerName.lowercased().split(separator: " ").filter { $0.count > 2 }.map(String.init) + for headline in injuryHeadlines { + let hl = headline.lowercased() + guard parts.contains(where: { hl.contains($0) }) else { continue } + if hl.contains("suspend") { return .suspended } + if hl.contains("doubtful") { return .doubtful } + if ["out","ruled out","injured","sidelined","misses"].contains(where: hl.contains) { return .injured } + } + return .fit +} + +// MARK: - Utilities + +func calcAge(birthDate: String) -> Int? { + let df = DateFormatter(); df.dateFormat = "yyyy-MM-dd" + guard let bd = df.date(from: birthDate) else { return nil } + let cal = Calendar.current + return cal.dateComponents([.year], from: bd, to: Date()).year +} + +func teamColor(_ teamName: String) -> String { + let lower = teamName.lowercased() + for (key, color) in TEAM_COLORS { if lower.contains(key) { return color } } + return TEAM_COLORS["default"]! +} + +func makeId(_ parts: String...) -> String { + let raw = parts.filter { !$0.isEmpty }.joined(separator: "-").lowercased().trimmingCharacters(in: .whitespaces) + let result = raw.replacingOccurrences(of: "[^a-z0-9]+", with: "-", options: .regularExpression) + .trimmingCharacters(in: CharacterSet(charactersIn: "-")) + return result.isEmpty ? "unknown" : result +} + +func topStats(_ stats: [String: String], limit: Int = 3) -> [String] { + stats.filter { !["—", "", "0", "0.0", "None"].contains($0.value) } + .prefix(limit).map { "\($0.value) \($0.key)" } +} + +// MARK: - Main Orchestrator + +func buildGameCache(teamName: String) async throws -> GameCache { + fputs("\n\("=".repeated(50))\n", stderr) + fputs("BroadcastBrain Cache Builder — \(teamName)\n", stderr) + fputs("\("=".repeated(50))\n\n", stderr) + + fputs("[1/5] Detecting sport...\n", stderr) + let (sport, league, competitionDisplay) = await detectSport(teamName: teamName) + fputs(" → \(competitionDisplay)\n\n", stderr) + + fputs("[2/5] Finding next game...\n", stderr) + var gameInfo: GameInfo? = nil + var ourTeamId = "" + + if sport == "soccer" || sport == "basketball" { + ourTeamId = await espnFindTeamId(teamName: teamName, sport: sport, league: league) ?? "" + if !ourTeamId.isEmpty { gameInfo = await espnNextGame(teamId: ourTeamId, sport: sport, league: league) } + } else if sport == "baseball" { + ourTeamId = await mlbFindTeamId(teamName: teamName) ?? "" + if !ourTeamId.isEmpty { gameInfo = await mlbNextGame(teamId: ourTeamId) } + } else if sport == "hockey" { + ourTeamId = nhlAbbrev(teamName: teamName) ?? "" + if !ourTeamId.isEmpty { gameInfo = await nhlNextGame(abbrev: ourTeamId) } + } + + if gameInfo == nil { + logErr("[2/5] No upcoming game in API, trying Google News...") + let newsHints = await googleNews(query: "\(teamName) next match fixture 2026", maxResults: 8) + var opponentHint = "" + for headline in newsHints { + let hl = headline.lowercased() + let teamWords = teamName.lowercased().split(separator: " ").filter { $0.count > 3 }.map(String.init) + guard teamWords.contains(where: { hl.contains($0) }) else { continue } + for (known, _) in KNOWN_TEAMS { + if hl.contains(known) && !teamName.lowercased().contains(known) { + if known.count > opponentHint.count { opponentHint = known } + } + } + if !opponentHint.isEmpty { + opponentHint = opponentHint.split(separator: " ").map { $0.capitalized }.joined(separator: " ") + logErr("[2/5] Extracted opponent: '\(opponentHint)'") + break + } + } + gameInfo = GameInfo(eventId: "tbd", homeTeam: teamName, + awayTeam: opponentHint.isEmpty ? "TBD" : opponentHint, + homeId: ourTeamId, awayId: "", + venue: "TBD", dateISO: ISO8601DateFormatter().string(from: Date()), + competition: competitionDisplay) + } + + let gi = gameInfo! + fputs(" → \(gi.homeTeam) vs \(gi.awayTeam) at \(gi.venue)\n\n", stderr) + + fputs("[3/5] Fetching rosters...\n", stderr) + var homeRaw: [RawPlayer] = [] + var awayRaw: [RawPlayer] = [] + + let isHome = teamName.lowercased().contains(gi.homeTeam.lowercased()) || gi.homeTeam.lowercased().contains(teamName.lowercased()) + let oppName = isHome ? gi.awayTeam : gi.homeTeam + var oppApiId = isHome ? gi.awayId : gi.homeId + + if sport == "soccer" || sport == "basketball" { + if !ourTeamId.isEmpty { homeRaw = await espnRoster(teamId: ourTeamId, sport: sport, league: league) } + if oppApiId.isEmpty && oppName != "TBD" { oppApiId = await espnFindTeamId(teamName: oppName, sport: sport, league: league) ?? "" } + if !oppApiId.isEmpty { awayRaw = await espnRoster(teamId: oppApiId, sport: sport, league: league) } + } else if sport == "baseball" { + if !ourTeamId.isEmpty { homeRaw = await mlbRoster(teamId: ourTeamId) } + if oppName != "TBD" { + let oppId = oppApiId.isEmpty ? (await mlbFindTeamId(teamName: oppName) ?? "") : oppApiId + if !oppId.isEmpty { awayRaw = await mlbRoster(teamId: oppId) } + } + } else if sport == "hockey" { + if !ourTeamId.isEmpty { homeRaw = await nhlRoster(abbrev: ourTeamId) } + if oppName != "TBD" { + let oppAbbr = oppApiId.isEmpty ? (nhlAbbrev(teamName: oppName) ?? "") : oppApiId + if !oppAbbr.isEmpty { awayRaw = await nhlRoster(abbrev: oppAbbr) } + } + } + fputs(" → Home: \(homeRaw.count) | Away: \(awayRaw.count)\n\n", stderr) + + fputs("[4/5] Fetching news & injuries...\n", stderr) + let homeInjuries = await fetchInjuryReport(gi.homeTeam) + let awayInjuries = gi.awayTeam != "TBD" ? await fetchInjuryReport(gi.awayTeam) : [] + let allInjuries = homeInjuries + awayInjuries + let homeNews = await fetchNewsForTeam(gi.homeTeam) + let awayNews = gi.awayTeam != "TBD" ? await fetchNewsForTeam(gi.awayTeam) : [] + var storylines = Array((homeNews.prefix(3) + awayNews.prefix(2))) + if (sport == "soccer" || sport == "basketball") && !ourTeamId.isEmpty { + let espnNews = await espnTeamNews(teamId: ourTeamId, sport: sport, league: league) + storylines = Array((espnNews.prefix(3) + storylines).prefix(8)) + } + fputs(" → \(storylines.count) storylines, \(allInjuries.count) injury items\n\n", stderr) + + fputs("[5/5] Building player records...\n", stderr) + let homeIdStr = makeId(gi.homeTeam) + let awayIdStr = makeId(gi.awayTeam) + + func buildPlayerList(raw: [RawPlayer], teamIdStr: String, teamDisplay: String, oppDisplay: String) async -> [Player] { + var built: [Player] = [] + for (i, p) in raw.prefix(20).enumerated() { + let name = p.name.trimmingCharacters(in: .whitespaces).isEmpty ? "Player \(i+1)" : p.name.trimmingCharacters(in: .whitespaces) + let playerId = p.id.isEmpty ? makeId(teamIdStr, name) : p.id + + var stats: [String: String] = [:] + if i < 10 && !playerId.isEmpty { + logErr("→ Fetching stats for \(name)...") + if sport == "soccer" || sport == "basketball" { stats = await espnPlayerStats(playerId: playerId, sport: sport, league: league) } + else if sport == "baseball" { stats = await mlbPlayerStats(playerId: playerId) } + else if sport == "hockey" { stats = await nhlPlayerStats(playerId: playerId) } + } + var playerNews: [String] = [] + if i < 6 { + logErr("→ Fetching news for \(name)...") + playerNews = await fetchNewsForPlayer(name, teamDisplay) + } + let status = inferStatus(playerName: name, injuryHeadlines: allInjuries) + built.append(Player( + id: makeId(teamIdStr, name), + teamId: teamIdStr, + shirtNumber: p.number ?? (i + 1), + name: name, + position: p.position.isEmpty ? "—" : p.position, + age: p.age ?? 0, + stats: PlayerStats(season: stats, formLast5: [:], vsOpponent: [:]), + storyline: makeStoryline(name: name, position: p.position, stats: stats, news: playerNews, status: status.rawValue), + matchupNote: makeMatchupNote(name: name, opponent: oppDisplay), + topStats: topStats(stats), + status: status, + newsHeadlines: playerNews + )) + } + return built + } + + let homePlayers = await buildPlayerList(raw: homeRaw, teamIdStr: homeIdStr, teamDisplay: gi.homeTeam, oppDisplay: gi.awayTeam) + let awayPlayers = await buildPlayerList(raw: awayRaw, teamIdStr: awayIdStr, teamDisplay: gi.awayTeam, oppDisplay: gi.homeTeam) + fputs(" → Built \(homePlayers.count) home + \(awayPlayers.count) away player records\n\n", stderr) + + return GameCache( + match: MatchInfo(id: makeId(gi.homeTeam, gi.awayTeam), homeTeam: gi.homeTeam, awayTeam: gi.awayTeam, + competition: gi.competition.isEmpty ? competitionDisplay : gi.competition, + venue: gi.venue, kickoffISO: gi.dateISO.isEmpty ? ISO8601DateFormatter().string(from: Date()) : gi.dateISO), + teams: TeamsPayload( + home: Team(id: homeIdStr, name: gi.homeTeam, colorHex: teamColor(gi.homeTeam), record: [:]), + away: Team(id: awayIdStr, name: gi.awayTeam, colorHex: teamColor(gi.awayTeam), record: [:]) + ), + players: homePlayers + awayPlayers, + storylines: storylines, + source: "espn_unofficial + mlb_official + nhl_official + google_news_rss", + generatedAt: ISO8601DateFormatter().string(from: Date()) + ) +} + +// MARK: - String helper + +extension String { + func repeated(_ count: Int) -> String { String(repeating: self, count: count) } +} + +// MARK: - Entry Point + +let args = CommandLine.arguments.dropFirst() +guard !args.isEmpty else { + print("Usage: swift src/data/FetchGame.swift ") + print(" e.g. swift src/data/FetchGame.swift 'Manchester City'") + print(" e.g. swift src/data/FetchGame.swift 'Los Angeles Lakers'") + print(" e.g. swift src/data/FetchGame.swift 'New York Yankees'") + print(" e.g. swift src/data/FetchGame.swift 'Toronto Maple Leafs'") + exit(1) +} + +let teamName = args.joined(separator: " ") + +let cache = try await buildGameCache(teamName: teamName) + +let outDir = URL(fileURLWithPath: FileManager.default.currentDirectoryPath).appendingPathComponent("assets") +try FileManager.default.createDirectory(at: outDir, withIntermediateDirectories: true) +let outPath = outDir.appendingPathComponent("game_cache.json") +let encoder = JSONEncoder(); encoder.outputFormatting = [.prettyPrinted, .sortedKeys] +try encoder.encode(cache).write(to: outPath) + +print("\n✓ Wrote \(outPath.path)") +print(" Match: \(cache.match.homeTeam) vs \(cache.match.awayTeam)") +print(" Venue: \(cache.match.venue)") +print(" Kickoff: \(cache.match.kickoffISO)") +print(" Players: \(cache.players.count)") +print(" Storylines: \(cache.storylines.count)") diff --git a/src/data/News.swift b/src/data/News.swift new file mode 100644 index 00000000..4aa43056 --- /dev/null +++ b/src/data/News.swift @@ -0,0 +1,176 @@ +import Foundation + +// MARK: - Types + +struct NewsItem: Codable { + let id: String + let headline: String + let description: String + let published: String + let imageUrl: String? + let articleUrl: String? + let leagueKey: String + let leagueLabel: String + let source: NewsSource + + enum NewsSource: String, Codable { + case espn + case googleNews = "google_news" + } +} + +// MARK: - Leagues + +private struct League { + let key: String + let sport: String + let league: String + let label: String +} + +private let LEAGUES: [League] = [ + League(key: "mlb", sport: "baseball", league: "mlb", label: "MLB"), + League(key: "nba", sport: "basketball", league: "nba", label: "NBA"), + League(key: "wnba", sport: "basketball", league: "wnba", label: "WNBA"), + League(key: "nfl", sport: "football", league: "nfl", label: "NFL"), + League(key: "ncaaf", sport: "football", league: "college-football",label: "NCAAF"), + League(key: "nhl", sport: "hockey", league: "nhl", label: "NHL"), + League(key: "epl", sport: "soccer", league: "eng.1", label: "EPL"), + League(key: "laliga", sport: "soccer", league: "esp.1", label: "La Liga"), + League(key: "seriea", sport: "soccer", league: "ita.1", label: "Serie A"), + League(key: "bundesliga", sport: "soccer", league: "ger.1", label: "Bundesliga"), + League(key: "ligue1", sport: "soccer", league: "fra.1", label: "Ligue 1"), + League(key: "ucl", sport: "soccer", league: "uefa.champions", label: "UCL"), + League(key: "mls", sport: "soccer", league: "usa.1", label: "MLS"), +] + +private let HTTP_HEADERS: [String: String] = [ + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36", + "Accept-Language": "en-US,en;q=0.9", +] + +// MARK: - ESPN + +private func espnNewsURL(sport: String, league: String, limit: Int) -> URL { + URL(string: "https://site.api.espn.com/apis/site/v2/sports/\(sport)/\(league)/news?limit=\(limit)")! +} + +func fetchLeagueNews(leagueKey: String, limit: Int = 20) async -> [NewsItem] { + guard let league = LEAGUES.first(where: { $0.key == leagueKey }) else { return [] } + let url = espnNewsURL(sport: league.sport, league: league.league, limit: limit) + guard let data = try? await httpGet(url: url), + let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any], + let articles = json["articles"] as? [[String: Any]] else { return [] } + return articles.map { espnArticleToNewsItem($0, leagueKey: league.key, leagueLabel: league.label) } +} + +func fetchAllSportsNews(limit: Int = 10) async -> [NewsItem] { + let mainLeagues = ["nfl", "nba", "mlb", "nhl", "epl", "mls"] + var all: [NewsItem] = [] + await withTaskGroup(of: [NewsItem].self) { group in + for key in mainLeagues { + group.addTask { await fetchLeagueNews(leagueKey: key, limit: limit) } + } + for await items in group { all.append(contentsOf: items) } + } + return all.sorted { + let df = ISO8601DateFormatter() + let a = df.date(from: $0.published) ?? Date.distantPast + let b = df.date(from: $1.published) ?? Date.distantPast + return a > b + } +} + +private func espnArticleToNewsItem(_ a: [String: Any], leagueKey: String, leagueLabel: String) -> NewsItem { + let id = a["id"].map { "espn-\(leagueKey)-\($0)" } ?? "espn-\(leagueKey)-\(Int.random(in: 0.. [NewsItem] { + let query = teamName.isEmpty ? playerName : "\(playerName) \(teamName)" + guard let encoded = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), + let url = URL(string: "https://news.google.com/rss/search?q=\(encoded)&hl=en-US&gl=US&ceid=US:en"), + let data = try? await httpGet(url: url), + let xml = String(data: data, encoding: .utf8) else { return [] } + return parseGoogleNewsRSS(xml: xml, limit: limit, source: .googleNews) +} + +private func parseGoogleNewsRSS(xml: String, limit: Int, source: NewsItem.NewsSource) -> [NewsItem] { + var items: [NewsItem] = [] + let pattern = try! NSRegularExpression(pattern: "([\\s\\S]*?)") + let range = NSRange(xml.startIndex..., in: xml) + for match in pattern.matches(in: xml, range: range) { + guard let contentRange = Range(match.range(at: 1), in: xml) else { continue } + let content = String(xml[contentRange]) + let rawTitle = extractTag(xml: content, tag: "title") ?? "" + let headline = rawTitle.replacingOccurrences( + of: "\\s*-\\s*[^-]+$", with: "", options: .regularExpression + ).trimmingCharacters(in: .whitespaces) + let description = stripHtml(extractTag(xml: content, tag: "description") ?? "") + let published = extractTag(xml: content, tag: "pubDate") ?? ISO8601DateFormatter().string(from: Date()) + let link = extractTag(xml: content, tag: "link") ?? "" + guard !headline.isEmpty, headline != "Google News" else { continue } + let idBase = Data(link.utf8).base64EncodedString().prefix(16) + items.append(NewsItem( + id: "gnews-\(idBase)", + headline: headline, + description: description, + published: published, + imageUrl: nil, + articleUrl: link.isEmpty ? nil : link, + leagueKey: "player", + leagueLabel: "Player News", + source: source + )) + if items.count >= limit { break } + } + return items +} + +private func extractTag(xml: String, tag: String) -> String? { + let open = "<\(tag)" + let close = "" + guard let startRange = xml.range(of: open), + let gtRange = xml.range(of: ">", range: startRange.upperBound..") { + value = String(value.dropFirst(9).dropLast(3)).trimmingCharacters(in: .whitespacesAndNewlines) + } + return value.isEmpty ? nil : value +} + +private func stripHtml(_ html: String) -> String { + html.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression) + .replacingOccurrences(of: "<", with: "<") + .replacingOccurrences(of: ">", with: ">") + .replacingOccurrences(of: "&", with: "&") + .trimmingCharacters(in: .whitespacesAndNewlines) +} + +// MARK: - HTTP + +func httpGet(url: URL) async throws -> Data { + var request = URLRequest(url: url) + for (k, v) in HTTP_HEADERS { request.setValue(v, forHTTPHeaderField: k) } + let (data, response) = try await URLSession.shared.data(for: request) + guard (response as? HTTPURLResponse)?.statusCode == 200 else { + throw URLError(.badServerResponse) + } + return data +} From 894a0da0161d713f4ee71b47005bdc974722fb18 Mon Sep 17 00:00:00 2001 From: Wali Viqas Date: Sun, 19 Apr 2026 04:43:53 -0700 Subject: [PATCH 02/18] feat(research): per-player storylines, matchup notes, NewsService MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the three gaps between GameFetchService and src/data/FetchGame.swift: fetchNewsForPlayer pulls top-3 Google News headlines for the first six players per side, makeStoryline picks the strongest signal (status → news headline → top stat → position fallback), and makeMatchupNote populates the Tactical card. Story-First and Tactical modes now carry real content when the cache is built dynamically. Adds NewsService (port of src/data/News.swift) exposing fetchLeagueNews, fetchAllSportsNews, and fetchPlayerNews so the Research UI can surface a live news feed — registered in the Xcode project under Services. Co-Authored-By: Claude Opus 4.7 (1M context) --- BroadcastBrain.xcodeproj/project.pbxproj | 4 + .../Services/GameFetchService.swift | 26 +++ BroadcastBrain/Services/NewsService.swift | 175 ++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 BroadcastBrain/Services/NewsService.swift diff --git a/BroadcastBrain.xcodeproj/project.pbxproj b/BroadcastBrain.xcodeproj/project.pbxproj index 3a863d33..86f6e6ec 100644 --- a/BroadcastBrain.xcodeproj/project.pbxproj +++ b/BroadcastBrain.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ A1B2C3D4E5F60718293A4B5C /* TacticalSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */; }; F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */; }; A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */; }; + C4D5E6F708192930A1B2C3D4 /* NewsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E6F708192930A1B2C3D4E5 /* NewsService.swift */; }; 70BA18D24CCC880D502CADD7 /* SquadsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */; }; 70BC25E15A41151CA931A4B9 /* cactus-macos.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */; }; 73474C0EE14E2A4A9B79742C /* LivePaneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01550DE4B92113B1173C6B2F /* LivePaneView.swift */; }; @@ -92,6 +93,7 @@ B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalSpottingBoardView.swift; sourceTree = ""; }; E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameFetchService.swift; sourceTree = ""; }; B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamSetupView.swift; sourceTree = ""; }; + D5E6F708192930A1B2C3D4E5 /* NewsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsService.swift; sourceTree = ""; }; 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "cactus-macos.xcframework"; path = "BroadcastBrain/Frameworks/cactus-macos.xcframework"; sourceTree = ""; }; 46EAD55D55FDE50021FA38E3 /* SportradarBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportradarBadge.swift; sourceTree = ""; }; 51919B20535309C89D4E15B9 /* Tokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tokens.swift; sourceTree = ""; }; @@ -238,6 +240,7 @@ children = ( B83E5A0C129A26A3CC625311 /* AudioCaptureService.swift */, E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */, + D5E6F708192930A1B2C3D4E5 /* NewsService.swift */, 82B9451069B6343C41C337AC /* Cactus.swift */, 90AFD39809B3E0BE8DF8644B /* CactusService.swift */, 7CE728CE31ACC8F9DB7324B9 /* MockResponder.swift */, @@ -394,6 +397,7 @@ A1B2C3D4E5F60718293A4B5C /* TacticalSpottingBoardView.swift in Sources */, F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */, A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */, + C4D5E6F708192930A1B2C3D4 /* NewsService.swift in Sources */, B28DD1DE6BE6197370BB602C /* ContentView.swift in Sources */, 43DB7EFEFC8C19A84E734EF6 /* DottedGrid.swift in Sources */, E05C57FFDF0F3B9977139753 /* LatencyTag.swift in Sources */, diff --git a/BroadcastBrain/Services/GameFetchService.swift b/BroadcastBrain/Services/GameFetchService.swift index 718367d5..e30ee9cc 100644 --- a/BroadcastBrain/Services/GameFetchService.swift +++ b/BroadcastBrain/Services/GameFetchService.swift @@ -433,6 +433,32 @@ final class GameFetchService { return "fit" } + private func fetchNewsForPlayer(name: String, team: String) async -> [String] { + guard !name.isEmpty else { return [] } + return await googleNews("\(name) \(team) 2026", max: 3) + } + + private func makeStoryline(name: String, position: String, stats: [String: String], news: [String], status: String) -> String { + if ["injured", "doubtful", "suspended"].contains(status) { + return "\(name) is listed as \(status) — availability is the key team news heading in." + } + if let headline = news.first { + let clean = headline.replacingOccurrences(of: "\\s*-\\s*[^-]+$", with: "", options: .regularExpression) + .trimmingCharacters(in: .whitespaces) + if clean.count > 10 { return clean } + } + if let (key, val) = stats.first(where: { !["", "0", "0.0", "—"].contains($0.value) }) { + return "\(name) brings \(val) \(key) into this matchup — one of the key figures to watch." + } + let pos = position.isEmpty ? "player" : position + return "\(name) is a key \(pos) piece in this lineup — watch how they influence the game." + } + + private func makeMatchupNote(name: String, opponent: String) -> String { + let opp = opponent.isEmpty || opponent == "TBD" ? "their opponent" : opponent + return "\(name) faces \(opp) — a key individual battle to monitor throughout." + } + private func makeId(_ parts: String...) -> String { let raw = parts.filter { !$0.isEmpty }.joined(separator: "-").lowercased().trimmingCharacters(in: .whitespaces) let r = raw.replacingOccurrences(of: "[^a-z0-9]+", with: "-", options: .regularExpression) diff --git a/BroadcastBrain/Services/NewsService.swift b/BroadcastBrain/Services/NewsService.swift new file mode 100644 index 00000000..24d58174 --- /dev/null +++ b/BroadcastBrain/Services/NewsService.swift @@ -0,0 +1,175 @@ +import Foundation + +// MARK: - Types + +struct NewsItem: Codable, Identifiable, Hashable { + let id: String + let headline: String + let description: String + let published: String + let imageUrl: String? + let articleUrl: String? + let leagueKey: String + let leagueLabel: String + let source: NewsSource + + enum NewsSource: String, Codable { + case espn + case googleNews = "google_news" + } +} + +// MARK: - Service + +enum NewsService { + + private struct League { + let key: String + let sport: String + let league: String + let label: String + } + + private static let leagues: [League] = [ + League(key: "mlb", sport: "baseball", league: "mlb", label: "MLB"), + League(key: "nba", sport: "basketball", league: "nba", label: "NBA"), + League(key: "wnba", sport: "basketball", league: "wnba", label: "WNBA"), + League(key: "nfl", sport: "football", league: "nfl", label: "NFL"), + League(key: "ncaaf", sport: "football", league: "college-football",label: "NCAAF"), + League(key: "nhl", sport: "hockey", league: "nhl", label: "NHL"), + League(key: "epl", sport: "soccer", league: "eng.1", label: "EPL"), + League(key: "laliga", sport: "soccer", league: "esp.1", label: "La Liga"), + League(key: "seriea", sport: "soccer", league: "ita.1", label: "Serie A"), + League(key: "bundesliga", sport: "soccer", league: "ger.1", label: "Bundesliga"), + League(key: "ligue1", sport: "soccer", league: "fra.1", label: "Ligue 1"), + League(key: "ucl", sport: "soccer", league: "uefa.champions", label: "UCL"), + League(key: "mls", sport: "soccer", league: "usa.1", label: "MLS"), + ] + + private static let headers: [String: String] = [ + "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36", + "Accept-Language": "en-US,en;q=0.9", + ] + + // MARK: - Public API + + static func fetchLeagueNews(leagueKey: String, limit: Int = 20) async -> [NewsItem] { + guard let league = leagues.first(where: { $0.key == leagueKey }), + let url = URL(string: "https://site.api.espn.com/apis/site/v2/sports/\(league.sport)/\(league.league)/news?limit=\(limit)"), + let data = try? await httpGet(url: url), + let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any], + let articles = json["articles"] as? [[String: Any]] else { return [] } + return articles.map { espnArticleToNewsItem($0, leagueKey: league.key, leagueLabel: league.label) } + } + + static func fetchAllSportsNews(limit: Int = 10) async -> [NewsItem] { + let mainLeagues = ["nfl", "nba", "mlb", "nhl", "epl", "mls"] + var all: [NewsItem] = [] + await withTaskGroup(of: [NewsItem].self) { group in + for key in mainLeagues { + group.addTask { await fetchLeagueNews(leagueKey: key, limit: limit) } + } + for await items in group { all.append(contentsOf: items) } + } + return all.sorted { + let df = ISO8601DateFormatter() + let a = df.date(from: $0.published) ?? Date.distantPast + let b = df.date(from: $1.published) ?? Date.distantPast + return a > b + } + } + + static func fetchPlayerNews(playerName: String, teamName: String = "", limit: Int = 5) async -> [NewsItem] { + let query = teamName.isEmpty ? playerName : "\(playerName) \(teamName)" + guard let encoded = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), + let url = URL(string: "https://news.google.com/rss/search?q=\(encoded)&hl=en-US&gl=US&ceid=US:en"), + let data = try? await httpGet(url: url), + let xml = String(data: data, encoding: .utf8) else { return [] } + return parseGoogleNewsRSS(xml: xml, limit: limit, source: .googleNews) + } + + // MARK: - Parsing + + private static func espnArticleToNewsItem(_ a: [String: Any], leagueKey: String, leagueLabel: String) -> NewsItem { + let id = a["id"].map { "espn-\(leagueKey)-\($0)" } ?? "espn-\(leagueKey)-\(UUID().uuidString)" + let images = a["images"] as? [[String: Any]] + let links = a["links"] as? [String: Any] + let web = links?["web"] as? [String: Any] + return NewsItem( + id: id, + headline: a["headline"] as? String ?? "", + description: a["description"] as? String ?? "", + published: a["published"] as? String ?? ISO8601DateFormatter().string(from: Date()), + imageUrl: images?.first?["url"] as? String, + articleUrl: web?["href"] as? String, + leagueKey: leagueKey, + leagueLabel: leagueLabel, + source: .espn + ) + } + + private static func parseGoogleNewsRSS(xml: String, limit: Int, source: NewsItem.NewsSource) -> [NewsItem] { + var items: [NewsItem] = [] + let pattern = try! NSRegularExpression(pattern: "([\\s\\S]*?)") + let range = NSRange(xml.startIndex..., in: xml) + for match in pattern.matches(in: xml, range: range) { + guard let contentRange = Range(match.range(at: 1), in: xml) else { continue } + let content = String(xml[contentRange]) + let rawTitle = extractTag(xml: content, tag: "title") ?? "" + let headline = rawTitle.replacingOccurrences( + of: "\\s*-\\s*[^-]+$", with: "", options: .regularExpression + ).trimmingCharacters(in: .whitespaces) + let description = stripHtml(extractTag(xml: content, tag: "description") ?? "") + let published = extractTag(xml: content, tag: "pubDate") ?? ISO8601DateFormatter().string(from: Date()) + let link = extractTag(xml: content, tag: "link") ?? "" + guard !headline.isEmpty, headline != "Google News" else { continue } + let idBase = Data(link.utf8).base64EncodedString().prefix(16) + items.append(NewsItem( + id: "gnews-\(idBase)", + headline: headline, + description: description, + published: published, + imageUrl: nil, + articleUrl: link.isEmpty ? nil : link, + leagueKey: "player", + leagueLabel: "Player News", + source: source + )) + if items.count >= limit { break } + } + return items + } + + private static func extractTag(xml: String, tag: String) -> String? { + let open = "<\(tag)" + let close = "" + guard let startRange = xml.range(of: open), + let gtRange = xml.range(of: ">", range: startRange.upperBound..") { + value = String(value.dropFirst(9).dropLast(3)).trimmingCharacters(in: .whitespacesAndNewlines) + } + return value.isEmpty ? nil : value + } + + private static func stripHtml(_ html: String) -> String { + html.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression) + .replacingOccurrences(of: "<", with: "<") + .replacingOccurrences(of: ">", with: ">") + .replacingOccurrences(of: "&", with: "&") + .trimmingCharacters(in: .whitespacesAndNewlines) + } + + // MARK: - HTTP + + private static func httpGet(url: URL) async throws -> Data { + var request = URLRequest(url: url) + for (k, v) in headers { request.setValue(v, forHTTPHeaderField: k) } + let (data, response) = try await URLSession.shared.data(for: request) + guard (response as? HTTPURLResponse)?.statusCode == 200 else { + throw URLError(.badServerResponse) + } + return data + } +} From 80efee79947bc43186b01f2ecd9b2d8682730db6 Mon Sep 17 00:00:00 2001 From: Wali Viqas Date: Sun, 19 Apr 2026 05:03:10 -0700 Subject: [PATCH 03/18] feat(news): News tab + Gemini synthesis to Research notes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a dedicated News sidebar tab that pulls live headlines across the major leagues via NewsService and groups them by league with filter chips. A "Synthesize to Research Notes" button packages the current list plus loaded match context (teams, key players) and sends it to gemini-2.5-flash for a broadcaster-style digest, which is date-stamped and appended to the current session's notes so it's available offline during the game. GeminiService reads the API key from ~/Library/Application Support/BroadcastBrain/gemini_key.txt — outside the repo to avoid ever committing it. Missing key surfaces a guidance error instead of a blank failure. Co-Authored-By: Claude Opus 4.7 (1M context) --- BroadcastBrain.xcodeproj/project.pbxproj | 8 + BroadcastBrain/ContentView.swift | 1 + BroadcastBrain/Services/GeminiService.swift | 92 ++++++++ BroadcastBrain/Stores/AppStore.swift | 2 +- BroadcastBrain/Views/NewsTabView.swift | 235 ++++++++++++++++++++ BroadcastBrain/Views/SidebarView.swift | 1 + 6 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 BroadcastBrain/Services/GeminiService.swift create mode 100644 BroadcastBrain/Views/NewsTabView.swift diff --git a/BroadcastBrain.xcodeproj/project.pbxproj b/BroadcastBrain.xcodeproj/project.pbxproj index 86f6e6ec..051b934a 100644 --- a/BroadcastBrain.xcodeproj/project.pbxproj +++ b/BroadcastBrain.xcodeproj/project.pbxproj @@ -28,6 +28,8 @@ F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */; }; A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */; }; C4D5E6F708192930A1B2C3D4 /* NewsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E6F708192930A1B2C3D4E5 /* NewsService.swift */; }; + E6F708192930A1B2C3D4E5F6 /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F708192930A1B2C3D4E5F607 /* GeminiService.swift */; }; + 08192930A1B2C3D4E5F60718 /* NewsTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 192930A1B2C3D4E5F6071829 /* NewsTabView.swift */; }; 70BA18D24CCC880D502CADD7 /* SquadsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */; }; 70BC25E15A41151CA931A4B9 /* cactus-macos.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */; }; 73474C0EE14E2A4A9B79742C /* LivePaneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01550DE4B92113B1173C6B2F /* LivePaneView.swift */; }; @@ -94,6 +96,8 @@ E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameFetchService.swift; sourceTree = ""; }; B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamSetupView.swift; sourceTree = ""; }; D5E6F708192930A1B2C3D4E5 /* NewsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsService.swift; sourceTree = ""; }; + F708192930A1B2C3D4E5F607 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; + 192930A1B2C3D4E5F6071829 /* NewsTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsTabView.swift; sourceTree = ""; }; 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "cactus-macos.xcframework"; path = "BroadcastBrain/Frameworks/cactus-macos.xcframework"; sourceTree = ""; }; 46EAD55D55FDE50021FA38E3 /* SportradarBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportradarBadge.swift; sourceTree = ""; }; 51919B20535309C89D4E15B9 /* Tokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tokens.swift; sourceTree = ""; }; @@ -151,6 +155,7 @@ FF6A7B8C9D0E1F2A3B4C5D6E /* StoryFirstSpottingBoardView.swift */, B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */, B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */, + 192930A1B2C3D4E5F6071829 /* NewsTabView.swift */, 01550DE4B92113B1173C6B2F /* LivePaneView.swift */, 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */, FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */, @@ -241,6 +246,7 @@ B83E5A0C129A26A3CC625311 /* AudioCaptureService.swift */, E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */, D5E6F708192930A1B2C3D4E5 /* NewsService.swift */, + F708192930A1B2C3D4E5F607 /* GeminiService.swift */, 82B9451069B6343C41C337AC /* Cactus.swift */, 90AFD39809B3E0BE8DF8644B /* CactusService.swift */, 7CE728CE31ACC8F9DB7324B9 /* MockResponder.swift */, @@ -398,6 +404,8 @@ F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */, A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */, C4D5E6F708192930A1B2C3D4 /* NewsService.swift in Sources */, + E6F708192930A1B2C3D4E5F6 /* GeminiService.swift in Sources */, + 08192930A1B2C3D4E5F60718 /* NewsTabView.swift in Sources */, B28DD1DE6BE6197370BB602C /* ContentView.swift in Sources */, 43DB7EFEFC8C19A84E734EF6 /* DottedGrid.swift in Sources */, E05C57FFDF0F3B9977139753 /* LatencyTag.swift in Sources */, diff --git a/BroadcastBrain/ContentView.swift b/BroadcastBrain/ContentView.swift index a29a9ce8..06c0678b 100644 --- a/BroadcastBrain/ContentView.swift +++ b/BroadcastBrain/ContentView.swift @@ -27,6 +27,7 @@ struct ContentView: View { case .live: LivePaneView() case .squads: SquadsView() case .research: ResearchCenterView() + case .news: NewsTabView() case .archive: ArchivesListView() } } diff --git a/BroadcastBrain/Services/GeminiService.swift b/BroadcastBrain/Services/GeminiService.swift new file mode 100644 index 00000000..d5668169 --- /dev/null +++ b/BroadcastBrain/Services/GeminiService.swift @@ -0,0 +1,92 @@ +import Foundation + +enum GeminiError: LocalizedError { + case missingKey + case badResponse(String) + case empty + + var errorDescription: String? { + switch self { + case .missingKey: + return "No Gemini API key. Save it to ~/Library/Application Support/BroadcastBrain/gemini_key.txt" + case .badResponse(let s): return "Gemini error: \(s)" + case .empty: return "Gemini returned an empty response." + } + } +} + +enum GeminiService { + + private static let model = "gemini-2.5-flash" + + private static var keyPath: URL { + FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] + .appendingPathComponent("BroadcastBrain/gemini_key.txt") + } + + static func apiKey() -> String? { + guard let data = try? Data(contentsOf: keyPath), + let raw = String(data: data, encoding: .utf8) else { return nil } + let trimmed = raw.trimmingCharacters(in: .whitespacesAndNewlines) + return trimmed.isEmpty ? nil : trimmed + } + + static func synthesizeNews(headlines: [NewsItem], matchTitle: String?, playerNames: [String]) async throws -> String { + guard let key = apiKey() else { throw GeminiError.missingKey } + + let headlineList = headlines.prefix(80).enumerated().map { idx, h in + "\(idx + 1). [\(h.leagueLabel)] \(h.headline)\(h.description.isEmpty ? "" : " — \(h.description)")" + }.joined(separator: "\n") + + let matchLine = matchTitle.map { "Match: \($0)" } ?? "No specific match loaded." + let playerLine = playerNames.isEmpty ? "" : "Key players to prioritize: \(playerNames.prefix(20).joined(separator: ", "))" + + let systemInstruction = """ + You are a broadcast prep assistant. From the headlines, produce a tight set of talking points for a live commentator. + If a specific match is loaded, prioritize news relevant to those teams and players; otherwise give a league-wide digest. + Group findings under these headings exactly (omit any with no content): + INJURIES & AVAILABILITY + FORM & RECENT RESULTS + STORYLINES & RIVALRY + WILDCARDS + Use short bullet points (1–2 sentences each). Keep the full response under 300 words. Plain text only, no markdown syntax. + """ + + let userPrompt = """ + \(matchLine) + \(playerLine) + + Headlines: + \(headlineList) + """ + + let body: [String: Any] = [ + "systemInstruction": ["parts": [["text": systemInstruction]]], + "contents": [["role": "user", "parts": [["text": userPrompt]]]], + "generationConfig": ["temperature": 0.4, "maxOutputTokens": 1024], + ] + let jsonData = try JSONSerialization.data(withJSONObject: body) + + var req = URLRequest(url: URL(string: "https://generativelanguage.googleapis.com/v1beta/models/\(model):generateContent?key=\(key)")!) + req.httpMethod = "POST" + req.setValue("application/json", forHTTPHeaderField: "Content-Type") + req.httpBody = jsonData + + let (data, resp) = try await URLSession.shared.data(for: req) + guard let http = resp as? HTTPURLResponse else { throw GeminiError.badResponse("no response") } + guard (200..<300).contains(http.statusCode) else { + let msg = String(data: data, encoding: .utf8) ?? "status \(http.statusCode)" + throw GeminiError.badResponse(msg) + } + + guard let json = try JSONSerialization.jsonObject(with: data) as? [String: Any], + let candidates = json["candidates"] as? [[String: Any]], + let content = candidates.first?["content"] as? [String: Any], + let parts = content["parts"] as? [[String: Any]], + let text = parts.first?["text"] as? String, + !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty + else { throw GeminiError.empty } + + return text.trimmingCharacters(in: .whitespacesAndNewlines) + } +} diff --git a/BroadcastBrain/Stores/AppStore.swift b/BroadcastBrain/Stores/AppStore.swift index b707a80a..28310b78 100644 --- a/BroadcastBrain/Stores/AppStore.swift +++ b/BroadcastBrain/Stores/AppStore.swift @@ -2,7 +2,7 @@ import Foundation import Observation enum Surface: String, CaseIterable, Identifiable { - case live, squads, research, archive + case live, squads, research, news, archive var id: String { rawValue } } diff --git a/BroadcastBrain/Views/NewsTabView.swift b/BroadcastBrain/Views/NewsTabView.swift new file mode 100644 index 00000000..b6db3d3b --- /dev/null +++ b/BroadcastBrain/Views/NewsTabView.swift @@ -0,0 +1,235 @@ +import SwiftUI + +struct NewsTabView: View { + @Environment(AppStore.self) private var store + + @State private var items: [NewsItem] = [] + @State private var selectedLeague: String = "all" + @State private var isLoading = false + @State private var isSynthesizing = false + @State private var errorMessage: String? + @State private var statusMessage: String? + + private let leagueFilters: [(key: String, label: String)] = [ + ("all", "ALL"), + ("nfl", "NFL"), + ("nba", "NBA"), + ("mlb", "MLB"), + ("nhl", "NHL"), + ("epl", "EPL"), + ("mls", "MLS"), + ] + + var body: some View { + VStack(spacing: 0) { + header + + if let msg = errorMessage { + Text(msg) + .font(Typography.chip) + .foregroundStyle(Color.live) + .padding(.horizontal, 20) + .padding(.vertical, 8) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.bgRaised) + } + if let msg = statusMessage { + Text(msg) + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + .padding(.horizontal, 20) + .padding(.vertical, 8) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.bgRaised) + } + + if isLoading && items.isEmpty { + Spacer() + ProgressView("Fetching headlines…").progressViewStyle(.circular) + Spacer() + } else if filteredItems.isEmpty { + Spacer() + Text("No headlines yet. Tap Refresh.") + .font(Typography.body) + .foregroundStyle(Color.textMuted) + Spacer() + } else { + ScrollView { + LazyVStack(alignment: .leading, spacing: 8) { + ForEach(filteredItems) { item in + NewsRow(item: item) + } + } + .padding(20) + } + } + } + .background(Color.bgBase) + .task { if items.isEmpty { await refresh() } } + } + + private var filteredItems: [NewsItem] { + selectedLeague == "all" ? items : items.filter { $0.leagueKey == selectedLeague } + } + + private var header: some View { + VStack(alignment: .leading, spacing: 10) { + HStack { + Text("NEWS") + .font(Typography.sectionHead) + .foregroundStyle(Color.textSubtle) + Spacer() + Button(action: { Task { await refresh() } }) { + HStack(spacing: 4) { + Image(systemName: "arrow.clockwise") + Text("Refresh").font(Typography.chip) + } + .foregroundStyle(Color.textMuted) + } + .buttonStyle(.plain) + .disabled(isLoading) + + Button(action: { Task { await synthesize() } }) { + HStack(spacing: 4) { + if isSynthesizing { + ProgressView().controlSize(.small) + } else { + Image(systemName: "sparkles") + } + Text("Synthesize to Research Notes").font(Typography.chip) + } + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(Color.live.opacity(canSynthesize ? 0.9 : 0.3), in: RoundedRectangle(cornerRadius: 4)) + .foregroundStyle(Color.white) + } + .buttonStyle(.plain) + .disabled(!canSynthesize) + } + + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 6) { + ForEach(leagueFilters, id: \.key) { filter in + leagueChip(filter) + } + } + } + } + .padding(.horizontal, 20) + .padding(.vertical, 14) + .background(Color.bgBase) + .overlay(Divider().background(Color.bbBorder), alignment: .bottom) + } + + private func leagueChip(_ filter: (key: String, label: String)) -> some View { + let selected = selectedLeague == filter.key + return Button(action: { selectedLeague = filter.key }) { + Text(filter.label) + .font(Typography.chip) + .padding(.horizontal, 10) + .padding(.vertical, 4) + .background(selected ? Color.live : Color.bgRaised, in: RoundedRectangle(cornerRadius: 4)) + .foregroundStyle(selected ? Color.white : Color.textPrimary) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) + } + + private var canSynthesize: Bool { + !items.isEmpty && !isSynthesizing + } + + // MARK: - Actions + + private func refresh() async { + isLoading = true + errorMessage = nil + let fetched = await NewsService.fetchAllSportsNews(limit: 10) + await MainActor.run { + self.items = fetched + self.isLoading = false + if fetched.isEmpty { self.errorMessage = "Couldn't fetch headlines (check network)." } + } + } + + private func synthesize() async { + guard !items.isEmpty else { return } + isSynthesizing = true + errorMessage = nil + statusMessage = "Synthesizing with Gemini…" + + let matchTitle = store.matchCache?.title + let playerNames = (store.matchCache?.players ?? []).map(\.name) + let pool = filteredItems.isEmpty ? items : filteredItems + + do { + let digest = try await GeminiService.synthesizeNews( + headlines: pool, + matchTitle: matchTitle, + playerNames: playerNames + ) + await MainActor.run { + appendDigestToNotes(digest) + self.isSynthesizing = false + self.statusMessage = "Saved to Research notes." + } + } catch { + await MainActor.run { + self.isSynthesizing = false + self.statusMessage = nil + self.errorMessage = error.localizedDescription + } + } + } + + private func appendDigestToNotes(_ digest: String) { + let df = DateFormatter() + df.dateFormat = "yyyy-MM-dd HH:mm" + let stamp = df.string(from: Date()) + let header = "=== News digest · \(stamp) ===" + let existing = store.currentSession.notes + let combined = existing.isEmpty + ? "\(header)\n\(digest)" + : "\(existing)\n\n\(header)\n\(digest)" + store.updateNotes(combined) + } +} + +private struct NewsRow: View { + let item: NewsItem + + var body: some View { + VStack(alignment: .leading, spacing: 4) { + HStack(spacing: 6) { + Text(item.leagueLabel) + .font(Typography.chip) + .padding(.horizontal, 6) + .padding(.vertical, 2) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 3)) + .foregroundStyle(Color.textMuted) + if !item.published.isEmpty { + Text(item.published.prefix(10)) + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + } + Spacer() + } + Text(item.headline) + .font(Typography.body) + .foregroundStyle(Color.textPrimary) + .lineLimit(3) + .fixedSize(horizontal: false, vertical: true) + if !item.description.isEmpty { + Text(item.description) + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + .lineLimit(2) + .fixedSize(horizontal: false, vertical: true) + } + } + .padding(10) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + } +} diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index cfcaeb36..8a7ba6ea 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -10,6 +10,7 @@ struct SidebarView: View { surfaceRow(title: "Live", systemImage: "dot.radiowaves.left.and.right", surface: .live) surfaceRow(title: "Squads", systemImage: "person.2", surface: .squads) surfaceRow(title: "Research", systemImage: "book", surface: .research) + surfaceRow(title: "News", systemImage: "newspaper", surface: .news) surfaceRow(title: "Archive", systemImage: "archivebox", surface: .archive) } } From 7cb589f7e8dc4b0babd46e91d1314e95c0104e25 Mon Sep 17 00:00:00 2001 From: Wali Viqas Date: Sun, 19 Apr 2026 05:43:29 -0700 Subject: [PATCH 04/18] feat: tailored setup, notes drawer, article selection, curated synthesis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First launch now always forces the team setup flow — the bundled Argentina vs France cache is no longer a silent fallback, so every user starts with their own match instead of demo data. Commentator style picker is sport-neutral: dropped the "5.2 xG / 4-3 Formation" soccer-specific previews for mode icons, rewrote the three descriptions to state what each mode actually does (numbers lead / narrative leads / matchups lead). Research tab gains a NOTES drawer: a floating toggle in the top-right of any spotting mode slides in an editable notes panel bound to the current session, so synthesized digests from the News tab are finally visible next to the board. News tab gains a SELECT ARTICLES toggle with per-row checkboxes. When active, clicks toggle selection instead of opening the article; the synthesize button updates its label and count; selection clears on success. Status messages are granular — Reading N headlines → Writing the digest → Appending to notes → Saved. GeminiService branches its prompt on curation: curated picks drop match context and force one bullet per headline, bulk synthesis keeps the match-prefer/league-fallback behavior. Error surface shows the real sandbox path so key placement is obvious. Co-Authored-By: Claude Opus 4.7 (1M context) --- BroadcastBrain/Services/GeminiService.swift | 68 +++--- BroadcastBrain/Stores/AppStore.swift | 11 +- .../Views/CommentatorStylePickerView.swift | 44 ++-- BroadcastBrain/Views/NewsTabView.swift | 194 ++++++++++++++---- BroadcastBrain/Views/ResearchCenterView.swift | 165 +++++---------- 5 files changed, 283 insertions(+), 199 deletions(-) diff --git a/BroadcastBrain/Services/GeminiService.swift b/BroadcastBrain/Services/GeminiService.swift index d5668169..f2f03daf 100644 --- a/BroadcastBrain/Services/GeminiService.swift +++ b/BroadcastBrain/Services/GeminiService.swift @@ -1,14 +1,14 @@ import Foundation enum GeminiError: LocalizedError { - case missingKey + case missingKey(String) case badResponse(String) case empty var errorDescription: String? { switch self { - case .missingKey: - return "No Gemini API key. Save it to ~/Library/Application Support/BroadcastBrain/gemini_key.txt" + case .missingKey(let path): + return "No Gemini API key. Save it to \(path)" case .badResponse(let s): return "Gemini error: \(s)" case .empty: return "Gemini returned an empty response." } @@ -31,34 +31,50 @@ enum GeminiService { return trimmed.isEmpty ? nil : trimmed } - static func synthesizeNews(headlines: [NewsItem], matchTitle: String?, playerNames: [String]) async throws -> String { - guard let key = apiKey() else { throw GeminiError.missingKey } + static func synthesizeNews(headlines: [NewsItem], matchTitle: String?, playerNames: [String], userCurated: Bool) async throws -> String { + guard let key = apiKey() else { throw GeminiError.missingKey(keyPath.path) } let headlineList = headlines.prefix(80).enumerated().map { idx, h in "\(idx + 1). [\(h.leagueLabel)] \(h.headline)\(h.description.isEmpty ? "" : " — \(h.description)")" }.joined(separator: "\n") - let matchLine = matchTitle.map { "Match: \($0)" } ?? "No specific match loaded." - let playerLine = playerNames.isEmpty ? "" : "Key players to prioritize: \(playerNames.prefix(20).joined(separator: ", "))" - - let systemInstruction = """ - You are a broadcast prep assistant. From the headlines, produce a tight set of talking points for a live commentator. - If a specific match is loaded, prioritize news relevant to those teams and players; otherwise give a league-wide digest. - Group findings under these headings exactly (omit any with no content): - INJURIES & AVAILABILITY - FORM & RECENT RESULTS - STORYLINES & RIVALRY - WILDCARDS - Use short bullet points (1–2 sentences each). Keep the full response under 300 words. Plain text only, no markdown syntax. - """ - - let userPrompt = """ - \(matchLine) - \(playerLine) - - Headlines: - \(headlineList) - """ + let systemInstruction: String + let userPrompt: String + + if userCurated { + // User hand-picked these — synthesize them on their own merits, + // ignore the loaded match context entirely. + systemInstruction = """ + You are a broadcast prep assistant. The broadcaster hand-picked these headlines. Produce at least one bullet point per headline — never skip one, never say "no relevant information". + Group bullets under these headings where they fit (omit truly empty ones): + INJURIES & AVAILABILITY + FORM & RECENT RESULTS + STORYLINES & RIVALRY + WILDCARDS + Each bullet: 1–2 sentences summarizing what a commentator would want to say about that headline. Plain text only, no markdown syntax. Under 400 words total. + """ + userPrompt = "Selected headlines:\n\(headlineList)" + } else { + let matchLine = matchTitle.map { "Match: \($0)" } ?? "No specific match loaded." + let playerLine = playerNames.isEmpty ? "" : "Players on the match roster: \(playerNames.prefix(20).joined(separator: ", "))" + systemInstruction = """ + You are a broadcast prep assistant. From the headlines, produce a tight set of talking points for a live commentator. + Prefer items relevant to the loaded match and its players, but still surface broader league context when nothing ties directly — never refuse with "no relevant information". + Group findings under these headings (omit any that truly have no content): + INJURIES & AVAILABILITY + FORM & RECENT RESULTS + STORYLINES & RIVALRY + WILDCARDS + Use short bullet points (1–2 sentences each). Keep the full response under 300 words. Plain text only, no markdown syntax. + """ + userPrompt = """ + \(matchLine) + \(playerLine) + + Headlines: + \(headlineList) + """ + } let body: [String: Any] = [ "systemInstruction": ["parts": [["text": systemInstruction]]], diff --git a/BroadcastBrain/Stores/AppStore.swift b/BroadcastBrain/Stores/AppStore.swift index 28310b78..eab9ba68 100644 --- a/BroadcastBrain/Stores/AppStore.swift +++ b/BroadcastBrain/Stores/AppStore.swift @@ -48,8 +48,9 @@ final class AppStore { self.sessionStore = sessionStore self.cactus = cactus - // Prefer the user-saved cache, fall back to bundled resource - let initialCache = Self.loadSavedCache() ?? Self.loadBundledCache() + // Only user-saved cache counts — no bundled fallback, so first launch always + // forces the team setup screen for a tailored experience. + let initialCache = Self.loadSavedCache() self.matchCache = initialCache let title = initialCache?.title ?? "New Match" @@ -134,12 +135,6 @@ final class AppStore { return try? JSONDecoder().decode(MatchCache.self, from: data) } - private static func loadBundledCache() -> MatchCache? { - guard let url = Bundle.main.url(forResource: "match_cache", withExtension: "json"), - let data = try? Data(contentsOf: url) else { return nil } - return try? JSONDecoder().decode(MatchCache.self, from: data) - } - private static func persistCache(_ cache: MatchCache) { let dir = savedCacheURL.deletingLastPathComponent() try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) diff --git a/BroadcastBrain/Views/CommentatorStylePickerView.swift b/BroadcastBrain/Views/CommentatorStylePickerView.swift index 808483ea..97b95a17 100644 --- a/BroadcastBrain/Views/CommentatorStylePickerView.swift +++ b/BroadcastBrain/Views/CommentatorStylePickerView.swift @@ -16,7 +16,7 @@ struct CommentatorStylePickerView: View { Image(systemName: "checkmark.circle.fill") .font(.system(size: 10, weight: .medium, design: .monospaced)) .foregroundStyle(Color.verified) - Text("READY · PRE-INDEXED OVERNIGHT") + Text("MATCH CACHE READY") .font(Typography.chip) .foregroundStyle(Color.verified) } @@ -27,7 +27,7 @@ struct CommentatorStylePickerView: View { .foregroundStyle(Color.textPrimary) .padding(.bottom, 8) - Text("\(playerCount) players · \(storylineCount) storylines pre-indexed.") + Text("\(playerCount) players · \(storylineCount) storylines cached for this match.") .font(Typography.chip) .foregroundStyle(Color.textMuted) .padding(.bottom, 24) @@ -38,24 +38,24 @@ struct CommentatorStylePickerView: View { mode: .stats, title: "STATS-FIRST", badge: nil, - description: "xG · xA · progressive carries. Numbers lead.", - detail: "\(playerCount) player stats · \(storylineCount) matchups cached.", + description: "Numbers lead. Top 3 stats per player, ranked by impact.", + detail: "Best for data-driven calls and quick comparisons.", hovered: $hovered ) StyleRow( mode: .story, title: "STORY-FIRST", - badge: "RECOMMENDED FOR YOU", - description: "Arcs, feuds, milestones. Narrative leads.", - detail: "World Cup · tournament history · season arcs.", + badge: "RECOMMENDED", + description: "Narrative leads. Latest headline or storyline on each card.", + detail: "Best for colour commentary and player arcs.", hovered: $hovered ) StyleRow( mode: .tactical, title: "TACTICAL", badge: nil, - description: "Formations, pressing, roles. Function leads.", - detail: "Top scoreboard list · goals · comments.", + description: "Matchups lead. Who each player faces and why it matters.", + detail: "Best for analytical breakdowns and individual battles.", hovered: $hovered ) } @@ -97,18 +97,34 @@ private struct StyleRow: View { var isHovered: Bool { hovered == mode } + private var iconName: String { + switch mode { + case .stats: return "chart.bar.fill" + case .story: return "book.fill" + case .tactical: return "point.3.connected.trianglepath.dotted" + } + } + + private var label: String { + switch mode { + case .stats: return "DATA" + case .story: return "ARC" + case .tactical: return "MATCH" + } + } + var body: some View { Button { store.spottingMode = mode store.selectedSurface = .research } label: { HStack(alignment: .top, spacing: 14) { - // Stat preview block - VStack(alignment: .trailing, spacing: 2) { - Text(mode == .stats ? "5.2" : mode == .story ? "W/L" : "4-3") - .font(.system(size: 18, weight: .semibold, design: .monospaced)) + // Mode icon + VStack(spacing: 2) { + Image(systemName: iconName) + .font(.system(size: 22, weight: .regular)) .foregroundStyle(Color.textPrimary) - Text(mode == .stats ? "xG" : mode == .story ? "Cup Final" : "Formation") + Text(label) .font(Typography.chip) .foregroundStyle(Color.textSubtle) } diff --git a/BroadcastBrain/Views/NewsTabView.swift b/BroadcastBrain/Views/NewsTabView.swift index b6db3d3b..fc1175f8 100644 --- a/BroadcastBrain/Views/NewsTabView.swift +++ b/BroadcastBrain/Views/NewsTabView.swift @@ -1,4 +1,5 @@ import SwiftUI +import AppKit struct NewsTabView: View { @Environment(AppStore.self) private var store @@ -10,6 +11,9 @@ struct NewsTabView: View { @State private var errorMessage: String? @State private var statusMessage: String? + @State private var selectionMode = false + @State private var selectedIds: Set = [] + private let leagueFilters: [(key: String, label: String)] = [ ("all", "ALL"), ("nfl", "NFL"), @@ -57,7 +61,12 @@ struct NewsTabView: View { ScrollView { LazyVStack(alignment: .leading, spacing: 8) { ForEach(filteredItems) { item in - NewsRow(item: item) + NewsRow( + item: item, + selectionMode: selectionMode, + isSelected: selectedIds.contains(item.id), + onToggleSelection: { toggleSelection(item) } + ) } } .padding(20) @@ -74,11 +83,30 @@ struct NewsTabView: View { private var header: some View { VStack(alignment: .leading, spacing: 10) { - HStack { + HStack(spacing: 8) { Text("NEWS") .font(Typography.sectionHead) .foregroundStyle(Color.textSubtle) Spacer() + + Button(action: toggleSelectionMode) { + HStack(spacing: 4) { + Image(systemName: selectionMode ? "checkmark.square.fill" : "square") + .font(.system(size: 11)) + Text(selectionMode + ? "\(selectedIds.count) SELECTED" + : "SELECT ARTICLES" + ) + .font(Typography.chip) + } + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(selectionMode ? Color.bgHover : Color.bgRaised, in: RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + .foregroundStyle(Color.textPrimary) + } + .buttonStyle(.plain) + Button(action: { Task { await refresh() } }) { HStack(spacing: 4) { Image(systemName: "arrow.clockwise") @@ -96,7 +124,7 @@ struct NewsTabView: View { } else { Image(systemName: "sparkles") } - Text("Synthesize to Research Notes").font(Typography.chip) + Text(synthesizeButtonLabel).font(Typography.chip) } .padding(.horizontal, 10) .padding(.vertical, 6) @@ -121,6 +149,15 @@ struct NewsTabView: View { .overlay(Divider().background(Color.bbBorder), alignment: .bottom) } + private var synthesizeButtonLabel: String { + if selectionMode { + return selectedIds.isEmpty + ? "Select articles to synthesize" + : "Synthesize \(selectedIds.count) selected" + } + return "Synthesize all to notes" + } + private func leagueChip(_ filter: (key: String, label: String)) -> some View { let selected = selectedLeague == filter.key return Button(action: { selectedLeague = filter.key }) { @@ -136,11 +173,34 @@ struct NewsTabView: View { } private var canSynthesize: Bool { - !items.isEmpty && !isSynthesizing + guard !isSynthesizing else { return false } + if selectionMode { return !selectedIds.isEmpty } + return !items.isEmpty + } + + private var synthesisPool: [NewsItem] { + if selectionMode { + return items.filter { selectedIds.contains($0.id) } + } + let scoped = filteredItems + return scoped.isEmpty ? items : scoped } // MARK: - Actions + private func toggleSelectionMode() { + selectionMode.toggle() + if !selectionMode { selectedIds.removeAll() } + } + + private func toggleSelection(_ item: NewsItem) { + if selectedIds.contains(item.id) { + selectedIds.remove(item.id) + } else { + selectedIds.insert(item.id) + } + } + private func refresh() async { isLoading = true errorMessage = nil @@ -153,24 +213,32 @@ struct NewsTabView: View { } private func synthesize() async { - guard !items.isEmpty else { return } + let pool = synthesisPool + guard !pool.isEmpty else { return } isSynthesizing = true errorMessage = nil - statusMessage = "Synthesizing with Gemini…" + let label = selectionMode ? "selected" : "filtered" + statusMessage = "Reading \(pool.count) \(label) headline\(pool.count == 1 ? "" : "s")…" let matchTitle = store.matchCache?.title let playerNames = (store.matchCache?.players ?? []).map(\.name) - let pool = filteredItems.isEmpty ? items : filteredItems + + // Short pause so the first message is readable before the request starts. + try? await Task.sleep(nanoseconds: 250_000_000) + await MainActor.run { self.statusMessage = "Writing the digest…" } do { let digest = try await GeminiService.synthesizeNews( headlines: pool, matchTitle: matchTitle, - playerNames: playerNames + playerNames: playerNames, + userCurated: selectionMode ) await MainActor.run { + self.statusMessage = "Appending to Research notes…" appendDigestToNotes(digest) self.isSynthesizing = false + self.selectedIds.removeAll() self.statusMessage = "Saved to Research notes." } } catch { @@ -197,39 +265,91 @@ struct NewsTabView: View { private struct NewsRow: View { let item: NewsItem + let selectionMode: Bool + let isSelected: Bool + let onToggleSelection: () -> Void + + @State private var hovered = false + + private var articleURL: URL? { + guard let s = item.articleUrl, let url = URL(string: s) else { return nil } + return url + } + + private var strokeColor: Color { + if selectionMode && isSelected { return Color.live } + return hovered ? Color.textMuted : Color.bbBorder + } var body: some View { - VStack(alignment: .leading, spacing: 4) { - HStack(spacing: 6) { - Text(item.leagueLabel) - .font(Typography.chip) - .padding(.horizontal, 6) - .padding(.vertical, 2) - .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 3)) - .foregroundStyle(Color.textMuted) - if !item.published.isEmpty { - Text(item.published.prefix(10)) - .font(.system(size: 9, design: .monospaced)) - .foregroundStyle(Color.textSubtle) + Button(action: handleTap) { + HStack(alignment: .top, spacing: 10) { + if selectionMode { + Image(systemName: isSelected ? "checkmark.square.fill" : "square") + .font(.system(size: 14)) + .foregroundStyle(isSelected ? Color.live : Color.textSubtle) + .padding(.top, 2) + } + + VStack(alignment: .leading, spacing: 4) { + HStack(spacing: 6) { + Text(item.leagueLabel) + .font(Typography.chip) + .padding(.horizontal, 6) + .padding(.vertical, 2) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 3)) + .foregroundStyle(Color.textMuted) + if !item.published.isEmpty { + Text(item.published.prefix(10)) + .font(.system(size: 9, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + } + Spacer() + if !selectionMode && articleURL != nil { + Image(systemName: "arrow.up.right.square") + .font(.system(size: 10)) + .foregroundStyle(hovered ? Color.textPrimary : Color.textSubtle) + } + } + Text(item.headline) + .font(Typography.body) + .foregroundStyle(Color.textPrimary) + .lineLimit(3) + .fixedSize(horizontal: false, vertical: true) + .multilineTextAlignment(.leading) + if !item.description.isEmpty { + Text(item.description) + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + .lineLimit(2) + .fixedSize(horizontal: false, vertical: true) + .multilineTextAlignment(.leading) + } } - Spacer() - } - Text(item.headline) - .font(Typography.body) - .foregroundStyle(Color.textPrimary) - .lineLimit(3) - .fixedSize(horizontal: false, vertical: true) - if !item.description.isEmpty { - Text(item.description) - .font(Typography.chip) - .foregroundStyle(Color.textMuted) - .lineLimit(2) - .fixedSize(horizontal: false, vertical: true) } + .padding(10) + .frame(maxWidth: .infinity, alignment: .leading) + .background( + (selectionMode && isSelected) ? Color.live.opacity(0.08) + : (hovered ? Color.bgHover : Color.bgRaised), + in: RoundedRectangle(cornerRadius: 4) + ) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(strokeColor, lineWidth: 1)) + .contentShape(Rectangle()) + } + .buttonStyle(.plain) + .disabled(!selectionMode && articleURL == nil) + .onHover { hovered = $0 } + .help(selectionMode + ? (isSelected ? "Deselect" : "Select for synthesis") + : (articleURL?.absoluteString ?? "No link available")) + } + + private func handleTap() { + if selectionMode { + onToggleSelection() + } else if let url = articleURL { + NSWorkspace.shared.open(url) } - .padding(10) - .frame(maxWidth: .infinity, alignment: .leading) - .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 4)) - .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) } } diff --git a/BroadcastBrain/Views/ResearchCenterView.swift b/BroadcastBrain/Views/ResearchCenterView.swift index 6b843153..ce6fd336 100644 --- a/BroadcastBrain/Views/ResearchCenterView.swift +++ b/BroadcastBrain/Views/ResearchCenterView.swift @@ -2,8 +2,7 @@ import SwiftUI struct ResearchCenterView: View { @Environment(AppStore.self) private var store - @State private var promptText: String = "" - @State private var isSending = false + @State private var showingNotes = false var body: some View { VStack(spacing: 0) { @@ -13,25 +12,60 @@ struct ResearchCenterView: View { latencyMs: store.lastLatencyMs ) - if store.spottingMode == nil { - ZStack { - Color.bgBase - CommentatorStylePickerView() - } - } else if store.spottingMode == .stats { - StatsFirstSpottingBoardView() - } else if store.spottingMode == .story { - StoryFirstSpottingBoardView() - } else if store.spottingMode == .tactical { - TacticalSpottingBoardView() - } else { - HSplitView { + HStack(spacing: 0) { + modeContent + .frame(maxWidth: .infinity, maxHeight: .infinity) + + if showingNotes && store.spottingMode != nil { + Rectangle().fill(Color.bbBorder).frame(width: 1) notesColumn - chatColumn + .frame(width: 360) + .transition(.move(edge: .trailing).combined(with: .opacity)) } } } .background(Color.bgBase) + .overlay(alignment: .topTrailing) { + if store.spottingMode != nil { + notesToggle + .padding(.top, 52) + .padding(.trailing, 16) + } + } + .animation(.easeInOut(duration: 0.2), value: showingNotes) + } + + @ViewBuilder + private var modeContent: some View { + if store.spottingMode == nil { + ZStack { + Color.bgBase + CommentatorStylePickerView() + } + } else if store.spottingMode == .stats { + StatsFirstSpottingBoardView() + } else if store.spottingMode == .story { + StoryFirstSpottingBoardView() + } else if store.spottingMode == .tactical { + TacticalSpottingBoardView() + } + } + + private var notesToggle: some View { + Button(action: { showingNotes.toggle() }) { + HStack(spacing: 5) { + Image(systemName: showingNotes ? "chevron.right" : "note.text") + .font(.system(size: 10, weight: .semibold)) + Text(showingNotes ? "HIDE" : "NOTES") + .font(Typography.chip) + } + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(showingNotes ? Color.live : Color.bgRaised, in: RoundedRectangle(cornerRadius: 4)) + .foregroundStyle(showingNotes ? Color.white : Color.textPrimary) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) } private var notesColumn: some View { @@ -57,104 +91,7 @@ struct ResearchCenterView: View { .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 4)) .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) } - .padding(20) - .frame(minWidth: 340) + .padding(16) .background(Color.bgBase) } - - private var chatColumn: some View { - VStack(spacing: 0) { - HStack { - Text("Q&A · GROUNDED IN MATCH CACHE") - .font(Typography.sectionHead) - .foregroundStyle(Color.textSubtle) - Spacer() - } - .padding(.horizontal, 20) - .padding(.top, 20) - .padding(.bottom, 8) - - ScrollView { - VStack(alignment: .leading, spacing: 4) { - ForEach(store.currentSession.researchMessages) { m in - ChatMessageRow(message: m) - } - if store.currentSession.researchMessages.isEmpty { - VStack(alignment: .leading, spacing: 6) { - Text("Ask grounded questions about the match.") - .font(Typography.body) - .foregroundStyle(Color.textMuted) - Text("e.g. \"How many WC goals does Mbappé have?\"") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - .padding(.top, 12) - } - } - .padding(.horizontal, 20) - } - - HStack(spacing: 8) { - TextField("Ask a research question…", text: $promptText, onCommit: send) - .textFieldStyle(.plain) - .font(Typography.body) - .foregroundStyle(Color.textPrimary) - .padding(10) - .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 4)) - .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) - - Button(action: send) { - Image(systemName: "arrow.up.circle.fill") - .font(.system(size: 24)) - .foregroundStyle(canSend ? Color.live : Color.textSubtle) - } - .buttonStyle(.plain) - .disabled(!canSend) - } - .padding(20) - } - .frame(minWidth: 340) - .background(Color.bgBase) - } - - private var canSend: Bool { - !isSending && !promptText.trimmingCharacters(in: .whitespaces).isEmpty - } - - private func send() { - let text = promptText.trimmingCharacters(in: .whitespaces) - guard !text.isEmpty, !isSending else { return } - promptText = "" - isSending = true - store.appendResearchMessage(ChatMessage(role: .user, content: text, grounded: false)) - - Task { - let facts = store.matchCache?.facts.joined(separator: "\n- ") ?? "" - let system = """ - You are a match research assistant. Answer from the verified facts below only. - If you don't know, say exactly: "I don't have verified data on that." - Keep answers under 3 sentences. - """ - let user = """ - Match facts: - - \(facts) - - Match: \(store.currentSession.title). Question: \(text) - """ - do { - let reply = try await store.cactus.complete(system: system, user: user) - let grounded = !reply.lowercased().contains("don't have verified") - && !reply.lowercased().contains("don't have that") - await MainActor.run { - store.appendResearchMessage(ChatMessage(role: .assistant, content: reply, grounded: grounded)) - isSending = false - } - } catch { - await MainActor.run { - store.appendResearchMessage(ChatMessage(role: .assistant, content: "Error: \(error.localizedDescription)", grounded: false)) - isSending = false - } - } - } - } } From d025c6326125f5aeec4cb50fab018dfe8039d83a Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:02:33 -0700 Subject: [PATCH 05/18] =?UTF-8?q?Merge=20main=20into=20feat/dynamic-match-?= =?UTF-8?q?fetch=20(drops=20PlayByPlayKit/NewMatchSheet=20=E2=80=94=20inco?= =?UTF-8?q?mpatible=20with=20TeamSetupView=20flow)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BroadcastBrain.xcodeproj/project.pbxproj | 126 ++--- BroadcastBrain/BroadcastBrainApp.swift | 6 +- BroadcastBrain/Stores/PlayByPlayStore.swift | 168 ------- BroadcastBrain/Views/LivePaneView.swift | 2 +- BroadcastBrain/Views/NewMatchSheet.swift | 240 ---------- BroadcastBrain/Views/PlaysDBView.swift | 362 -------------- BroadcastBrain/Views/PlaysSearchView.swift | 446 ------------------ BroadcastBrain/Views/PlaysStreamView.swift | 149 ------ PlayByPlayKit/.gitignore | 6 - PlayByPlayKit/Package.swift | 17 - .../PlayByPlayKit/AthleteResponse.swift | 14 - .../Sources/PlayByPlayKit/Compactor.swift | 146 ------ .../Sources/PlayByPlayKit/ESPNClient.swift | 29 -- .../Sources/PlayByPlayKit/Helpers.swift | 59 --- .../Sources/PlayByPlayKit/League.swift | 45 -- .../Sources/PlayByPlayKit/LiveSession.swift | 153 ------ .../Sources/PlayByPlayKit/Models.swift | 97 ---- .../Sources/PlayByPlayKit/PlayByPlay.swift | 41 -- .../PlayByPlayKit/PlayByPlayError.swift | 30 -- .../Sources/PlayByPlayKit/PlaysFetcher.swift | 104 ---- .../Sources/PlayByPlayKit/RawPlay.swift | 146 ------ .../Sources/PlayByPlayKit/Scoreboard.swift | 66 --- .../PlayByPlayKit/SessionStorage.swift | 46 -- .../Sources/PlayByPlayKit/SportCleaners.swift | 106 ----- .../Sources/PlayByPlayKit/SportFields.swift | 116 ----- .../PlayByPlayKitTests/CompactorTests.swift | 152 ------ .../PlayByPlayKitTests/LeagueTests.swift | 38 -- .../PlayByPlayKitTests/LiveSessionTests.swift | 197 -------- .../PlayByPlayKitTests/MockURLProtocol.swift | 56 --- .../PlayByPlayKitTests/ScoreboardTests.swift | 60 --- .../SessionStorageTests.swift | 95 ---- .../SportCleanerTests.swift | 125 ----- project.yml | 6 - 33 files changed, 38 insertions(+), 3411 deletions(-) delete mode 100644 BroadcastBrain/Stores/PlayByPlayStore.swift delete mode 100644 BroadcastBrain/Views/NewMatchSheet.swift delete mode 100644 BroadcastBrain/Views/PlaysDBView.swift delete mode 100644 BroadcastBrain/Views/PlaysSearchView.swift delete mode 100644 BroadcastBrain/Views/PlaysStreamView.swift delete mode 100644 PlayByPlayKit/.gitignore delete mode 100644 PlayByPlayKit/Package.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/League.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Models.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/RawPlay.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Scoreboard.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift delete mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift delete mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift delete mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift delete mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift delete mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift delete mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift delete mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift delete mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift diff --git a/BroadcastBrain.xcodeproj/project.pbxproj b/BroadcastBrain.xcodeproj/project.pbxproj index 3ebc9d8d..e943bbd9 100644 --- a/BroadcastBrain.xcodeproj/project.pbxproj +++ b/BroadcastBrain.xcodeproj/project.pbxproj @@ -7,9 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 00799F9CED5F78ECAA28985A /* StoryFirstSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22F62487F851CC49522E8D29 /* StoryFirstSpottingBoardView.swift */; }; 034498E25A8850984493C9E2 /* SessionStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1186F00AC31EE683675AE6 /* SessionStoreTests.swift */; }; 053617CC8A80BFBB884CF402 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */; }; - 0CC48F247E683B3FB185A6FB /* PlayByPlayStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846A697EC3777956030AC4C3 /* PlayByPlayStore.swift */; }; + 06A1F33ECBAF18586AC02A37 /* NewsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA68D7CA900438A10D7B4AC9 /* NewsService.swift */; }; 0F02EBD664051BF052EF7012 /* ModelCodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2491DE25F4F75DA94526903 /* ModelCodableTests.swift */; }; 162B595396D5974D448E5A8C /* AppStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C2E3CFAB5CA8C1AD68FB5B /* AppStore.swift */; }; 164F7E394D28280CBD14A11D /* StackCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B521A0B659765D883F5E4C /* StackCard.swift */; }; @@ -21,24 +22,17 @@ 43DB7EFEFC8C19A84E734EF6 /* DottedGrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82A885FF039D9F376DE27C84 /* DottedGrid.swift */; }; 45CB73E5789C135680D10F96 /* FlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9C5C443A7D8D3D41E5B0E13 /* FlowLayout.swift */; }; 4888A82003BDA03F00D954CD /* LivePill.swift in Sources */ = {isa = PBXBuildFile; fileRef = B79E4BA0F9248D3466873BBE /* LivePill.swift */; }; - 5874FC398254108334E944D0 /* PlaysSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 721C2BA2DE9BCD5F29F526F0 /* PlaysSearchView.swift */; }; + 4DD529CF07EB0CCAB762BEAF /* NewsTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE805D3AE864A2EC89074CF1 /* NewsTabView.swift */; }; 5982407B776A2A4BF04125BA /* StatCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE64AD9C32691F3111C8595F /* StatCardView.swift */; }; 67EED72EDEC3D8621574A4BC /* ResearchCenterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */; }; - AA1B2C3D4E5F6A7B8C9D0E1F /* CommentatorStylePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB2C3D4E5F6A7B8C9D0E1F2A /* CommentatorStylePickerView.swift */; }; - CC3D4E5F6A7B8C9D0E1F2A3B /* StatsFirstSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD4E5F6A7B8C9D0E1F2A3B4C /* StatsFirstSpottingBoardView.swift */; }; - EE5F6A7B8C9D0E1F2A3B4C5D /* StoryFirstSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6A7B8C9D0E1F2A3B4C5D6E /* StoryFirstSpottingBoardView.swift */; }; - A1B2C3D4E5F60718293A4B5C /* TacticalSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */; }; - F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */; }; - A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */; }; - C4D5E6F708192930A1B2C3D4 /* NewsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5E6F708192930A1B2C3D4E5 /* NewsService.swift */; }; - E6F708192930A1B2C3D4E5F6 /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F708192930A1B2C3D4E5F607 /* GeminiService.swift */; }; - 08192930A1B2C3D4E5F60718 /* NewsTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 192930A1B2C3D4E5F6071829 /* NewsTabView.swift */; }; 70BA18D24CCC880D502CADD7 /* SquadsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */; }; 70BC25E15A41151CA931A4B9 /* cactus-macos.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */; }; 73474C0EE14E2A4A9B79742C /* LivePaneView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01550DE4B92113B1173C6B2F /* LivePaneView.swift */; }; 75823BF5B5A04A60E2C364D1 /* Tokens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51919B20535309C89D4E15B9 /* Tokens.swift */; }; 76BD684BF4DDC88E49946E2E /* BroadcastBrainApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90487A3CA3F809A1CFB8ED20 /* BroadcastBrainApp.swift */; }; 77475FBA9D6370A088D71876 /* StatusBarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A2069035A22848052FAF13B0 /* StatusBarView.swift */; }; + 7B4224664340A548BC7BDC06 /* StatsFirstSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3CC277C30947157232CFF61 /* StatsFirstSpottingBoardView.swift */; }; + 7B7EF85462746C3A72D2CF0B /* CommentatorStylePickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54D3D58CDEAD133FF9CB941E /* CommentatorStylePickerView.swift */; }; 7EE3DFD6034A989F9599CB72 /* ThemeStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EF6CAC9075A33368706F52FE /* ThemeStore.swift */; }; 8597296F58177F87BE1CEE5E /* TranscriptOverlay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AAA500ADFDDF5CAD7707BAD /* TranscriptOverlay.swift */; }; 875A1F9F21CE58F78EBD1DAE /* ArchivesListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8CC045EB8451818A6CD5A1ED /* ArchivesListView.swift */; }; @@ -48,18 +42,17 @@ AE9607AB8A5E0C197FFB861E /* PlayerCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 029080D103ECBCC33E9E38F8 /* PlayerCellView.swift */; }; B0DA6E09C0BD2DD22E1CCC99 /* match_cache.json in Resources */ = {isa = PBXBuildFile; fileRef = AF50D005DA852CAE53DC0E99 /* match_cache.json */; }; B28DD1DE6BE6197370BB602C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB90A6DC8002673826C8BD0 /* ContentView.swift */; }; - B2FBCA5535B628A8827395B7 /* PlaysStreamView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C131AA2D56A147325E0E848 /* PlaysStreamView.swift */; }; - B5ABF69FE9AFDAD11C56621B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 154FDBDC815FD074D17C258E /* Assets.xcassets */; }; B6F4346E4C192BF816F68EAA /* Cactus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B9451069B6343C41C337AC /* Cactus.swift */; }; BA8DD13242C5D90231FBF21E /* ArchiveDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05EF9474EB26DF74B8D7FDAA /* ArchiveDetailView.swift */; }; - BBE476D5CF788B4125A50962 /* PlaysDBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */; }; + C072623647D8C5AF5C70080D /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBAB314A003AE79E3D7E3791 /* GeminiService.swift */; }; C2EC1CB5DC0D4914B540E12A /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF9FC0FE9D60DC37A1594C96 /* Session.swift */; }; - C418A911A2E29B77BEAEDAF8 /* NewMatchSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E714CFC5D1F7C7748D159C9D /* NewMatchSheet.swift */; }; C51482DD2F2F981AD8D640F5 /* SportradarBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EAD55D55FDE50021FA38E3 /* SportradarBadge.swift */; }; + CC3B9BF6F21086368795B456 /* TeamSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1F0EA67AFC55CE71E2374 /* TeamSetupView.swift */; }; D2F4BB6524F4500D144AF80C /* CactusService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90AFD39809B3E0BE8DF8644B /* CactusService.swift */; }; - DC5AA753C120F87BE6240707 /* PlayByPlayKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5C1A4F9118E151B9F0F57F22 /* PlayByPlayKit */; }; + D72A2274675152B2E545ED57 /* TacticalSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1F12695D4CB88A451D3918D /* TacticalSpottingBoardView.swift */; }; DF2E26836A96D0D12400BA94 /* ListeningDot.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE877181D0D2EB6F44FCF490 /* ListeningDot.swift */; }; E05C57FFDF0F3B9977139753 /* LatencyTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AE6D73A8667738DD33BAF2B /* LatencyTag.swift */; }; + E16958E56C7E41CCDE6D3B46 /* GameFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D12F4621EA52FEBDFBBA9E09 /* GameFetchService.swift */; }; E31D20151B71FBD3257BF1D8 /* MockResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CE728CE31ACC8F9DB7324B9 /* MockResponder.swift */; }; ED24D8E788873134C2FEEBCA /* SessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F5FE8926459F794E4A039D /* SessionStore.swift */; }; FC54722D2160DEDE13F882C0 /* GlassSegmentedPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E53DB1034B149B17293FE383 /* GlassSegmentedPicker.swift */; }; @@ -93,32 +86,22 @@ 01550DE4B92113B1173C6B2F /* LivePaneView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LivePaneView.swift; sourceTree = ""; }; 029080D103ECBCC33E9E38F8 /* PlayerCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerCellView.swift; sourceTree = ""; }; 05EF9474EB26DF74B8D7FDAA /* ArchiveDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchiveDetailView.swift; sourceTree = ""; }; + 0CE1F0EA67AFC55CE71E2374 /* TeamSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamSetupView.swift; sourceTree = ""; }; 10B521A0B659765D883F5E4C /* StackCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackCard.swift; sourceTree = ""; }; 1227A240F189BB798494FD0F /* Waveform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Waveform.swift; sourceTree = ""; }; - 154FDBDC815FD074D17C258E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 1BDB3FB2A46D89FB8F6E528D /* BroadcastBrain.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BroadcastBrain.app; sourceTree = BUILT_PRODUCTS_DIR; }; 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResearchCenterView.swift; sourceTree = ""; }; - BB2C3D4E5F6A7B8C9D0E1F2A /* CommentatorStylePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentatorStylePickerView.swift; sourceTree = ""; }; - DD4E5F6A7B8C9D0E1F2A3B4C /* StatsFirstSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsFirstSpottingBoardView.swift; sourceTree = ""; }; - FF6A7B8C9D0E1F2A3B4C5D6E /* StoryFirstSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryFirstSpottingBoardView.swift; sourceTree = ""; }; - B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalSpottingBoardView.swift; sourceTree = ""; }; - E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameFetchService.swift; sourceTree = ""; }; - B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeamSetupView.swift; sourceTree = ""; }; - D5E6F708192930A1B2C3D4E5 /* NewsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsService.swift; sourceTree = ""; }; - F708192930A1B2C3D4E5F607 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; - 192930A1B2C3D4E5F6071829 /* NewsTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsTabView.swift; sourceTree = ""; }; + 22F62487F851CC49522E8D29 /* StoryFirstSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoryFirstSpottingBoardView.swift; sourceTree = ""; }; 4132AE323E5FEB98D3E225B8 /* cactus-macos.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = "cactus-macos.xcframework"; path = "BroadcastBrain/Frameworks/cactus-macos.xcframework"; sourceTree = ""; }; 46EAD55D55FDE50021FA38E3 /* SportradarBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SportradarBadge.swift; sourceTree = ""; }; 51919B20535309C89D4E15B9 /* Tokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tokens.swift; sourceTree = ""; }; + 54D3D58CDEAD133FF9CB941E /* CommentatorStylePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentatorStylePickerView.swift; sourceTree = ""; }; 57DC475ADA91F2B5E0A8A94C /* MockResponderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockResponderTests.swift; sourceTree = ""; }; - 721C2BA2DE9BCD5F29F526F0 /* PlaysSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaysSearchView.swift; sourceTree = ""; }; 757AB2F3C722DB4440337D1A /* PressToTalkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PressToTalkButton.swift; sourceTree = ""; }; - 7C131AA2D56A147325E0E848 /* PlaysStreamView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaysStreamView.swift; sourceTree = ""; }; 7CE728CE31ACC8F9DB7324B9 /* MockResponder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockResponder.swift; sourceTree = ""; }; 7DD86CEF67DA77208349168F /* BroadcastBrainTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BroadcastBrainTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 82A885FF039D9F376DE27C84 /* DottedGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DottedGrid.swift; sourceTree = ""; }; 82B9451069B6343C41C337AC /* Cactus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cactus.swift; sourceTree = ""; }; - 846A697EC3777956030AC4C3 /* PlayByPlayStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayByPlayStore.swift; sourceTree = ""; }; 8AE6D73A8667738DD33BAF2B /* LatencyTag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatencyTag.swift; sourceTree = ""; }; 8CC045EB8451818A6CD5A1ED /* ArchivesListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchivesListView.swift; sourceTree = ""; }; 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SquadsView.swift; sourceTree = ""; }; @@ -134,20 +117,23 @@ B4F1237976FCC7179733FC75 /* ChatMessageRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageRow.swift; sourceTree = ""; }; B79E4BA0F9248D3466873BBE /* LivePill.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LivePill.swift; sourceTree = ""; }; B83E5A0C129A26A3CC625311 /* AudioCaptureService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioCaptureService.swift; sourceTree = ""; }; - B94DFFB69D5F724350D835B4 /* PlayByPlayKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = PlayByPlayKit; path = PlayByPlayKit; sourceTree = SOURCE_ROOT; }; B9C5C443A7D8D3D41E5B0E13 /* FlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowLayout.swift; sourceTree = ""; }; BAB90A6DC8002673826C8BD0 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; C3A6A719D484016893C42760 /* MatchCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchCache.swift; sourceTree = ""; }; C706D6F845EC11E12CA3B0F5 /* BroadcastBrain.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = BroadcastBrain.entitlements; sourceTree = ""; }; C9F5FE8926459F794E4A039D /* SessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionStore.swift; sourceTree = ""; }; CD1186F00AC31EE683675AE6 /* SessionStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionStoreTests.swift; sourceTree = ""; }; + D12F4621EA52FEBDFBBA9E09 /* GameFetchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameFetchService.swift; sourceTree = ""; }; + E3CC277C30947157232CFF61 /* StatsFirstSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsFirstSpottingBoardView.swift; sourceTree = ""; }; E5059B3472C8B2022AC33356 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; E53DB1034B149B17293FE383 /* GlassSegmentedPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlassSegmentedPicker.swift; sourceTree = ""; }; - E714CFC5D1F7C7748D159C9D /* NewMatchSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewMatchSheet.swift; sourceTree = ""; }; + EA68D7CA900438A10D7B4AC9 /* NewsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsService.swift; sourceTree = ""; }; EE877181D0D2EB6F44FCF490 /* ListeningDot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListeningDot.swift; sourceTree = ""; }; EF6CAC9075A33368706F52FE /* ThemeStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeStore.swift; sourceTree = ""; }; - F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaysDBView.swift; sourceTree = ""; }; + F1F12695D4CB88A451D3918D /* TacticalSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalSpottingBoardView.swift; sourceTree = ""; }; + FBAB314A003AE79E3D7E3791 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = ""; }; + FE805D3AE864A2EC89074CF1 /* NewsTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsTabView.swift; sourceTree = ""; }; FF9FC0FE9D60DC37A1594C96 /* Session.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Session.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -157,7 +143,6 @@ buildActionMask = 2147483647; files = ( 70BC25E15A41151CA931A4B9 /* cactus-macos.xcframework in Frameworks */, - DC5AA753C120F87BE6240707 /* PlayByPlayKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -169,20 +154,16 @@ children = ( 05EF9474EB26DF74B8D7FDAA /* ArchiveDetailView.swift */, 8CC045EB8451818A6CD5A1ED /* ArchivesListView.swift */, - BB2C3D4E5F6A7B8C9D0E1F2A /* CommentatorStylePickerView.swift */, - DD4E5F6A7B8C9D0E1F2A3B4C /* StatsFirstSpottingBoardView.swift */, - FF6A7B8C9D0E1F2A3B4C5D6E /* StoryFirstSpottingBoardView.swift */, - B2C3D4E5F60718293A4B5C6D /* TacticalSpottingBoardView.swift */, - B3C4D5E6F708192930A1B2C3 /* TeamSetupView.swift */, - 192930A1B2C3D4E5F6071829 /* NewsTabView.swift */, + 54D3D58CDEAD133FF9CB941E /* CommentatorStylePickerView.swift */, 01550DE4B92113B1173C6B2F /* LivePaneView.swift */, - E714CFC5D1F7C7748D159C9D /* NewMatchSheet.swift */, - F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */, - 721C2BA2DE9BCD5F29F526F0 /* PlaysSearchView.swift */, - 7C131AA2D56A147325E0E848 /* PlaysStreamView.swift */, + FE805D3AE864A2EC89074CF1 /* NewsTabView.swift */, 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */, FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */, 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */, + E3CC277C30947157232CFF61 /* StatsFirstSpottingBoardView.swift */, + 22F62487F851CC49522E8D29 /* StoryFirstSpottingBoardView.swift */, + F1F12695D4CB88A451D3918D /* TacticalSpottingBoardView.swift */, + 0CE1F0EA67AFC55CE71E2374 /* TeamSetupView.swift */, 576EFBB721C77F668145738B /* Components */, ); path = Views; @@ -242,7 +223,6 @@ 5E133AC1178766FED41CC012 /* BroadcastBrain */ = { isa = PBXGroup; children = ( - 154FDBDC815FD074D17C258E /* Assets.xcassets */, C706D6F845EC11E12CA3B0F5 /* BroadcastBrain.entitlements */, 90487A3CA3F809A1CFB8ED20 /* BroadcastBrainApp.swift */, BAB90A6DC8002673826C8BD0 /* ContentView.swift */, @@ -269,12 +249,12 @@ isa = PBXGroup; children = ( B83E5A0C129A26A3CC625311 /* AudioCaptureService.swift */, - E0F1A2B3C4D5E6F708192930 /* GameFetchService.swift */, - D5E6F708192930A1B2C3D4E5 /* NewsService.swift */, - F708192930A1B2C3D4E5F607 /* GeminiService.swift */, 82B9451069B6343C41C337AC /* Cactus.swift */, 90AFD39809B3E0BE8DF8644B /* CactusService.swift */, + D12F4621EA52FEBDFBBA9E09 /* GameFetchService.swift */, + FBAB314A003AE79E3D7E3791 /* GeminiService.swift */, 7CE728CE31ACC8F9DB7324B9 /* MockResponder.swift */, + EA68D7CA900438A10D7B4AC9 /* NewsService.swift */, ); path = Services; sourceTree = ""; @@ -284,7 +264,6 @@ children = ( 5E133AC1178766FED41CC012 /* BroadcastBrain */, 2FB4C7AF75A217215F604EB7 /* BroadcastBrainTests */, - F1AA7256D7D83E51F35D717F /* Packages */, D1C7F98E649425E4E53622C6 /* Frameworks */, 65A284292BEEBC0943964CCE /* Products */, ); @@ -294,7 +273,6 @@ isa = PBXGroup; children = ( A5C2E3CFAB5CA8C1AD68FB5B /* AppStore.swift */, - 846A697EC3777956030AC4C3 /* PlayByPlayStore.swift */, C9F5FE8926459F794E4A039D /* SessionStore.swift */, EF6CAC9075A33368706F52FE /* ThemeStore.swift */, ); @@ -309,14 +287,6 @@ name = Frameworks; sourceTree = ""; }; - F1AA7256D7D83E51F35D717F /* Packages */ = { - isa = PBXGroup; - children = ( - B94DFFB69D5F724350D835B4 /* PlayByPlayKit */, - ); - name = Packages; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -353,7 +323,6 @@ ); name = BroadcastBrain; packageProductDependencies = ( - 5C1A4F9118E151B9F0F57F22 /* PlayByPlayKit */, ); productName = BroadcastBrain; productReference = 1BDB3FB2A46D89FB8F6E528D /* BroadcastBrain.app */; @@ -388,9 +357,6 @@ ); mainGroup = AFF55C48CD22E09820BEB37C; minimizedProjectReferenceProxies = 1; - packageReferences = ( - D325D9FCCDF26CC90AFB3972 /* XCLocalSwiftPackageReference "PlayByPlayKit" */, - ); preferredProjectObjectVersion = 77; projectDirPath = ""; projectRoot = ""; @@ -406,7 +372,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - B5ABF69FE9AFDAD11C56621B /* Assets.xcassets in Resources */, B0DA6E09C0BD2DD22E1CCC99 /* match_cache.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -437,18 +402,12 @@ B6F4346E4C192BF816F68EAA /* Cactus.swift in Sources */, D2F4BB6524F4500D144AF80C /* CactusService.swift in Sources */, 30702CFDAB6E91475D9965F5 /* ChatMessageRow.swift in Sources */, - AA1B2C3D4E5F6A7B8C9D0E1F /* CommentatorStylePickerView.swift in Sources */, - CC3D4E5F6A7B8C9D0E1F2A3B /* StatsFirstSpottingBoardView.swift in Sources */, - EE5F6A7B8C9D0E1F2A3B4C5D /* StoryFirstSpottingBoardView.swift in Sources */, - A1B2C3D4E5F60718293A4B5C /* TacticalSpottingBoardView.swift in Sources */, - F1A2B3C4D5E6F7081929A0B1 /* GameFetchService.swift in Sources */, - A2B3C4D5E6F708192930A1B2 /* TeamSetupView.swift in Sources */, - C4D5E6F708192930A1B2C3D4 /* NewsService.swift in Sources */, - E6F708192930A1B2C3D4E5F6 /* GeminiService.swift in Sources */, - 08192930A1B2C3D4E5F60718 /* NewsTabView.swift in Sources */, + 7B7EF85462746C3A72D2CF0B /* CommentatorStylePickerView.swift in Sources */, B28DD1DE6BE6197370BB602C /* ContentView.swift in Sources */, 43DB7EFEFC8C19A84E734EF6 /* DottedGrid.swift in Sources */, 45CB73E5789C135680D10F96 /* FlowLayout.swift in Sources */, + E16958E56C7E41CCDE6D3B46 /* GameFetchService.swift in Sources */, + C072623647D8C5AF5C70080D /* GeminiService.swift in Sources */, FC54722D2160DEDE13F882C0 /* GlassSegmentedPicker.swift in Sources */, E05C57FFDF0F3B9977139753 /* LatencyTag.swift in Sources */, DF2E26836A96D0D12400BA94 /* ListeningDot.swift in Sources */, @@ -456,12 +415,9 @@ 4888A82003BDA03F00D954CD /* LivePill.swift in Sources */, 3689ED92510A4D081B6CBB1E /* MatchCache.swift in Sources */, E31D20151B71FBD3257BF1D8 /* MockResponder.swift in Sources */, - C418A911A2E29B77BEAEDAF8 /* NewMatchSheet.swift in Sources */, - 0CC48F247E683B3FB185A6FB /* PlayByPlayStore.swift in Sources */, + 06A1F33ECBAF18586AC02A37 /* NewsService.swift in Sources */, + 4DD529CF07EB0CCAB762BEAF /* NewsTabView.swift in Sources */, AE9607AB8A5E0C197FFB861E /* PlayerCellView.swift in Sources */, - BBE476D5CF788B4125A50962 /* PlaysDBView.swift in Sources */, - 5874FC398254108334E944D0 /* PlaysSearchView.swift in Sources */, - B2FBCA5535B628A8827395B7 /* PlaysStreamView.swift in Sources */, 41B921C4FB590088E94910D6 /* PressToTalkButton.swift in Sources */, 67EED72EDEC3D8621574A4BC /* ResearchCenterView.swift in Sources */, C2EC1CB5DC0D4914B540E12A /* Session.swift in Sources */, @@ -471,7 +427,11 @@ 70BA18D24CCC880D502CADD7 /* SquadsView.swift in Sources */, 164F7E394D28280CBD14A11D /* StackCard.swift in Sources */, 5982407B776A2A4BF04125BA /* StatCardView.swift in Sources */, + 7B4224664340A548BC7BDC06 /* StatsFirstSpottingBoardView.swift in Sources */, 77475FBA9D6370A088D71876 /* StatusBarView.swift in Sources */, + 00799F9CED5F78ECAA28985A /* StoryFirstSpottingBoardView.swift in Sources */, + D72A2274675152B2E545ED57 /* TacticalSpottingBoardView.swift in Sources */, + CC3B9BF6F21086368795B456 /* TeamSetupView.swift in Sources */, 7EE3DFD6034A989F9599CB72 /* ThemeStore.swift in Sources */, 75823BF5B5A04A60E2C364D1 /* Tokens.swift in Sources */, 8597296F58177F87BE1CEE5E /* TranscriptOverlay.swift in Sources */, @@ -732,20 +692,6 @@ defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ - -/* Begin XCLocalSwiftPackageReference section */ - D325D9FCCDF26CC90AFB3972 /* XCLocalSwiftPackageReference "PlayByPlayKit" */ = { - isa = XCLocalSwiftPackageReference; - relativePath = PlayByPlayKit; - }; -/* End XCLocalSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - 5C1A4F9118E151B9F0F57F22 /* PlayByPlayKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PlayByPlayKit; - }; -/* End XCSwiftPackageProductDependency section */ }; rootObject = B8AC317D5AF7C3382A569AB7 /* Project object */; } diff --git a/BroadcastBrain/BroadcastBrainApp.swift b/BroadcastBrain/BroadcastBrainApp.swift index c99ddc75..2ad637a9 100644 --- a/BroadcastBrain/BroadcastBrainApp.swift +++ b/BroadcastBrain/BroadcastBrainApp.swift @@ -19,11 +19,7 @@ struct BroadcastBrainApp: App { private static func makeStore() -> AppStore { let sessionStore = SessionStore() let cactus: CactusService = makeCactusService() - let cacheDir = FileManager.default - .urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] - .appendingPathComponent("BroadcastBrain/playbyplay", isDirectory: true) - let pbp = PlayByPlayStore(cacheDirectory: cacheDir) - return AppStore(sessionStore: sessionStore, cactus: cactus, playByPlayStore: pbp) + return AppStore(sessionStore: sessionStore, cactus: cactus) } private static func makeCactusService() -> CactusService { diff --git a/BroadcastBrain/Stores/PlayByPlayStore.swift b/BroadcastBrain/Stores/PlayByPlayStore.swift deleted file mode 100644 index e458842d..00000000 --- a/BroadcastBrain/Stores/PlayByPlayStore.swift +++ /dev/null @@ -1,168 +0,0 @@ -import Foundation -import Observation -import PlayByPlayKit - -struct SavedGameEntry: Identifiable, Hashable { - let fileURL: URL - let leagueKey: String - let game: CompactGame - let modifiedAt: Date - var id: String { fileURL.path } -} - -@MainActor -@Observable -final class PlayByPlayStore { - let leagues: [League] = League.all - var selectedLeague: League - var games: [Game] = [] - var searchText: String = "" - var loadingGames: Bool = false - var gamesError: String? - - var selectedGame: Game? - var currentCompact: CompactGame? - var streamError: String? - var isStreaming: Bool = false - var lastUpdated: Date? - - var plays: [CompactPlay] { - guard let c = currentCompact else { return [] } - return c.periods.flatMap { $0.plays } - } - - let cacheDirectory: URL - - private var activeSession: LiveSession? - private var streamTask: Task? - - init(cacheDirectory: URL) { - self.cacheDirectory = cacheDirectory - self.selectedLeague = League.all.first(where: { $0.key == "nba" }) ?? League.all[0] - try? FileManager.default.createDirectory(at: cacheDirectory, withIntermediateDirectories: true) - } - - var filteredGames: [Game] { - let q = searchText.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() - guard !q.isEmpty else { return games } - return games.filter { g in - g.name.lowercased().contains(q) - || g.shortName.lowercased().contains(q) - || g.homeTeam.lowercased().contains(q) - || g.awayTeam.lowercased().contains(q) - } - } - - func loadLiveGames() async { - loadingGames = true - gamesError = nil - defer { loadingGames = false } - do { - let league = selectedLeague - games = try await PlayByPlay.getLiveGames(league) - } catch { - games = [] - gamesError = String(describing: error) - } - } - - func selectLeague(_ league: League) { - guard league != selectedLeague else { return } - selectedLeague = league - games = [] - } - - func startStreaming(_ game: Game) { - stopStreaming() - - selectedGame = game - currentCompact = nil - streamError = nil - isStreaming = true - lastUpdated = nil - - let league = selectedLeague - let cacheDir = cacheDirectory - let session = PlayByPlay.liveSession( - league: league, - game: game, - cacheDirectory: cacheDir, - pollInterval: 0.5, - maxConsecutiveTransientFailures: 20, - onTransientError: nil - ) - activeSession = session - - streamTask = Task { [weak self] in - await session.start() - let stream = await session.deltas - do { - for try await delta in stream { - await MainActor.run { - guard let self else { return } - self.currentCompact = delta.state - self.lastUpdated = Date() - } - if Task.isCancelled { break } - } - } catch { - await MainActor.run { - self?.streamError = String(describing: error) - self?.isStreaming = false - } - } - await MainActor.run { - self?.isStreaming = false - } - } - } - - func stopStreaming() { - streamTask?.cancel() - streamTask = nil - if let session = activeSession { - Task { await session.stop() } - } - activeSession = nil - isStreaming = false - } - - func clearSelection() { - stopStreaming() - selectedGame = nil - currentCompact = nil - streamError = nil - lastUpdated = nil - } - - func listSavedGames() -> [SavedGameEntry] { - let fm = FileManager.default - guard let leagueDirs = try? fm.contentsOfDirectory( - at: cacheDirectory, - includingPropertiesForKeys: [.isDirectoryKey] - ) else { return [] } - - let decoder = JSONDecoder() - var entries: [SavedGameEntry] = [] - for dir in leagueDirs { - var isDir: ObjCBool = false - guard fm.fileExists(atPath: dir.path, isDirectory: &isDir), isDir.boolValue else { continue } - guard let files = try? fm.contentsOfDirectory( - at: dir, - includingPropertiesForKeys: [.contentModificationDateKey] - ) else { continue } - for file in files where file.pathExtension == "json" && !file.lastPathComponent.hasPrefix(".") { - guard let data = try? Data(contentsOf: file), - let game = try? decoder.decode(CompactGame.self, from: data) else { continue } - let mtime = (try? file.resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate) ?? Date.distantPast - entries.append(SavedGameEntry( - fileURL: file, - leagueKey: dir.lastPathComponent, - game: game, - modifiedAt: mtime - )) - } - } - return entries.sorted { $0.modifiedAt > $1.modifiedAt } - } -} diff --git a/BroadcastBrain/Views/LivePaneView.swift b/BroadcastBrain/Views/LivePaneView.swift index 2ee5bd2a..0f96a5f6 100644 --- a/BroadcastBrain/Views/LivePaneView.swift +++ b/BroadcastBrain/Views/LivePaneView.swift @@ -619,7 +619,7 @@ struct LivePaneView: View { if hadContent { // Reuse the same match for the next recording — don't re-prompt // the commentator for team/sport info after each match. - store.newSessionKeepingCurrentMatch() + store.newSession() } // 4. Route to Archive detail view for the just-ended session diff --git a/BroadcastBrain/Views/NewMatchSheet.swift b/BroadcastBrain/Views/NewMatchSheet.swift deleted file mode 100644 index ccd29b7e..00000000 --- a/BroadcastBrain/Views/NewMatchSheet.swift +++ /dev/null @@ -1,240 +0,0 @@ -import SwiftUI - -/// Modal form presented when the commentator starts a new match session. -/// Captures sport, teams, tournament, and venue — saved as a `Match` on the -/// new `Session`. -struct NewMatchSheet: View { - @Environment(AppStore.self) private var store - @Environment(\.dismiss) private var dismiss - - @State private var sport: Sport = .soccer - @State private var homeTeam: String = "" - @State private var awayTeam: String = "" - @State private var tournament: String = "" - @State private var venue: String = "" - @State private var matchDate: Date = Date() - @State private var hasDate: Bool = false - - var body: some View { - VStack(spacing: 0) { - header - form - footer - } - .frame(width: 520) - .background(Color.bgRaised) - .overlay( - RoundedRectangle(cornerRadius: 10) - .stroke(Color.bbBorder, lineWidth: 1) - ) - .clipShape(RoundedRectangle(cornerRadius: 10)) - } - - private var header: some View { - HStack(spacing: 10) { - Image(systemName: "sparkles") - .font(.system(size: 14)) - .foregroundStyle(Color.live) - Text("NEW MATCH") - .font(Typography.sectionHead) - .foregroundStyle(Color.textPrimary) - .tracking(0.6) - Spacer() - Button(action: { store.showNewMatchSheet = false; dismiss() }) { - Image(systemName: "xmark") - .font(.system(size: 11, weight: .medium)) - .foregroundStyle(Color.textSubtle) - .padding(6) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) - } - .buttonStyle(.plain) - } - .padding(.horizontal, 20) - .padding(.vertical, 16) - .background(Color.bgSubtle) - .overlay(alignment: .bottom) { - Rectangle().fill(Color.bbBorder).frame(height: 1) - } - } - - private var form: some View { - VStack(alignment: .leading, spacing: 18) { - field("SPORT") { - HStack(spacing: 6) { - ForEach(primarySports, id: \.self) { option in - sportPill(option) - } - Menu { - ForEach(Sport.allCases.filter { !primarySports.contains($0) }, id: \.self) { s in - Button(s.displayName) { sport = s } - } - } label: { - HStack(spacing: 4) { - Text(primarySports.contains(sport) ? "More" : sport.displayName.uppercased()) - .font(Typography.chip) - Image(systemName: "chevron.down") - .font(.system(size: 8)) - } - .foregroundStyle(!primarySports.contains(sport) ? Color.textPrimary : Color.textMuted) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(!primarySports.contains(sport) ? Color.live.opacity(0.12) : Color.bgSubtle, - in: Capsule()) - .overlay( - Capsule().stroke( - !primarySports.contains(sport) ? Color.live : Color.bbBorder, - lineWidth: 1 - ) - ) - } - .buttonStyle(.plain) - .menuStyle(.borderlessButton) - .menuIndicator(.hidden) - .fixedSize() - } - } - - HStack(spacing: 14) { - field("HOME TEAM") { - textField("Argentina", text: $homeTeam) - } - field("AWAY TEAM") { - textField("France", text: $awayTeam) - } - } - - field("TOURNAMENT") { - textField("2022 World Cup Final", text: $tournament) - } - - field("VENUE") { - textField("Lusail Stadium · Lusail, Qatar", text: $venue) - } - - field("MATCH DATE") { - HStack(spacing: 10) { - Toggle(isOn: $hasDate) { EmptyView() } - .toggleStyle(.switch) - .labelsHidden() - .controlSize(.small) - if hasDate { - DatePicker("", selection: $matchDate, displayedComponents: [.date]) - .labelsHidden() - .datePickerStyle(.compact) - } else { - Text("Not set") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - Spacer() - } - } - } - .padding(20) - } - - private var footer: some View { - VStack(spacing: 8) { - Divider().background(Color.bbBorder) - HStack(spacing: 10) { - Button(action: { store.showNewMatchSheet = false; dismiss() }) { - Text("CANCEL") - .font(Typography.chip) - .tracking(0.6) - .foregroundStyle(Color.textMuted) - .frame(maxWidth: .infinity) - .padding(.vertical, 11) - .background(Color.bgSubtle) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) - .clipShape(RoundedRectangle(cornerRadius: 5)) - } - .buttonStyle(.plain) - - Button(action: submit) { - HStack(spacing: 8) { - Image(systemName: "arrow.right.circle.fill") - .font(.system(size: 12)) - Text("CREATE MATCH") - .font(Typography.chip) - .tracking(0.6) - } - .frame(maxWidth: .infinity) - .padding(.vertical, 11) - .foregroundStyle(Color.textPrimary) - .background(canSubmit ? Color.live : Color.bgHover) - .clipShape(RoundedRectangle(cornerRadius: 5)) - } - .buttonStyle(.plain) - .disabled(!canSubmit) - } - .padding(.horizontal, 20) - .padding(.vertical, 14) - } - .background(Color.bgSubtle) - } - - private var canSubmit: Bool { - !homeTeam.trimmingCharacters(in: .whitespaces).isEmpty - && !awayTeam.trimmingCharacters(in: .whitespaces).isEmpty - } - - private var primarySports: [Sport] { - [.soccer, .basketball, .baseball, .americanFootball, .hockey] - } - - @ViewBuilder - private func field(_ label: String, @ViewBuilder content: () -> Content) -> some View { - VStack(alignment: .leading, spacing: 6) { - Text(label) - .font(.system(size: 9, weight: .semibold, design: .monospaced)) - .foregroundStyle(Color.textSubtle) - .tracking(1.4) - content() - } - } - - private func textField(_ placeholder: String, text: Binding) -> some View { - TextField(placeholder, text: text) - .textFieldStyle(.plain) - .font(Typography.body) - .foregroundStyle(Color.textPrimary) - .padding(.horizontal, 10) - .padding(.vertical, 9) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) - .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) - } - - private func sportPill(_ s: Sport) -> some View { - Button(action: { sport = s }) { - Text(s.displayName.uppercased()) - .font(Typography.chip) - .tracking(0.5) - .foregroundStyle(sport == s ? Color.textPrimary : Color.textMuted) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(sport == s ? Color.live.opacity(0.15) : Color.bgSubtle, - in: Capsule()) - .overlay( - Capsule().stroke( - sport == s ? Color.live : Color.bbBorder, - lineWidth: 1 - ) - ) - } - .buttonStyle(.plain) - } - - private func submit() { - guard canSubmit else { return } - let match = Match( - sport: sport, - homeTeam: homeTeam.trimmingCharacters(in: .whitespaces), - awayTeam: awayTeam.trimmingCharacters(in: .whitespaces), - tournament: tournament.trimmingCharacters(in: .whitespaces), - venue: venue.trimmingCharacters(in: .whitespaces), - matchDate: hasDate ? matchDate : nil - ) - store.createSession(from: match) - dismiss() - } -} diff --git a/BroadcastBrain/Views/PlaysDBView.swift b/BroadcastBrain/Views/PlaysDBView.swift deleted file mode 100644 index ee48b88b..00000000 --- a/BroadcastBrain/Views/PlaysDBView.swift +++ /dev/null @@ -1,362 +0,0 @@ -import SwiftUI -import PlayByPlayKit - -struct PlaysDBView: View { - @Environment(AppStore.self) private var store - - @State private var entries: [SavedGameEntry] = [] - @State private var selected: SavedGameEntry? - @State private var query: String = "" - - var body: some View { - VStack(spacing: 0) { - StatusBarView( - matchTitle: selected?.game.game.shortName ?? "Plays DB · ESPN cache", - isAirplane: false, - latencyMs: nil - ) - - if let sel = selected { - detailHeader(sel) - detailView(sel) - } else { - listHeader - listView - } - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color.bgBase) - .onAppear { reload() } - } - - // MARK: - List header - - private var listHeader: some View { - HStack(spacing: 12) { - Text("SAVED PLAYS") - .font(Typography.sectionHead) - .tracking(1.4) - .foregroundStyle(Color.textSubtle) - - countPill("\(entries.count) GAMES") - - Spacer() - - searchField - - refreshButton - } - .padding(.horizontal, 20) - .padding(.vertical, 12) - .background(Color.bgRaised) - .overlay(alignment: .bottom) { - Rectangle().fill(Color.bbBorder).frame(height: 1) - } - } - - private var searchField: some View { - HStack(spacing: 6) { - Image(systemName: "magnifyingglass") - .font(.system(size: 10, weight: .medium)) - .foregroundStyle(Color.textSubtle) - TextField("Search saved games", text: $query) - .textFieldStyle(.plain) - .font(Typography.chip) - .foregroundStyle(Color.textPrimary) - if !query.isEmpty { - Button { query = "" } label: { - Image(systemName: "xmark.circle.fill") - .font(.system(size: 10)) - .foregroundStyle(Color.textSubtle) - } - .buttonStyle(.plain) - } - } - .padding(.horizontal, 8) - .padding(.vertical, 6) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) - .frame(width: 240) - } - - private var refreshButton: some View { - Button { - reload() - } label: { - Image(systemName: "arrow.clockwise") - .font(.system(size: 11, weight: .semibold)) - .foregroundStyle(Color.textMuted) - .frame(width: 32, height: 30) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) - } - .buttonStyle(.plain) - .help("Re-scan saved games") - } - - private func countPill(_ text: String) -> some View { - Text(text) - .font(.system(size: 9, weight: .semibold, design: .monospaced)) - .tracking(1.2) - .foregroundStyle(Color.textSubtle) - .padding(.horizontal, 6) - .padding(.vertical, 3) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 3)) - .overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.bbBorder, lineWidth: 1)) - } - - // MARK: - List body - - private var filtered: [SavedGameEntry] { - let q = query.trimmingCharacters(in: .whitespaces).lowercased() - guard !q.isEmpty else { return entries } - return entries.filter { - $0.game.game.shortName.lowercased().contains(q) - || $0.leagueKey.lowercased().contains(q) - } - } - - private var listView: some View { - ScrollView { - LazyVStack(spacing: 10) { - if entries.isEmpty { - emptyState - } else if filtered.isEmpty { - noMatchState - } else { - ForEach(filtered) { entry in - SavedGameRow(entry: entry) - .contentShape(Rectangle()) - .onTapGesture { selected = entry } - } - } - } - .padding(20) - } - } - - private var emptyState: some View { - VStack(spacing: 10) { - Image(systemName: "tray") - .font(.system(size: 28, weight: .light)) - .foregroundStyle(Color.textSubtle) - Text("No saved games yet") - .font(Typography.body) - .foregroundStyle(Color.textPrimary) - Text("Start streaming a game from the Plays tab — each play is cached here for offline scrubbing.") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - .multilineTextAlignment(.center) - .frame(maxWidth: 380) - } - .frame(maxWidth: .infinity) - .padding(.vertical, 48) - .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) - .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1)) - } - - private var noMatchState: some View { - Text("No saved games match ‘\(query)’") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - .frame(maxWidth: .infinity) - .padding(.vertical, 32) - .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) - .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1)) - } - - // MARK: - Detail - - private func detailHeader(_ entry: SavedGameEntry) -> some View { - HStack(spacing: 12) { - Button { selected = nil } label: { - HStack(spacing: 4) { - Image(systemName: "chevron.left") - .font(.system(size: 10, weight: .semibold)) - Text("ALL SAVED GAMES") - .font(.system(size: 10, weight: .semibold, design: .monospaced)) - .tracking(1.2) - } - .foregroundStyle(Color.textMuted) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) - } - .buttonStyle(.plain) - - leagueBadge(entry.leagueKey) - - Text(entry.game.game.shortName) - .font(.system(size: 14, weight: .semibold, design: .monospaced)) - .foregroundStyle(Color.textPrimary) - - Text(entry.game.game.statusDetail) - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - - Spacer() - - HStack(spacing: 6) { - Text("\(entry.game.totalPlays)") - .font(.system(size: 14, weight: .bold, design: .monospaced)) - .foregroundStyle(Color.verified) - Text("PLAYS") - .font(.system(size: 9, weight: .semibold, design: .monospaced)) - .tracking(1.2) - .foregroundStyle(Color.textSubtle) - } - } - .padding(.horizontal, 20) - .padding(.vertical, 12) - .background(Color.bgRaised) - .overlay(alignment: .bottom) { - Rectangle().fill(Color.bbBorder).frame(height: 1) - } - } - - private func detailView(_ entry: SavedGameEntry) -> some View { - ScrollView { - LazyVStack(alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders]) { - ForEach(entry.game.periods, id: \.number) { period in - Section { - VStack(alignment: .leading, spacing: 6) { - ForEach(period.plays) { play in - PlayRow(play: play, compact: entry.game) - } - } - .padding(.bottom, 8) - } header: { - HStack(spacing: 10) { - Text(period.displayValue ?? "Period \(period.number)") - .font(.system(size: 10, weight: .semibold, design: .monospaced)) - .tracking(1.6) - .foregroundStyle(Color.textSubtle) - Rectangle().fill(Color.bbBorder).frame(height: 1) - Text("\(period.plays.count)") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - .padding(.vertical, 6) - .background(Color.bgBase) - } - } - } - .padding(20) - } - } - - // MARK: - League badge - - private func leagueBadge(_ key: String) -> some View { - let accent = PlaysDBView.leagueAccent(key) - return Text(key.uppercased()) - .font(.system(size: 9, weight: .bold, design: .monospaced)) - .tracking(1.2) - .foregroundStyle(accent) - .padding(.horizontal, 6) - .padding(.vertical, 3) - .background(accent.opacity(0.12), in: RoundedRectangle(cornerRadius: 3)) - .overlay(RoundedRectangle(cornerRadius: 3).stroke(accent.opacity(0.3), lineWidth: 1)) - } - - static func leagueAccent(_ key: String) -> Color { - switch key.lowercased() { - case let k where k.contains("nba"): return Color(hex: "#E87A00") - case let k where k.contains("mlb"): return Color(hex: "#3B82F6") - case let k where k.contains("nfl"): return Color(hex: "#8B5CF6") - case let k where k.contains("nhl"): return Color(hex: "#22C55E") - case let k where k.contains("mls"), - let k where k.contains("epl"), - let k where k.contains("uefa"): return Color.verified - default: return Color.textMuted - } - } - - private func reload() { - entries = store.playByPlayStore.listSavedGames() - } -} - -// MARK: - Saved game row - -private struct SavedGameRow: View { - let entry: SavedGameEntry - - @State private var hovering = false - - private var accent: Color { PlaysDBView.leagueAccent(entry.leagueKey) } - - var body: some View { - HStack(alignment: .center, spacing: 0) { - Rectangle() - .fill(accent) - .frame(width: 3) - - // League badge - Text(entry.leagueKey.uppercased()) - .font(.system(size: 9, weight: .bold, design: .monospaced)) - .tracking(1.2) - .foregroundStyle(accent) - .frame(width: 52, alignment: .center) - .padding(.vertical, 4) - .background(accent.opacity(0.1), in: RoundedRectangle(cornerRadius: 3)) - .overlay(RoundedRectangle(cornerRadius: 3).stroke(accent.opacity(0.25), lineWidth: 1)) - .padding(.leading, 14) - .padding(.trailing, 14) - - // Matchup - VStack(alignment: .leading, spacing: 3) { - Text(entry.game.game.shortName) - .font(.system(size: 15, weight: .semibold, design: .monospaced)) - .foregroundStyle(Color.textPrimary) - .lineLimit(1) - HStack(spacing: 8) { - Text(entry.game.game.statusDetail) - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - if !entry.game.game.awayScore.isEmpty, !entry.game.game.homeScore.isEmpty { - Text("·") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - Text("\(entry.game.game.awayScore)–\(entry.game.game.homeScore)") - .font(Typography.chip) - .foregroundStyle(Color.textMuted) - } - } - } - - Spacer() - - // Play count hero stat - VStack(alignment: .trailing, spacing: 2) { - HStack(spacing: 5) { - Text("\(entry.game.totalPlays)") - .font(.system(size: 15, weight: .bold, design: .monospaced)) - .foregroundStyle(Color.verified) - Text("PLAYS") - .font(.system(size: 9, weight: .semibold, design: .monospaced)) - .tracking(1.2) - .foregroundStyle(Color.textSubtle) - } - Text(entry.modifiedAt.formatted(date: .abbreviated, time: .shortened)) - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - - Image(systemName: "chevron.right") - .font(.system(size: 10, weight: .semibold)) - .foregroundStyle(hovering ? Color.textPrimary : Color.textSubtle) - .padding(.leading, 12) - .padding(.trailing, 14) - } - .padding(.vertical, 12) - .frame(maxWidth: .infinity) - .background(hovering ? Color.bgHover : Color.bgRaised) - .overlay( - RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1) - ) - .clipShape(RoundedRectangle(cornerRadius: 6)) - .onHover { hovering = $0 } - } -} diff --git a/BroadcastBrain/Views/PlaysSearchView.swift b/BroadcastBrain/Views/PlaysSearchView.swift deleted file mode 100644 index eada45e4..00000000 --- a/BroadcastBrain/Views/PlaysSearchView.swift +++ /dev/null @@ -1,446 +0,0 @@ -import SwiftUI -import PlayByPlayKit - -struct PlaysSearchView: View { - @Environment(AppStore.self) private var store - - var body: some View { - @Bindable var pbp = store.playByPlayStore - - VStack(spacing: 0) { - StatusBarView( - matchTitle: "Plays · ESPN feed", - isAirplane: false, - latencyMs: nil - ) - - header(pbp: pbp) - - if pbp.selectedGame != nil { - PlaysStreamView() - } else { - scoreboard(pbp: pbp) - } - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color.bgBase) - .task { - if pbp.games.isEmpty && pbp.selectedGame == nil { - await pbp.loadLiveGames() - } - } - } - - // MARK: - Header - - private func header(pbp: PlayByPlayStore) -> some View { - HStack(spacing: 12) { - leaguePicker(pbp: pbp) - searchField(pbp: pbp) - refreshButton(pbp: pbp) - } - .padding(.horizontal, 20) - .padding(.vertical, 12) - .background(Color.bgRaised) - .overlay(alignment: .bottom) { - Rectangle().fill(Color.bbBorder).frame(height: 1) - } - } - - private func leaguePicker(pbp: PlayByPlayStore) -> some View { - Menu { - ForEach(pbp.leagues, id: \.key) { league in - Button(league.displayName) { - pbp.selectedLeague = league - pbp.games = [] - Task { await pbp.loadLiveGames() } - } - } - } label: { - LeagueDropdownLabel(name: pbp.selectedLeague.displayName) - } - .menuStyle(.borderlessButton) - .menuIndicator(.hidden) - .fixedSize() - } - - private func searchField(pbp: PlayByPlayStore) -> some View { - SearchFieldRow( - text: Binding( - get: { pbp.searchText }, - set: { pbp.searchText = $0 } - ) - ) - } - - private func refreshButton(pbp: PlayByPlayStore) -> some View { - Button { - Task { await pbp.loadLiveGames() } - } label: { - Group { - if pbp.loadingGames { - ProgressView().controlSize(.small) - } else { - Image(systemName: "arrow.clockwise") - .font(.system(size: 11, weight: .semibold)) - .foregroundStyle(Color.textMuted) - } - } - .frame(width: 32, height: 30) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) - } - .buttonStyle(.plain) - .help("Refresh live games") - } - - // MARK: - Scoreboard - - private func scoreboard(pbp: PlayByPlayStore) -> some View { - ScrollView { - LazyVStack(spacing: 18, pinnedViews: [.sectionHeaders]) { - if let err = pbp.gamesError { - errorBanner(err) - } - - let grouped = GameGroup.group(pbp.filteredGames) - - if grouped.isEmpty && !pbp.loadingGames { - emptyState(leagueName: pbp.selectedLeague.displayName, - hasQuery: !pbp.searchText.isEmpty) - } - - ForEach(grouped, id: \.status) { bucket in - Section { - VStack(spacing: 8) { - ForEach(bucket.games) { game in - GameRow(game: game) - .contentShape(Rectangle()) - .onTapGesture { pbp.startStreaming(game) } - } - } - } header: { - sectionHeader(bucket) - } - } - } - .padding(20) - } - } - - private func sectionHeader(_ bucket: GameGroup) -> some View { - HStack(spacing: 10) { - if bucket.status == .live { - LiveDot() - } - Text(bucket.status.label) - .font(.system(size: 10, weight: .semibold, design: .monospaced)) - .tracking(1.6) - .foregroundStyle(bucket.status == .live ? Color.live : Color.textSubtle) - Rectangle().fill(Color.bbBorder).frame(height: 1) - Text("\(bucket.games.count)") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - .padding(.vertical, 6) - .background(Color.bgBase) - } - - private func errorBanner(_ text: String) -> some View { - HStack(spacing: 8) { - Image(systemName: "exclamationmark.triangle.fill") - .font(.system(size: 11)) - .foregroundStyle(Color.live) - Text(text) - .font(Typography.chip) - .foregroundStyle(Color.textPrimary) - } - .padding(.horizontal, 12) - .padding(.vertical, 10) - .frame(maxWidth: .infinity, alignment: .leading) - .background(Color.live.opacity(0.08), in: RoundedRectangle(cornerRadius: 6)) - .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.live.opacity(0.3), lineWidth: 1)) - } - - private func emptyState(leagueName: String, hasQuery: Bool) -> some View { - VStack(spacing: 10) { - Image(systemName: hasQuery ? "magnifyingglass" : "sportscourt") - .font(.system(size: 28, weight: .light)) - .foregroundStyle(Color.textSubtle) - Text(hasQuery ? "No matches" : "No live games") - .font(Typography.body) - .foregroundStyle(Color.textPrimary) - Text(hasQuery - ? "Try a different team name or switch leagues." - : "\(leagueName) has no games in progress. Check back later or refresh.") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - .multilineTextAlignment(.center) - } - .frame(maxWidth: .infinity) - .padding(.vertical, 48) - .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) - .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1)) - } -} - -// MARK: - Grouping - -enum GameStatus: Int, CaseIterable { - case live, scheduled, final, other - - var label: String { - switch self { - case .live: return "LIVE NOW" - case .scheduled: return "UPCOMING" - case .final: return "COMPLETED" - case .other: return "OTHER" - } - } - - static func from(_ raw: String) -> GameStatus { - let s = raw.lowercased() - if s.contains("in progress") || s.contains("halftime") || s.contains("delay") { return .live } - if s.contains("scheduled") || s.contains("pre") || s.contains("upcoming") { return .scheduled } - if s.contains("final") || s.contains("full time") || s.contains("end of") { return .final } - return .other - } -} - -struct GameGroup { - let status: GameStatus - let games: [Game] - - static func group(_ games: [Game]) -> [GameGroup] { - var byStatus: [GameStatus: [Game]] = [:] - for g in games { - byStatus[GameStatus.from(g.status), default: []].append(g) - } - return GameStatus.allCases.compactMap { s in - guard let list = byStatus[s], !list.isEmpty else { return nil } - return GameGroup(status: s, games: list) - } - } -} - -// MARK: - Row - -private struct GameRow: View { - let game: Game - @State private var hovering = false - - private var status: GameStatus { GameStatus.from(game.status) } - - private var homeWin: Bool { - guard let h = Int(game.homeScore), let a = Int(game.awayScore) else { return false } - return h > a - } - - private var awayWin: Bool { - guard let h = Int(game.homeScore), let a = Int(game.awayScore) else { return false } - return a > h - } - - private var accentColor: Color { - switch status { - case .live: return Color.live - case .scheduled: return Color.esoteric - case .final: return Color.verified - case .other: return Color.bbBorder - } - } - - var body: some View { - HStack(alignment: .center, spacing: 0) { - // Accent stripe - Rectangle() - .fill(accentColor) - .frame(width: 3) - - // Status pill column (fixed width) - statusPill - .frame(width: 90, alignment: .leading) - .padding(.leading, 14) - - // Matchup (fixed width) - HStack(spacing: 8) { - Text(awayAbbr) - .font(.system(size: 16, weight: .bold, design: .monospaced)) - .foregroundStyle(awayWin && status == .final ? Color.textPrimary : Color.textMuted) - Text("@") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - Text(homeAbbr) - .font(.system(size: 16, weight: .bold, design: .monospaced)) - .foregroundStyle(homeWin && status == .final ? Color.textPrimary : Color.textMuted) - } - .frame(width: 160, alignment: .leading) - - // Teams + score - VStack(alignment: .leading, spacing: 3) { - teamLine(name: game.awayTeam, score: game.awayScore, isWinner: awayWin) - teamLine(name: game.homeTeam, score: game.homeScore, isWinner: homeWin) - } - - Spacer() - - // Period / detail - Text(game.period.isEmpty ? game.statusDetail : game.period) - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - .lineLimit(1) - - Image(systemName: "chevron.right") - .font(.system(size: 10, weight: .semibold)) - .foregroundStyle(hovering ? Color.textPrimary : Color.textSubtle) - .padding(.leading, 12) - .padding(.trailing, 14) - } - .padding(.vertical, 12) - .frame(maxWidth: .infinity) - .background(hovering ? Color.bgHover : Color.bgRaised) - .overlay( - RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1) - ) - .clipShape(RoundedRectangle(cornerRadius: 6)) - .onHover { hovering = $0 } - } - - // MARK: sub-views - - private var awayAbbr: String { game.awayTeamAbbr ?? String(game.awayTeam.prefix(3)).uppercased() } - private var homeAbbr: String { game.homeTeamAbbr ?? String(game.homeTeam.prefix(3)).uppercased() } - - @ViewBuilder - private var statusPill: some View { - switch status { - case .live: - HStack(spacing: 5) { - LiveDot() - Text("LIVE") - .font(.system(size: 9, weight: .bold, design: .monospaced)) - .tracking(1.2) - .foregroundStyle(Color.live) - } - .padding(.horizontal, 6) - .padding(.vertical, 3) - .background(Color.live.opacity(0.12), in: RoundedRectangle(cornerRadius: 3)) - .overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.live.opacity(0.35), lineWidth: 1)) - case .scheduled: - pill("UPCOMING", color: .esoteric) - case .final: - pill("FINAL", color: .textSubtle) - case .other: - pill(game.status.uppercased(), color: .textSubtle) - } - } - - private func pill(_ text: String, color: Color) -> some View { - Text(text) - .font(.system(size: 9, weight: .bold, design: .monospaced)) - .tracking(1.2) - .foregroundStyle(color) - .padding(.horizontal, 6) - .padding(.vertical, 3) - .background(color.opacity(0.1), in: RoundedRectangle(cornerRadius: 3)) - .overlay(RoundedRectangle(cornerRadius: 3).stroke(color.opacity(0.25), lineWidth: 1)) - } - - private func teamLine(name: String, score: String, isWinner: Bool) -> some View { - HStack(spacing: 8) { - Text(name) - .font(.system(size: 12, weight: isWinner ? .semibold : .regular, design: .monospaced)) - .foregroundStyle(isWinner ? Color.textPrimary : Color.textMuted) - .lineLimit(1) - Spacer(minLength: 6) - Text(score) - .font(.system(size: 13, weight: .bold, design: .monospaced)) - .foregroundStyle(isWinner ? Color.textPrimary : Color.textMuted) - .frame(minWidth: 28, alignment: .trailing) - } - .frame(maxWidth: 280) - } -} - -private struct LeagueDropdownLabel: View { - let name: String - @State private var hovering = false - - var body: some View { - HStack(spacing: 10) { - Text("LEAGUE") - .font(.system(size: 8, weight: .bold, design: .monospaced)) - .tracking(1.4) - .foregroundStyle(Color.textSubtle) - .padding(.horizontal, 5) - .padding(.vertical, 2) - .background(Color.bgBase, in: RoundedRectangle(cornerRadius: 2)) - .overlay(RoundedRectangle(cornerRadius: 2).stroke(Color.bbBorder, lineWidth: 1)) - - Text(name.uppercased()) - .font(.system(size: 12, weight: .semibold, design: .monospaced)) - .tracking(0.6) - .foregroundStyle(Color.textPrimary) - - Rectangle() - .fill(Color.bbBorder) - .frame(width: 1, height: 16) - - Image(systemName: "chevron.down") - .font(.system(size: 10, weight: .bold)) - .foregroundStyle(hovering ? Color.textPrimary : Color.textMuted) - } - .padding(.horizontal, 10) - .padding(.vertical, 8) - .background(hovering ? Color.bgHover : Color.bgRaised) - .overlay( - RoundedRectangle(cornerRadius: 6) - .stroke(Color.bbBorder, lineWidth: 1) - ) - .clipShape(RoundedRectangle(cornerRadius: 6)) - .contentShape(Rectangle()) - .onHover { hovering = $0 } - } -} - -private struct SearchFieldRow: View { - @Binding var text: String - - var body: some View { - HStack(spacing: 6) { - Image(systemName: "magnifyingglass") - .font(.system(size: 10, weight: .medium)) - .foregroundStyle(Color.textSubtle) - TextField("Filter by team", text: $text) - .textFieldStyle(.plain) - .font(Typography.chip) - .foregroundStyle(Color.textPrimary) - if !text.isEmpty { - Button { text = "" } label: { - Image(systemName: "xmark.circle.fill") - .font(.system(size: 10)) - .foregroundStyle(Color.textSubtle) - } - .buttonStyle(.plain) - } - } - .padding(.horizontal, 8) - .padding(.vertical, 6) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) - .frame(maxWidth: .infinity) - } -} - -private struct LiveDot: View { - @State private var pulse = false - var body: some View { - Circle() - .fill(Color.live) - .frame(width: 6, height: 6) - .scaleEffect(pulse ? 1.3 : 0.85) - .opacity(pulse ? 0.5 : 1.0) - .animation(.easeInOut(duration: 0.7).repeatForever(), value: pulse) - .onAppear { pulse = true } - } -} diff --git a/BroadcastBrain/Views/PlaysStreamView.swift b/BroadcastBrain/Views/PlaysStreamView.swift deleted file mode 100644 index b121f05e..00000000 --- a/BroadcastBrain/Views/PlaysStreamView.swift +++ /dev/null @@ -1,149 +0,0 @@ -import SwiftUI -import PlayByPlayKit - -struct PlaysStreamView: View { - @Environment(AppStore.self) private var store - - private var pbp: PlayByPlayStore { store.playByPlayStore } - - var body: some View { - VStack(spacing: 0) { - header - Divider().background(Color.bbBorder) - - if let err = pbp.streamError { - Text(err) - .font(Typography.body) - .foregroundStyle(Color.live) - .padding(12) - } - - ScrollView { - LazyVStack(alignment: .leading, spacing: 6) { - ForEach(pbp.plays.reversed()) { play in - PlayRow(play: play, compact: pbp.currentCompact) - } - } - .padding(16) - } - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .background(Color.bgBase) - } - - private var header: some View { - HStack(spacing: 12) { - Button { pbp.clearSelection() } label: { - HStack(spacing: 4) { - Image(systemName: "chevron.left") - .font(.system(size: 10, weight: .semibold)) - Text("ALL GAMES") - .font(.system(size: 10, weight: .semibold, design: .monospaced)) - .tracking(1.2) - } - .foregroundStyle(Color.textMuted) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) - } - .buttonStyle(.plain) - .help("Back to game list") - - VStack(alignment: .leading, spacing: 2) { - Text(pbp.selectedGame?.shortName ?? "") - .font(.system(size: 14, weight: .semibold, design: .monospaced)) - .foregroundStyle(Color.textPrimary) - Text(streamStatus) - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - Spacer() - if let game = pbp.currentCompact?.game { - Text("\(game.awayTeam) \(game.awayScore) — \(game.homeScore) \(game.homeTeam)") - .font(Typography.statLabel) - .foregroundStyle(Color.textMuted) - } - Button { - pbp.clearSelection() - } label: { - HStack(spacing: 6) { - Image(systemName: "stop.fill") - .font(.system(size: 9)) - Text("STOP") - .font(.system(size: 10, weight: .bold, design: .monospaced)) - .tracking(1.2) - } - .foregroundStyle(Color.live) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(Color.live.opacity(0.1), in: RoundedRectangle(cornerRadius: 5)) - .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.live.opacity(0.35), lineWidth: 1)) - } - .buttonStyle(.plain) - .help("Stop streaming") - } - .padding(.horizontal, 20) - .padding(.vertical, 12) - .background(Color.bgRaised) - } - - private var streamStatus: String { - if pbp.streamError != nil { return "stopped · error" } - if pbp.isStreaming { return "streaming · polling every 500ms · \(pbp.plays.count) plays" } - return "\(pbp.plays.count) plays" - } -} - -struct PlayRow: View { - let play: CompactPlay - let compact: CompactGame? - - var body: some View { - HStack(alignment: .top, spacing: 10) { - VStack(alignment: .leading, spacing: 2) { - Text(periodLabel) - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - Text(play.clock ?? "") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - .frame(width: 62, alignment: .leading) - - VStack(alignment: .leading, spacing: 4) { - Text(headline) - .font(Typography.body) - .foregroundStyle(Color.textPrimary) - .fixedSize(horizontal: false, vertical: true) - if let teamName = teamName { - Text(teamName) - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - } - } - Spacer() - if play.scoringPlay == true { - Text("SCORE") - .font(Typography.chip) - .foregroundStyle(Color.verified) - } - } - .padding(10) - .background(Color.bgRaised) - .clipShape(RoundedRectangle(cornerRadius: 6)) - } - - private var periodLabel: String { - play.period?.displayValue ?? play.period.map { "P\($0.number)" } ?? "" - } - - private var headline: String { - play.text ?? play.type ?? "—" - } - - private var teamName: String? { - guard let id = play.teamId, let team = compact?.teams[id] else { return nil } - return team.name ?? team.abbreviation - } -} diff --git a/PlayByPlayKit/.gitignore b/PlayByPlayKit/.gitignore deleted file mode 100644 index 7635adac..00000000 --- a/PlayByPlayKit/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.build/ -.swiftpm/ -Packages/ -*.xcodeproj -DerivedData/ -.DS_Store diff --git a/PlayByPlayKit/Package.swift b/PlayByPlayKit/Package.swift deleted file mode 100644 index f42ac28f..00000000 --- a/PlayByPlayKit/Package.swift +++ /dev/null @@ -1,17 +0,0 @@ -// swift-tools-version: 5.9 -import PackageDescription - -let package = Package( - name: "PlayByPlayKit", - platforms: [ - .iOS(.v15), - .macOS(.v12), - ], - products: [ - .library(name: "PlayByPlayKit", targets: ["PlayByPlayKit"]), - ], - targets: [ - .target(name: "PlayByPlayKit"), - .testTarget(name: "PlayByPlayKitTests", dependencies: ["PlayByPlayKit"]), - ] -) diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift b/PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift deleted file mode 100644 index ecd7b138..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift +++ /dev/null @@ -1,14 +0,0 @@ -import Foundation - -struct AthleteResponse: Decodable { - let id: String? - let displayName: String? - let fullName: String? - let jersey: String? - let position: Position? - - struct Position: Decodable { - let abbreviation: String? - let displayName: String? - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift b/PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift deleted file mode 100644 index 3cd3ff80..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift +++ /dev/null @@ -1,146 +0,0 @@ -import Foundation - -enum Compactor { - static func compactPlay( - _ raw: RawPlay, - sport: String, - athletes: inout [String: Athlete] - ) -> CompactPlay { - var participants: [CompactParticipant]? - if let parts = raw.participants, !parts.isEmpty { - participants = parts.map { p in - let id = ESPNRef.extractId(from: p.athlete?.ref) - return CompactParticipant(athleteId: id, type: p.type, order: p.order) - } - } - - var sportFields: SportFields? - switch sport { - case "baseball": - sportFields = .baseball(SportCleaners.cleanBaseball(raw)) - case "basketball": - sportFields = .basketball(SportCleaners.cleanBasketball(raw)) - case "football": - sportFields = .football(SportCleaners.cleanFootball(raw)) - case "hockey": - sportFields = .hockey(SportCleaners.cleanHockey(raw)) - case "soccer": - sportFields = .soccer(SportCleaners.cleanSoccer(raw)) - default: - sportFields = nil - } - - let periodInfo: PeriodInfo? = raw.period.map { p in - PeriodInfo(number: p.number ?? 0, type: p.type, displayValue: p.displayValue) - } - - return CompactPlay( - id: raw.id, - seq: raw.sequenceNumber, - type: raw.type?.text, - text: raw.text, - awayScore: raw.awayScore, - homeScore: raw.homeScore, - clock: raw.clock?.displayValue, - scoringPlay: raw.scoringPlay, - scoreValue: raw.scoreValue, - wallclock: raw.wallclock, - teamId: ESPNRef.extractId(from: raw.team?.ref), - participants: participants, - period: periodInfo, - sportFields: sportFields - ) - } - - static func compactGame( - league: League, - game: Game, - rawPlays: [RawPlay], - athleteMap: [String: AthleteResponse] - ) -> CompactGame { - var athletes: [String: Athlete] = [:] - var teams: [String: TeamRef] = [:] - - if let id = game.homeTeamId { - teams[id] = TeamRef(name: game.homeTeam, abbreviation: game.homeTeamAbbr) - } - if let id = game.awayTeamId { - teams[id] = TeamRef(name: game.awayTeam, abbreviation: game.awayTeamAbbr) - } - - // Pre-populate athletes from resolved refs. - for (ref, a) in athleteMap { - let id = a.id ?? ESPNRef.extractId(from: ref) - guard let id, let name = a.displayName ?? a.fullName else { continue } - if athletes[id] == nil { - athletes[id] = Athlete( - name: name, - jersey: a.jersey, - position: a.position?.abbreviation ?? a.position?.displayName - ) - } - } - - struct PeriodKey: Hashable { - let number: Int - let type: String - } - var orderedKeys: [PeriodKey] = [] - var byKey: [PeriodKey: (type: String?, displayValue: String?, plays: [CompactPlay])] = [:] - - for raw in rawPlays { - let cp = compactPlay(raw, sport: league.sport, athletes: &athletes) - let number = raw.period?.number ?? 0 - let typeStr = raw.period?.type ?? "" - let key = PeriodKey(number: number, type: typeStr) - if byKey[key] == nil { - byKey[key] = (type: raw.period?.type, displayValue: raw.period?.displayValue, plays: []) - orderedKeys.append(key) - } - byKey[key]!.plays.append(cp) - } - - let periods = orderedKeys.map { key -> CompactPeriod in - let v = byKey[key]! - return CompactPeriod(number: key.number, type: v.type, displayValue: v.displayValue, plays: v.plays) - } - - return CompactGame( - league: LeagueRef(key: league.key, sport: league.sport, league: league.league), - game: GameSummary( - id: game.id, - name: game.name, - shortName: game.shortName, - status: game.status, - statusDetail: game.statusDetail, - awayTeam: game.awayTeam, - homeTeam: game.homeTeam, - awayScore: game.awayScore, - homeScore: game.homeScore - ), - totalPlays: rawPlays.count, - athletes: athletes, - teams: teams, - periods: periods - ) - } - - /// Returns the last play ID across all periods (walking back-to-front). - static func lastCompactPlayId(_ game: CompactGame?) -> String? { - guard let game else { return nil } - for period in game.periods.reversed() { - if let last = period.plays.last { return last.id } - } - return nil - } - - /// Returns plays in `next` that appear after `lastId` in `next`'s own order. - /// If `lastId` is nil (cold start), all plays are considered new. - /// If `lastId` isn't found in `next`, all of `next`'s plays are considered new. - static func diffNewPlays(prev: CompactGame?, next: CompactGame) -> [CompactPlay] { - let allNext = next.periods.flatMap { $0.plays } - guard let lastId = lastCompactPlayId(prev) else { return allNext } - guard let idx = allNext.firstIndex(where: { $0.id == lastId }) else { return allNext } - return Array(allNext[allNext.index(after: idx)...]) - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift b/PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift deleted file mode 100644 index 9f380cba..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift +++ /dev/null @@ -1,29 +0,0 @@ -import Foundation - -struct ESPNClient: Sendable { - let session: URLSession - - init(session: URLSession = .shared) { - self.session = session - } - - func fetchJSON(_ url: URL, as type: T.Type = T.self) async throws -> T { - let data: Data - let response: URLResponse - do { - (data, response) = try await session.data(from: url) - } catch { - throw error - } - - if let http = response as? HTTPURLResponse, !(200..<300).contains(http.statusCode) { - throw PlayByPlayError.http(status: http.statusCode, url: url) - } - - do { - return try JSONDecoder().decode(T.self, from: data) - } catch { - throw PlayByPlayError(decoding: error, context: url.absoluteString) - } - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift b/PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift deleted file mode 100644 index d330f466..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift +++ /dev/null @@ -1,59 +0,0 @@ -import Foundation - -public struct Coordinate: Hashable, Sendable, Codable { - public let x: Double? - public let y: Double? - public init(x: Double?, y: Double?) { - self.x = x - self.y = y - } -} - -public struct PitchCount: Hashable, Sendable, Codable { - public let balls: Int? - public let strikes: Int? - public init(balls: Int?, strikes: Int?) { - self.balls = balls - self.strikes = strikes - } -} - -public struct DriveMarker: Hashable, Sendable, Codable { - public let down: Int? - public let distance: Int? - public let yardLine: Int? - public let yardsToEndzone: Int? - public let downDistance: String? - public let possession: String? - public let teamId: String? -} - -public struct TeamParticipant: Hashable, Sendable, Codable { - public let teamId: String? - public let order: Int? - public let type: String? -} - -public struct FieldPosition: Hashable, Sendable, Codable { - public let x: Double? - public let y: Double? -} - -public struct GoalPosition: Hashable, Sendable, Codable { - public let x: Double? - public let y: Double? - public let z: Double? -} - -enum ESPNRef { - static func extractId(from url: String?) -> String? { - guard let url else { return nil } - guard let regex = try? NSRegularExpression(pattern: #"/(?:teams|athletes|positions)/(\d+)"#) else { return nil } - let range = NSRange(url.startIndex..., in: url) - guard let match = regex.firstMatch(in: url, range: range), match.numberOfRanges >= 2 else { - return nil - } - guard let r = Range(match.range(at: 1), in: url) else { return nil } - return String(url[r]) - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/League.swift b/PlayByPlayKit/Sources/PlayByPlayKit/League.swift deleted file mode 100644 index f7a4574c..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/League.swift +++ /dev/null @@ -1,45 +0,0 @@ -import Foundation - -public struct League: Hashable, Sendable, Codable { - public let key: String - public let sport: String - public let league: String - public let displayName: String - - public init(key: String, sport: String, league: String, displayName: String) { - self.key = key - self.sport = sport - self.league = league - self.displayName = displayName - } -} - -public extension League { - static let all: [League] = [ - League(key: "mlb", sport: "baseball", league: "mlb", displayName: "MLB — Baseball"), - League(key: "nba", sport: "basketball", league: "nba", displayName: "NBA — Basketball"), - League(key: "wnba", sport: "basketball", league: "wnba", displayName: "WNBA — Basketball"), - League(key: "ncaam", sport: "basketball", league: "mens-college-basketball", displayName: "NCAAM — College Basketball"), - League(key: "ncaaw", sport: "basketball", league: "womens-college-basketball", displayName: "NCAAW — College Basketball"), - League(key: "nfl", sport: "football", league: "nfl", displayName: "NFL — Football"), - League(key: "ncaaf", sport: "football", league: "college-football", displayName: "NCAAF — College Football"), - League(key: "nhl", sport: "hockey", league: "nhl", displayName: "NHL — Hockey"), - League(key: "epl", sport: "soccer", league: "eng.1", displayName: "EPL — Soccer"), - League(key: "laliga", sport: "soccer", league: "esp.1", displayName: "La Liga — Soccer"), - League(key: "seriea", sport: "soccer", league: "ita.1", displayName: "Serie A — Soccer"), - League(key: "bundesliga", sport: "soccer", league: "ger.1", displayName: "Bundesliga — Soccer"), - League(key: "ligue1", sport: "soccer", league: "fra.1", displayName: "Ligue 1 — Soccer"), - League(key: "ucl", sport: "soccer", league: "uefa.champions", displayName: "UEFA Champions League — Soccer"), - League(key: "mls", sport: "soccer", league: "usa.1", displayName: "MLS — Soccer"), - ] -} - -enum ESPNEndpoints { - static func scoreboardURL(_ l: League) -> URL { - URL(string: "https://site.api.espn.com/apis/site/v2/sports/\(l.sport)/\(l.league)/scoreboard")! - } - - static func playByPlayURL(_ l: League, gameId: String, limit: Int = 1000) -> URL { - URL(string: "https://sports.core.api.espn.com/v2/sports/\(l.sport)/leagues/\(l.league)/events/\(gameId)/competitions/\(gameId)/plays?limit=\(limit)")! - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift b/PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift deleted file mode 100644 index d1c90e28..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift +++ /dev/null @@ -1,153 +0,0 @@ -import Foundation - -public actor LiveSession { - private let league: League - private let game: Game - private let cacheDirectory: URL - private let pollInterval: TimeInterval - private let maxConsecutiveTransientFailures: Int - private let onTransientError: (@Sendable (Error) -> Void)? - private let client: ESPNClient - private let fetcher: PlaysFetcher - private let athleteCache = AthleteCache() - - private var state: CompactGame? - private var pollTask: Task? - private var continuation: AsyncThrowingStream.Continuation? - private var stream: AsyncThrowingStream? - private var consecutiveFailures: Int = 0 - private var started = false - - init( - league: League, - game: Game, - cacheDirectory: URL, - pollInterval: TimeInterval, - maxConsecutiveTransientFailures: Int, - onTransientError: (@Sendable (Error) -> Void)?, - session: URLSession - ) { - self.league = league - self.game = game - self.cacheDirectory = cacheDirectory - self.pollInterval = pollInterval - self.maxConsecutiveTransientFailures = maxConsecutiveTransientFailures - self.onTransientError = onTransientError - self.client = ESPNClient(session: session) - self.fetcher = PlaysFetcher(client: client) - } - - public nonisolated var deltas: AsyncThrowingStream { - get async { - await makeStreamIfNeeded() - } - } - - private func makeStreamIfNeeded() -> AsyncThrowingStream { - if let stream { return stream } - let (s, cont) = AsyncThrowingStream.makeStream() - self.stream = s - self.continuation = cont - cont.onTermination = { [weak self] _ in - Task { [weak self] in await self?.stop() } - } - return s - } - - public func currentState() -> CompactGame? { state } - - public func start() async { - guard !started else { return } - started = true - _ = makeStreamIfNeeded() - - // Seed from disk if present. - let url = SessionStorage.cacheFileURL( - root: cacheDirectory, - leagueKey: league.key, - shortName: game.shortName - ) - if let disk = try? SessionStorage.read(url) { - self.state = disk - await athleteCache.seed(disk.athletes) - } - - pollTask = Task { [weak self] in - await self?.pollLoop(cacheURL: url) - } - } - - public func stop() async { - pollTask?.cancel() - pollTask = nil - continuation?.finish() - continuation = nil - } - - private func pollLoop(cacheURL: URL) async { - while !Task.isCancelled { - await tickOnce(cacheURL: cacheURL) - if Task.isCancelled { return } - if pollTask == nil { return } - do { - try await cancellableSleep(pollInterval) - } catch { - return - } - } - } - - private func tickOnce(cacheURL: URL) async { - do { - let rawPlays = try await fetcher.fetchRawPlays(league: league, gameId: game.id) - await fetcher.resolveAthletes(for: rawPlays, cache: athleteCache) - let resolvedMap = await athleteCache.snapshot() - let newCompact = Compactor.compactGame( - league: league, - game: game, - rawPlays: rawPlays, - athleteMap: resolvedMap - ) - let newPlays = Compactor.diffNewPlays(prev: state, next: newCompact) - if !newPlays.isEmpty || state == nil { - state = newCompact - try SessionStorage.write(newCompact, to: cacheURL) - continuation?.yield(PlayDelta(newPlays: newPlays, state: newCompact)) - } - consecutiveFailures = 0 - } catch { - if isPermanent(error) { - continuation?.finish(throwing: error) - pollTask?.cancel() - pollTask = nil - return - } - consecutiveFailures += 1 - onTransientError?(error) - if consecutiveFailures >= maxConsecutiveTransientFailures { - continuation?.finish(throwing: error) - pollTask?.cancel() - pollTask = nil - } - } - } - - private func cancellableSleep(_ seconds: TimeInterval) async throws { - let nanos = UInt64(max(0, seconds) * 1_000_000_000) - try await Task.sleep(nanoseconds: nanos) - } - - private func isPermanent(_ error: Error) -> Bool { - if let e = error as? PlayByPlayError { - switch e { - case .http(let status, _): - return (400..<500).contains(status) - case .decoding, .invalidAthleteRef: - return true - case .io, .cancelled: - return false - } - } - return false - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/Models.swift b/PlayByPlayKit/Sources/PlayByPlayKit/Models.swift deleted file mode 100644 index 6446aad3..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/Models.swift +++ /dev/null @@ -1,97 +0,0 @@ -import Foundation - -public struct Game: Identifiable, Hashable, Sendable, Codable { - public let id: String - public let name: String - public let shortName: String - public let status: String - public let statusDetail: String - public let homeTeam: String - public let awayTeam: String - public let homeScore: String - public let awayScore: String - public let period: String - public let homeTeamId: String? - public let awayTeamId: String? - public let homeTeamAbbr: String? - public let awayTeamAbbr: String? -} - -public struct Athlete: Hashable, Sendable, Codable { - public let name: String - public let jersey: String? - public let position: String? -} - -public struct CompactParticipant: Hashable, Sendable, Codable { - public let athleteId: String? - public let type: String? - public let order: Int? -} - -public struct LeagueRef: Hashable, Sendable, Codable { - public let key: String - public let sport: String - public let league: String -} - -public struct GameSummary: Hashable, Sendable, Codable { - public let id: String - public let name: String - public let shortName: String - public let status: String - public let statusDetail: String - public let awayTeam: String - public let homeTeam: String - public let awayScore: String - public let homeScore: String -} - -public struct TeamRef: Hashable, Sendable, Codable { - public let name: String? - public let abbreviation: String? -} - -public struct CompactPlay: Identifiable, Hashable, Sendable, Codable { - public let id: String - public var seq: String? - public var type: String? - public var text: String? - public var awayScore: Int? - public var homeScore: Int? - public var clock: String? - public var scoringPlay: Bool? - public var scoreValue: Int? - public var wallclock: String? - public var teamId: String? - public var participants: [CompactParticipant]? - public var period: PeriodInfo? - public var sportFields: SportFields? -} - -public struct PeriodInfo: Hashable, Sendable, Codable { - public let number: Int - public let type: String? - public let displayValue: String? -} - -public struct CompactPeriod: Hashable, Sendable, Codable { - public let number: Int - public let type: String? - public let displayValue: String? - public let plays: [CompactPlay] -} - -public struct CompactGame: Hashable, Sendable, Codable { - public let league: LeagueRef - public let game: GameSummary - public let totalPlays: Int - public let athletes: [String: Athlete] - public let teams: [String: TeamRef] - public let periods: [CompactPeriod] -} - -public struct PlayDelta: Sendable { - public let newPlays: [CompactPlay] - public let state: CompactGame -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift b/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift deleted file mode 100644 index 8a1ecb0b..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift +++ /dev/null @@ -1,41 +0,0 @@ -import Foundation - -public enum PlayByPlay { - public static var leagues: [League] { League.all } - - public static func getLiveGames(_ league: League, session: URLSession = .shared) async throws -> [Game] { - let client = ESPNClient(session: session) - let response: ScoreboardResponse = try await client.fetchJSON(ESPNEndpoints.scoreboardURL(league)) - return Scoreboard.toGames(response) - } - - public static func getPlays(_ league: League, game: Game, session: URLSession = .shared) async throws -> CompactGame { - let client = ESPNClient(session: session) - let fetcher = PlaysFetcher(client: client) - let rawPlays = try await fetcher.fetchRawPlays(league: league, gameId: game.id) - let cache = AthleteCache() - await fetcher.resolveAthletes(for: rawPlays, cache: cache) - let map = await cache.snapshot() - return Compactor.compactGame(league: league, game: game, rawPlays: rawPlays, athleteMap: map) - } - - public static func liveSession( - league: League, - game: Game, - cacheDirectory: URL, - pollInterval: TimeInterval = 10, - maxConsecutiveTransientFailures: Int = 10, - onTransientError: (@Sendable (Error) -> Void)? = nil, - session: URLSession = .shared - ) -> LiveSession { - LiveSession( - league: league, - game: game, - cacheDirectory: cacheDirectory, - pollInterval: pollInterval, - maxConsecutiveTransientFailures: maxConsecutiveTransientFailures, - onTransientError: onTransientError, - session: session - ) - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift b/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift deleted file mode 100644 index 9a593314..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift +++ /dev/null @@ -1,30 +0,0 @@ -import Foundation - -public enum PlayByPlayError: Error, Sendable { - case http(status: Int, url: URL) - case decoding(underlying: String, context: String) - case io(underlying: String) - case invalidAthleteRef(String) - case cancelled - - init(decoding error: Error, context: String) { - self = .decoding(underlying: String(describing: error), context: context) - } - - init(io error: Error) { - self = .io(underlying: String(describing: error)) - } -} - -extension PlayByPlayError: Equatable { - public static func == (lhs: PlayByPlayError, rhs: PlayByPlayError) -> Bool { - switch (lhs, rhs) { - case let (.http(a, b), .http(c, d)): return a == c && b == d - case let (.decoding(a, b), .decoding(c, d)): return a == c && b == d - case let (.io(a), .io(b)): return a == b - case let (.invalidAthleteRef(a), .invalidAthleteRef(b)): return a == b - case (.cancelled, .cancelled): return true - default: return false - } - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift b/PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift deleted file mode 100644 index f581a895..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift +++ /dev/null @@ -1,104 +0,0 @@ -import Foundation - -actor AthleteCache { - private var entries: [String: AthleteResponse] = [:] - - func get(_ url: String) -> AthleteResponse? { entries[url] } - - func set(_ url: String, _ value: AthleteResponse) { entries[url] = value } - - func has(_ url: String) -> Bool { entries[url] != nil } - - func snapshot() -> [String: AthleteResponse] { entries } - - func seed(_ athletes: [String: Athlete]) { - // Seed cache with already-known athletes so we don't refetch. - // Keyed by the original $ref URL, which we don't have here — - // so we key by athleteId URL shape that `extractId` recovers. - // Instead of reconstructing URLs, we just record the IDs as already-known; - // the fetcher filters its $ref list by ID when the map knows that ID. - for (id, a) in athletes { - // Use synthetic key "id:" so fetcher can check by ID. - entries["id:\(id)"] = AthleteResponse( - id: id, - displayName: a.name, - fullName: a.name, - jersey: a.jersey, - position: a.position.map { AthleteResponse.Position(abbreviation: $0, displayName: $0) } - ) - } - } - - func hasId(_ id: String) -> Bool { entries["id:\(id)"] != nil } - - func byId(_ id: String) -> AthleteResponse? { entries["id:\(id)"] } -} - -struct PlaysFetcher { - let client: ESPNClient - - init(client: ESPNClient = ESPNClient()) { - self.client = client - } - - func fetchRawPlays(league: League, gameId: String) async throws -> [RawPlay] { - let url = ESPNEndpoints.playByPlayURL(league, gameId: gameId) - let response: PlayByPlayResponse = try await client.fetchJSON(url) - return response.items ?? [] - } - - /// Resolve every athlete $ref into the cache. Concurrency bounded to `maxInFlight`. - func resolveAthletes(for plays: [RawPlay], cache: AthleteCache, maxInFlight: Int = 8) async { - var unique = Set() - for play in plays { - for p in play.participants ?? [] { - if let ref = p.athlete?.ref, !ref.isEmpty { - unique.insert(ref) - } - } - } - - var toFetch: [String] = [] - for ref in unique { - if await cache.has(ref) { continue } - if let id = ESPNRef.extractId(from: ref), await cache.hasId(id) { continue } - toFetch.append(ref) - } - - guard !toFetch.isEmpty else { return } - - await withTaskGroup(of: (String, AthleteResponse?).self) { group in - var index = 0 - var active = 0 - - func launchNext() { - guard index < toFetch.count else { return } - let ref = toFetch[index] - index += 1 - active += 1 - group.addTask { - guard let url = URL(string: ref) else { return (ref, nil) } - let response: AthleteResponse? = try? await self.client.fetchJSON(url) - return (ref, response) - } - } - - let initial = min(maxInFlight, toFetch.count) - for _ in 0.. [Game] { - (response.events ?? []).compactMap { event in - guard let comp = event.competitions.first, - let home = comp.competitors.first(where: { $0.homeAway == "home" }), - let away = comp.competitors.first(where: { $0.homeAway == "away" }) - else { return nil } - - return Game( - id: event.id, - name: event.name, - shortName: event.shortName, - status: comp.status.type.description, - statusDetail: comp.status.type.detail, - homeTeam: home.team.displayName, - awayTeam: away.team.displayName, - homeScore: home.score ?? "0", - awayScore: away.score ?? "0", - period: comp.status.type.detail, - homeTeamId: home.id, - awayTeamId: away.id, - homeTeamAbbr: home.team.abbreviation, - awayTeamAbbr: away.team.abbreviation - ) - } - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift b/PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift deleted file mode 100644 index 62e20bd3..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift +++ /dev/null @@ -1,46 +0,0 @@ -import Foundation - -enum SessionStorage { - static func cacheFileURL(root: URL, leagueKey: String, shortName: String, date: Date = Date()) -> URL { - let formatter = DateFormatter() - formatter.dateFormat = "yyyy-MM-dd" - formatter.timeZone = TimeZone(identifier: "UTC") - let dateStr = formatter.string(from: date) - let sanitized = shortName.replacingOccurrences(of: " ", with: "_") - let leagueDir = root.appendingPathComponent(leagueKey, isDirectory: true) - return leagueDir.appendingPathComponent("\(sanitized)_\(dateStr).json") - } - - static func read(_ url: URL) throws -> CompactGame? { - guard FileManager.default.fileExists(atPath: url.path) else { return nil } - do { - let data = try Data(contentsOf: url) - return try JSONDecoder().decode(CompactGame.self, from: data) - } catch { - throw PlayByPlayError(io: error) - } - } - - static func write(_ game: CompactGame, to url: URL) throws { - do { - try FileManager.default.createDirectory( - at: url.deletingLastPathComponent(), - withIntermediateDirectories: true - ) - let encoder = JSONEncoder() - encoder.outputFormatting = [.prettyPrinted, .sortedKeys] - let data = try encoder.encode(game) - - let tempURL = url.deletingLastPathComponent() - .appendingPathComponent(".\(url.lastPathComponent).tmp") - try data.write(to: tempURL, options: .atomic) - if FileManager.default.fileExists(atPath: url.path) { - _ = try FileManager.default.replaceItemAt(url, withItemAt: tempURL) - } else { - try FileManager.default.moveItem(at: tempURL, to: url) - } - } catch { - throw PlayByPlayError(io: error) - } - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift b/PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift deleted file mode 100644 index 94899f8a..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift +++ /dev/null @@ -1,106 +0,0 @@ -import Foundation - -/// Sentinel values ESPN uses to indicate "no court position" on basketball plays. -private let basketballSentinelX: Double = -214748340 -private let basketballSentinelY: Double = -214748365 - -enum SportCleaners { - static func cleanBaseball(_ raw: RawPlay) -> BaseballFields { - var f = BaseballFields() - if let c = raw.pitchCoordinate { f.pitchCoordinate = Coordinate(x: c.x, y: c.y) } - if let t = raw.pitchType?.text { f.pitchType = t } - f.pitchVelocity = raw.pitchVelocity - if let c = raw.hitCoordinate { f.hitCoordinate = Coordinate(x: c.x, y: c.y) } - f.trajectory = raw.trajectory - f.atBatId = raw.atBatId - f.batOrder = raw.batOrder - f.atBatPitchNumber = raw.atBatPitchNumber - f.bats = raw.bats?.abbreviation - f.pitches = raw.pitches?.abbreviation - if let pc = raw.pitchCount { - f.pitchCount = PitchCount(balls: pc.balls, strikes: pc.strikes) - } - f.outs = raw.outs - f.rbiCount = raw.rbiCount - f.awayHits = raw.awayHits - f.homeHits = raw.homeHits - f.awayErrors = raw.awayErrors - f.homeErrors = raw.homeErrors - f.doublePlay = raw.doublePlay - f.triplePlay = raw.triplePlay - f.summaryType = raw.summaryType - return f - } - - static func cleanBasketball(_ raw: RawPlay) -> BasketballFields { - var f = BasketballFields() - if let c = raw.coordinate, c.x != basketballSentinelX, c.y != basketballSentinelY { - f.coordinate = Coordinate(x: c.x, y: c.y) - } - f.pointsAttempted = raw.pointsAttempted - f.shootingPlay = raw.shootingPlay - return f - } - - static func cleanFootball(_ raw: RawPlay) -> FootballFields { - var f = FootballFields() - f.start = driveMarker(raw.start) - f.end = driveMarker(raw.end) - f.statYardage = raw.statYardage - f.isTurnover = raw.isTurnover - if let tps = raw.teamParticipants, !tps.isEmpty { - f.teamParticipants = tps.map { tp in - TeamParticipant( - teamId: tp.id ?? ESPNRef.extractId(from: tp.team?.ref), - order: tp.order, - type: tp.type - ) - } - } - return f - } - - static func cleanHockey(_ raw: RawPlay) -> HockeyFields { - var f = HockeyFields() - f.strength = raw.strength?.text - f.isPenalty = raw.isPenalty - f.shootingPlay = raw.shootingPlay - return f - } - - static func cleanSoccer(_ raw: RawPlay) -> SoccerFields { - var f = SoccerFields() - f.redCard = raw.redCard - f.yellowCard = raw.yellowCard - f.penaltyKick = raw.penaltyKick - f.ownGoal = raw.ownGoal - f.shootout = raw.shootout - f.substitution = raw.substitution - f.addedClock = raw.addedClock?.value - if raw.fieldPositionX != nil || raw.fieldPositionY != nil { - f.fieldPosition = FieldPosition(x: raw.fieldPositionX, y: raw.fieldPositionY) - } - if raw.fieldPosition2X != nil || raw.fieldPosition2Y != nil { - f.fieldPosition2 = FieldPosition(x: raw.fieldPosition2X, y: raw.fieldPosition2Y) - } - if raw.goalPositionX != nil || raw.goalPositionY != nil || raw.goalPositionZ != nil { - f.goalPosition = GoalPosition(x: raw.goalPositionX, y: raw.goalPositionY, z: raw.goalPositionZ) - } - return f - } - - private static func driveMarker(_ m: RawDriveMarker?) -> DriveMarker? { - guard let m else { return nil } - let hasAny = m.down != nil || m.distance != nil || m.yardLine != nil || m.yardsToEndzone != nil || m.shortDownDistanceText != nil || m.possessionText != nil || m.team != nil - guard hasAny else { return nil } - return DriveMarker( - down: m.down, - distance: m.distance, - yardLine: m.yardLine, - yardsToEndzone: m.yardsToEndzone, - downDistance: m.shortDownDistanceText, - possession: m.possessionText, - teamId: ESPNRef.extractId(from: m.team?.ref) - ) - } -} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift b/PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift deleted file mode 100644 index 8e0b31fa..00000000 --- a/PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift +++ /dev/null @@ -1,116 +0,0 @@ -import Foundation - -public struct BaseballFields: Hashable, Sendable, Codable { - public var pitchCoordinate: Coordinate? - public var pitchType: String? - public var pitchVelocity: Double? - public var hitCoordinate: Coordinate? - public var trajectory: String? - public var atBatId: String? - public var batOrder: Int? - public var atBatPitchNumber: Int? - public var bats: String? - public var pitches: String? - public var pitchCount: PitchCount? - public var outs: Int? - public var rbiCount: Int? - public var awayHits: Int? - public var homeHits: Int? - public var awayErrors: Int? - public var homeErrors: Int? - public var doublePlay: Bool? - public var triplePlay: Bool? - public var summaryType: String? -} - -public struct BasketballFields: Hashable, Sendable, Codable { - public var coordinate: Coordinate? - public var pointsAttempted: Int? - public var shootingPlay: Bool? -} - -public struct FootballFields: Hashable, Sendable, Codable { - public var start: DriveMarker? - public var end: DriveMarker? - public var statYardage: Int? - public var isTurnover: Bool? - public var teamParticipants: [TeamParticipant]? -} - -public struct HockeyFields: Hashable, Sendable, Codable { - public var strength: String? - public var isPenalty: Bool? - public var shootingPlay: Bool? -} - -public struct SoccerFields: Hashable, Sendable, Codable { - public var redCard: Bool? - public var yellowCard: Bool? - public var penaltyKick: Bool? - public var ownGoal: Bool? - public var shootout: Bool? - public var substitution: Bool? - public var addedClock: Double? - public var fieldPosition: FieldPosition? - public var fieldPosition2: FieldPosition? - public var goalPosition: GoalPosition? -} - -public enum SportFields: Hashable, Sendable { - case baseball(BaseballFields) - case basketball(BasketballFields) - case football(FootballFields) - case hockey(HockeyFields) - case soccer(SoccerFields) -} - -extension SportFields: Codable { - private enum CodingKeys: String, CodingKey { - case sport - case data - } - - public func encode(to encoder: Encoder) throws { - var c = encoder.container(keyedBy: CodingKeys.self) - switch self { - case .baseball(let v): - try c.encode("baseball", forKey: .sport) - try c.encode(v, forKey: .data) - case .basketball(let v): - try c.encode("basketball", forKey: .sport) - try c.encode(v, forKey: .data) - case .football(let v): - try c.encode("football", forKey: .sport) - try c.encode(v, forKey: .data) - case .hockey(let v): - try c.encode("hockey", forKey: .sport) - try c.encode(v, forKey: .data) - case .soccer(let v): - try c.encode("soccer", forKey: .sport) - try c.encode(v, forKey: .data) - } - } - - public init(from decoder: Decoder) throws { - let c = try decoder.container(keyedBy: CodingKeys.self) - let sport = try c.decode(String.self, forKey: .sport) - switch sport { - case "baseball": - self = .baseball(try c.decode(BaseballFields.self, forKey: .data)) - case "basketball": - self = .basketball(try c.decode(BasketballFields.self, forKey: .data)) - case "football": - self = .football(try c.decode(FootballFields.self, forKey: .data)) - case "hockey": - self = .hockey(try c.decode(HockeyFields.self, forKey: .data)) - case "soccer": - self = .soccer(try c.decode(SoccerFields.self, forKey: .data)) - default: - throw DecodingError.dataCorruptedError( - forKey: .sport, - in: c, - debugDescription: "Unknown sport: \(sport)" - ) - } - } -} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift deleted file mode 100644 index 248de647..00000000 --- a/PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift +++ /dev/null @@ -1,152 +0,0 @@ -import XCTest -@testable import PlayByPlayKit - -final class CompactorTests: XCTestCase { - private func sampleGame() -> Game { - Game( - id: "g1", name: "A at B", shortName: "A @ B", - status: "In Progress", statusDetail: "Top 5th", - homeTeam: "B", awayTeam: "A", - homeScore: "2", awayScore: "1", - period: "Top 5th", - homeTeamId: "100", awayTeamId: "200", - homeTeamAbbr: "B", awayTeamAbbr: "A" - ) - } - - private let mlb = League(key: "mlb", sport: "baseball", league: "mlb", displayName: "MLB") - - private func rawPlays(_ json: String) throws -> [RawPlay] { - let data = json.data(using: .utf8)! - return try JSONDecoder().decode([RawPlay].self, from: data) - } - - func testCompactGroupsByPeriodInOrder() throws { - let plays = try rawPlays(""" - [ - {"id":"1","period":{"number":1,"type":"Top","displayValue":"Top 1st"}}, - {"id":"2","period":{"number":1,"type":"Bot","displayValue":"Bot 1st"}}, - {"id":"3","period":{"number":2,"type":"Top","displayValue":"Top 2nd"}}, - {"id":"4","period":{"number":2,"type":"Top","displayValue":"Top 2nd"}} - ] - """) - - let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) - - XCTAssertEqual(compact.totalPlays, 4) - XCTAssertEqual(compact.periods.count, 3) - XCTAssertEqual(compact.periods[0].plays.map { $0.id }, ["1"]) - XCTAssertEqual(compact.periods[1].plays.map { $0.id }, ["2"]) - XCTAssertEqual(compact.periods[2].plays.map { $0.id }, ["3", "4"]) - } - - func testCompactPopulatesTeams() throws { - let plays = try rawPlays("[]") - let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) - XCTAssertEqual(compact.teams["100"]?.name, "B") - XCTAssertEqual(compact.teams["200"]?.name, "A") - XCTAssertEqual(compact.teams["100"]?.abbreviation, "B") - } - - func testCompactPopulatesAthletesFromMap() throws { - let plays = try rawPlays(""" - [{"id":"1","participants":[{"athlete":{"$ref":"https://example.com/athletes/5?x=y"},"type":"batter"}]}] - """) - - let map: [String: AthleteResponse] = [ - "https://example.com/athletes/5?x=y": AthleteResponse( - id: "5", - displayName: "Jane Doe", - fullName: "Jane A Doe", - jersey: "42", - position: AthleteResponse.Position(abbreviation: "SS", displayName: "Shortstop") - ) - ] - - let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: map) - XCTAssertEqual(compact.athletes["5"]?.name, "Jane Doe") - XCTAssertEqual(compact.athletes["5"]?.jersey, "42") - XCTAssertEqual(compact.athletes["5"]?.position, "SS") - XCTAssertEqual(compact.periods.first?.plays.first?.participants?.first?.athleteId, "5") - } - - func testLastCompactPlayIdWalksBackward() throws { - let plays = try rawPlays(""" - [ - {"id":"1","period":{"number":1,"type":"Top"}}, - {"id":"2","period":{"number":2,"type":"Top"}} - ] - """) - let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) - XCTAssertEqual(Compactor.lastCompactPlayId(compact), "2") - XCTAssertNil(Compactor.lastCompactPlayId(nil)) - } - - func testDiffNewPlaysReturnsAllWhenNoPrev() throws { - let plays = try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"}]") - let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) - let delta = Compactor.diffNewPlays(prev: nil, next: compact) - XCTAssertEqual(delta.map { $0.id }, ["1", "2"]) - } - - func testDiffNewPlaysFiltersBeforeLastId() throws { - let prev = Compactor.compactGame( - league: mlb, game: sampleGame(), - rawPlays: try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"}]"), - athleteMap: [:] - ) - let next = Compactor.compactGame( - league: mlb, game: sampleGame(), - rawPlays: try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"},{\"id\":\"3\"},{\"id\":\"4\"}]"), - athleteMap: [:] - ) - let delta = Compactor.diffNewPlays(prev: prev, next: next) - XCTAssertEqual(delta.map { $0.id }, ["3", "4"]) - } - - func testDiffNewPlaysReturnsAllWhenLastIdMissing() throws { - let prev = Compactor.compactGame( - league: mlb, game: sampleGame(), - rawPlays: try rawPlays("[{\"id\":\"X\"}]"), - athleteMap: [:] - ) - let next = Compactor.compactGame( - league: mlb, game: sampleGame(), - rawPlays: try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"}]"), - athleteMap: [:] - ) - let delta = Compactor.diffNewPlays(prev: prev, next: next) - XCTAssertEqual(delta.map { $0.id }, ["1", "2"]) - } - - func testSportFieldsEnumDispatchesCorrectly() throws { - let nba = League(key: "nba", sport: "basketball", league: "nba", displayName: "NBA") - let plays = try rawPlays("[{\"id\":\"1\",\"coordinate\":{\"x\":5,\"y\":5},\"pointsAttempted\":3}]") - let compact = Compactor.compactGame(league: nba, game: sampleGame(), rawPlays: plays, athleteMap: [:]) - let first = compact.periods.first?.plays.first - if case let .basketball(f) = first?.sportFields { - XCTAssertEqual(f.coordinate?.x, 5) - XCTAssertEqual(f.pointsAttempted, 3) - } else { - XCTFail("expected basketball sport fields") - } - } - - func testSportFieldsEnumRoundTrip() throws { - let nfl = League(key: "nfl", sport: "football", league: "nfl", displayName: "NFL") - let plays = try rawPlays("[{\"id\":\"1\",\"start\":{\"down\":1,\"distance\":10}}]") - let compact = Compactor.compactGame(league: nfl, game: sampleGame(), rawPlays: plays, athleteMap: [:]) - - let encoder = JSONEncoder() - encoder.outputFormatting = [.sortedKeys] - let data = try encoder.encode(compact) - let decoded = try JSONDecoder().decode(CompactGame.self, from: data) - - if case let .football(f) = decoded.periods.first?.plays.first?.sportFields { - XCTAssertEqual(f.start?.down, 1) - XCTAssertEqual(f.start?.distance, 10) - } else { - XCTFail("expected football on round-trip") - } - } -} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift deleted file mode 100644 index 868e0828..00000000 --- a/PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift +++ /dev/null @@ -1,38 +0,0 @@ -import XCTest -@testable import PlayByPlayKit - -final class LeagueTests: XCTestCase { - func testAllLeaguesCount() { - XCTAssertEqual(League.all.count, 15) - } - - func testMLBLeague() { - let mlb = League.all.first { $0.key == "mlb" } - XCTAssertNotNil(mlb) - XCTAssertEqual(mlb?.sport, "baseball") - XCTAssertEqual(mlb?.league, "mlb") - } - - func testScoreboardURL() { - let mlb = League.all.first { $0.key == "mlb" }! - XCTAssertEqual( - ESPNEndpoints.scoreboardURL(mlb).absoluteString, - "https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/scoreboard" - ) - } - - func testPlayByPlayURL() { - let epl = League.all.first { $0.key == "epl" }! - XCTAssertEqual( - ESPNEndpoints.playByPlayURL(epl, gameId: "12345").absoluteString, - "https://sports.core.api.espn.com/v2/sports/soccer/leagues/eng.1/events/12345/competitions/12345/plays?limit=1000" - ) - } - - func testExtractIdFromRef() { - XCTAssertEqual(ESPNRef.extractId(from: "https://example.com/v2/sports/x/athletes/33333?lang=en"), "33333") - XCTAssertEqual(ESPNRef.extractId(from: "/teams/17"), "17") - XCTAssertNil(ESPNRef.extractId(from: nil)) - XCTAssertNil(ESPNRef.extractId(from: "no-match-here")) - } -} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift deleted file mode 100644 index 4f7809ea..00000000 --- a/PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift +++ /dev/null @@ -1,197 +0,0 @@ -import XCTest -@testable import PlayByPlayKit - -final class LiveSessionTests: XCTestCase { - private let mlb = League(key: "mlb", sport: "baseball", league: "mlb", displayName: "MLB") - - private func sampleGame() -> Game { - Game( - id: "401", - name: "A at B", shortName: "A @ B", - status: "In Progress", statusDetail: "Top 5th", - homeTeam: "B", awayTeam: "A", - homeScore: "0", awayScore: "0", - period: "Top 5th", - homeTeamId: "100", awayTeamId: "200", - homeTeamAbbr: "B", awayTeamAbbr: "A" - ) - } - - private func tempDir() -> URL { - let url = FileManager.default.temporaryDirectory - .appendingPathComponent("PlayByPlayKitTests-\(UUID().uuidString)", isDirectory: true) - try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true) - return url - } - - override func setUp() { - MockURLProtocol.reset() - } - - override func tearDown() { - MockURLProtocol.reset() - } - - private func playsResponse(_ ids: [String]) -> Data { - let items = ids.map { #"{"id":"\#($0)"}"# }.joined(separator: ",") - let json = #"{"items":[\#(items)]}"# - return json.data(using: .utf8)! - } - - func testColdStartEmitsInitialDelta() async throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - MockURLProtocol.handler = { url in - .init(statusCode: 200, body: self.playsResponse(["1", "2"])) - } - - let session = PlayByPlay.liveSession( - league: mlb, game: sampleGame(), - cacheDirectory: dir, - pollInterval: 3600, - session: MockURLProtocol.session() - ) - - let stream = await session.deltas - await session.start() - - var iter = stream.makeAsyncIterator() - let delta = try await iter.next() - XCTAssertNotNil(delta) - XCTAssertEqual(delta?.newPlays.map { $0.id }, ["1", "2"]) - XCTAssertEqual(delta?.state.totalPlays, 2) - - await session.stop() - } - - func testResumeSuppressesUnchangedPollThenEmitsNew() async throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - - var callCount = 0 - MockURLProtocol.handler = { url in - MockURLProtocol.lock.lock() - callCount += 1 - let c = callCount - MockURLProtocol.lock.unlock() - if c == 1 { - return .init(statusCode: 200, body: self.playsResponse(["1", "2"])) - } else { - return .init(statusCode: 200, body: self.playsResponse(["1", "2", "3"])) - } - } - - let session = PlayByPlay.liveSession( - league: mlb, game: sampleGame(), - cacheDirectory: dir, - pollInterval: 0.05, - session: MockURLProtocol.session() - ) - - let stream = await session.deltas - await session.start() - - var iter = stream.makeAsyncIterator() - - let first = try await iter.next() - XCTAssertEqual(first?.newPlays.map { $0.id }, ["1", "2"]) - - let second = try await iter.next() - XCTAssertEqual(second?.newPlays.map { $0.id }, ["3"]) - XCTAssertEqual(second?.state.totalPlays, 3) - - await session.stop() - } - - func testPermanentErrorThrowsIntoStream() async throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - - MockURLProtocol.handler = { _ in .init(statusCode: 404, body: Data()) } - - let session = PlayByPlay.liveSession( - league: mlb, game: sampleGame(), - cacheDirectory: dir, - pollInterval: 0.05, - session: MockURLProtocol.session() - ) - let stream = await session.deltas - await session.start() - - var iter = stream.makeAsyncIterator() - do { - _ = try await iter.next() - XCTFail("expected error") - } catch let error as PlayByPlayError { - if case .http(let status, _) = error { - XCTAssertEqual(status, 404) - } else { - XCTFail("expected .http(404)") - } - } - await session.stop() - } - - func testTransientErrorRetries() async throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - - var callCount = 0 - MockURLProtocol.handler = { _ in - MockURLProtocol.lock.lock() - callCount += 1 - let c = callCount - MockURLProtocol.lock.unlock() - if c == 1 { - return .init(statusCode: 503, body: Data()) - } - let json = #"{"items":[{"id":"1"}]}"# - return .init(statusCode: 200, body: json.data(using: .utf8)!) - } - - var transientCount = 0 - let lock = NSLock() - - let session = PlayByPlay.liveSession( - league: mlb, game: sampleGame(), - cacheDirectory: dir, - pollInterval: 0.05, - onTransientError: { _ in - lock.lock() - transientCount += 1 - lock.unlock() - }, - session: MockURLProtocol.session() - ) - let stream = await session.deltas - await session.start() - var iter = stream.makeAsyncIterator() - let delta = try await iter.next() - XCTAssertEqual(delta?.newPlays.map { $0.id }, ["1"]) - lock.lock() - XCTAssertEqual(transientCount, 1) - lock.unlock() - await session.stop() - } - - func testStopEndsStreamCleanly() async throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - MockURLProtocol.handler = { _ in - .init(statusCode: 200, body: self.playsResponse(["1"])) - } - let session = PlayByPlay.liveSession( - league: mlb, game: sampleGame(), - cacheDirectory: dir, - pollInterval: 3600, - session: MockURLProtocol.session() - ) - let stream = await session.deltas - await session.start() - var iter = stream.makeAsyncIterator() - _ = try await iter.next() - await session.stop() - let final = try await iter.next() - XCTAssertNil(final, "stream should terminate after stop()") - } -} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift deleted file mode 100644 index 9182c6dd..00000000 --- a/PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift +++ /dev/null @@ -1,56 +0,0 @@ -import Foundation - -final class MockURLProtocol: URLProtocol, @unchecked Sendable { - struct Response { - let statusCode: Int - let body: Data - } - - static let lock = NSLock() - nonisolated(unsafe) static var handler: (@Sendable (URL) -> Response)? - nonisolated(unsafe) static var requestLog: [URL] = [] - - override class func canInit(with request: URLRequest) -> Bool { true } - override class func canonicalRequest(for request: URLRequest) -> URLRequest { request } - - override func startLoading() { - guard let url = request.url else { - client?.urlProtocol(self, didFailWithError: URLError(.badURL)) - return - } - MockURLProtocol.lock.lock() - MockURLProtocol.requestLog.append(url) - let handler = MockURLProtocol.handler - MockURLProtocol.lock.unlock() - - guard let handler else { - client?.urlProtocol(self, didFailWithError: URLError(.notConnectedToInternet)) - return - } - let response = handler(url) - let http = HTTPURLResponse( - url: url, - statusCode: response.statusCode, - httpVersion: "HTTP/1.1", - headerFields: ["Content-Type": "application/json"] - )! - client?.urlProtocol(self, didReceive: http, cacheStoragePolicy: .notAllowed) - client?.urlProtocol(self, didLoad: response.body) - client?.urlProtocolDidFinishLoading(self) - } - - override func stopLoading() {} - - static func reset() { - lock.lock() - defer { lock.unlock() } - handler = nil - requestLog = [] - } - - static func session() -> URLSession { - let config = URLSessionConfiguration.ephemeral - config.protocolClasses = [MockURLProtocol.self] - return URLSession(configuration: config) - } -} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift deleted file mode 100644 index ef480273..00000000 --- a/PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift +++ /dev/null @@ -1,60 +0,0 @@ -import XCTest -@testable import PlayByPlayKit - -final class ScoreboardTests: XCTestCase { - func testDecodeAndToGames() throws { - let json = """ - { - "events": [ - { - "id": "401570000", - "name": "New York Yankees at Boston Red Sox", - "shortName": "NYY @ BOS", - "competitions": [ - { - "competitors": [ - { - "id": "10", - "homeAway": "home", - "score": "3", - "team": { "displayName": "Boston Red Sox", "abbreviation": "BOS" } - }, - { - "id": "9", - "homeAway": "away", - "score": "2", - "team": { "displayName": "New York Yankees", "abbreviation": "NYY" } - } - ], - "status": { - "type": { "description": "In Progress", "detail": "Top 7th" } - } - } - ] - } - ] - } - """.data(using: .utf8)! - - let response = try JSONDecoder().decode(ScoreboardResponse.self, from: json) - let games = Scoreboard.toGames(response) - XCTAssertEqual(games.count, 1) - let g = games[0] - XCTAssertEqual(g.id, "401570000") - XCTAssertEqual(g.homeTeam, "Boston Red Sox") - XCTAssertEqual(g.awayTeam, "New York Yankees") - XCTAssertEqual(g.homeScore, "3") - XCTAssertEqual(g.awayScore, "2") - XCTAssertEqual(g.homeTeamId, "10") - XCTAssertEqual(g.awayTeamId, "9") - XCTAssertEqual(g.homeTeamAbbr, "BOS") - XCTAssertEqual(g.status, "In Progress") - XCTAssertEqual(g.statusDetail, "Top 7th") - } - - func testEmptyScoreboard() throws { - let json = #"{"events":[]}"#.data(using: .utf8)! - let response = try JSONDecoder().decode(ScoreboardResponse.self, from: json) - XCTAssertEqual(Scoreboard.toGames(response).count, 0) - } -} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift deleted file mode 100644 index 0364ab36..00000000 --- a/PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift +++ /dev/null @@ -1,95 +0,0 @@ -import XCTest -@testable import PlayByPlayKit - -final class SessionStorageTests: XCTestCase { - private func tempDir() -> URL { - let url = FileManager.default.temporaryDirectory - .appendingPathComponent("PlayByPlayKitTests-\(UUID().uuidString)", isDirectory: true) - try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true) - return url - } - - private func makeCompact() -> CompactGame { - CompactGame( - league: LeagueRef(key: "mlb", sport: "baseball", league: "mlb"), - game: GameSummary( - id: "g1", name: "A at B", shortName: "A @ B", - status: "In Progress", statusDetail: "Top 5th", - awayTeam: "A", homeTeam: "B", awayScore: "1", homeScore: "2" - ), - totalPlays: 2, - athletes: ["5": Athlete(name: "Jane Doe", jersey: "42", position: "SS")], - teams: ["100": TeamRef(name: "B", abbreviation: "B")], - periods: [ - CompactPeriod( - number: 1, - type: "Top", - displayValue: "Top 1st", - plays: [ - CompactPlay(id: "p1"), - CompactPlay(id: "p2") - ] - ) - ] - ) - } - - func testCacheFileURLFormat() { - let root = URL(fileURLWithPath: "/tmp/root") - let date = ISO8601DateFormatter().date(from: "2026-04-19T10:00:00Z")! - let url = SessionStorage.cacheFileURL( - root: root, - leagueKey: "mlb", - shortName: "NYY @ BOS", - date: date - ) - XCTAssertEqual(url.path, "/tmp/root/mlb/NYY_@_BOS_2026-04-19.json") - } - - func testWriteReadRoundTrip() throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - - let compact = makeCompact() - let url = dir.appendingPathComponent("test.json") - try SessionStorage.write(compact, to: url) - - let loaded = try SessionStorage.read(url) - XCTAssertEqual(loaded, compact) - } - - func testReadReturnsNilWhenFileMissing() throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - let url = dir.appendingPathComponent("missing.json") - XCTAssertNil(try SessionStorage.read(url)) - } - - func testWriteCreatesIntermediateDirectories() throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - let url = dir.appendingPathComponent("mlb").appendingPathComponent("game.json") - try SessionStorage.write(makeCompact(), to: url) - XCTAssertTrue(FileManager.default.fileExists(atPath: url.path)) - } - - func testWriteOverwritesExistingFile() throws { - let dir = tempDir() - defer { try? FileManager.default.removeItem(at: dir) } - let url = dir.appendingPathComponent("game.json") - try SessionStorage.write(makeCompact(), to: url) - try SessionStorage.write(makeCompact(), to: url) // second write should succeed - XCTAssertNotNil(try SessionStorage.read(url)) - } -} - -extension CompactPlay { - init(id: String) { - self.init( - id: id, seq: nil, type: nil, text: nil, - awayScore: nil, homeScore: nil, clock: nil, - scoringPlay: nil, scoreValue: nil, wallclock: nil, - teamId: nil, participants: nil, period: nil, sportFields: nil - ) - } -} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift deleted file mode 100644 index c047f060..00000000 --- a/PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift +++ /dev/null @@ -1,125 +0,0 @@ -import XCTest -@testable import PlayByPlayKit - -final class SportCleanerTests: XCTestCase { - func testBaseballCleanerPassesThroughFields() throws { - let json = """ - { - "id": "p1", - "pitchCoordinate": {"x": 1.0, "y": 2.0}, - "pitchType": {"text": "Fastball"}, - "pitchVelocity": 95.5, - "bats": {"abbreviation": "L"}, - "pitchCount": {"balls": 2, "strikes": 1}, - "outs": 1, - "doublePlay": true, - "homeHits": 5 - } - """.data(using: .utf8)! - let raw = try JSONDecoder().decode(RawPlay.self, from: json) - let f = SportCleaners.cleanBaseball(raw) - XCTAssertEqual(f.pitchCoordinate?.x, 1.0) - XCTAssertEqual(f.pitchType, "Fastball") - XCTAssertEqual(f.pitchVelocity, 95.5) - XCTAssertEqual(f.bats, "L") - XCTAssertEqual(f.pitchCount?.balls, 2) - XCTAssertEqual(f.pitchCount?.strikes, 1) - XCTAssertEqual(f.outs, 1) - XCTAssertEqual(f.doublePlay, true) - XCTAssertEqual(f.homeHits, 5) - } - - func testBasketballCleanerDropsSentinel() throws { - let json = """ - { - "id": "p2", - "coordinate": {"x": -214748340, "y": -214748365}, - "pointsAttempted": 3, - "shootingPlay": true - } - """.data(using: .utf8)! - let raw = try JSONDecoder().decode(RawPlay.self, from: json) - let f = SportCleaners.cleanBasketball(raw) - XCTAssertNil(f.coordinate, "sentinel coordinate must be dropped") - XCTAssertEqual(f.pointsAttempted, 3) - XCTAssertEqual(f.shootingPlay, true) - } - - func testBasketballCleanerKeepsRealCoordinate() throws { - let json = """ - {"id":"p3","coordinate":{"x":12.5,"y":-7.3}} - """.data(using: .utf8)! - let raw = try JSONDecoder().decode(RawPlay.self, from: json) - let f = SportCleaners.cleanBasketball(raw) - XCTAssertEqual(f.coordinate?.x, 12.5) - XCTAssertEqual(f.coordinate?.y, -7.3) - } - - func testFootballCleanerBuildsDriveMarkers() throws { - let json = """ - { - "id": "p4", - "start": { - "down": 3, - "distance": 7, - "yardLine": 45, - "yardsToEndzone": 55, - "team": {"$ref": "https://example.com/teams/17?lang=en"} - }, - "end": { - "down": 4, - "distance": 1, - "shortDownDistanceText": "4th & 1", - "possessionText": "NE 46" - }, - "statYardage": 6, - "teamParticipants": [ - {"id": "17", "order": 1, "type": "offense"} - ] - } - """.data(using: .utf8)! - let raw = try JSONDecoder().decode(RawPlay.self, from: json) - let f = SportCleaners.cleanFootball(raw) - XCTAssertEqual(f.start?.down, 3) - XCTAssertEqual(f.start?.distance, 7) - XCTAssertEqual(f.start?.teamId, "17") - XCTAssertEqual(f.end?.downDistance, "4th & 1") - XCTAssertEqual(f.end?.possession, "NE 46") - XCTAssertEqual(f.statYardage, 6) - XCTAssertEqual(f.teamParticipants?.first?.teamId, "17") - XCTAssertEqual(f.teamParticipants?.first?.order, 1) - } - - func testHockeyCleaner() throws { - let json = """ - {"id":"p5","strength":{"text":"Power Play"},"isPenalty":true,"shootingPlay":true} - """.data(using: .utf8)! - let raw = try JSONDecoder().decode(RawPlay.self, from: json) - let f = SportCleaners.cleanHockey(raw) - XCTAssertEqual(f.strength, "Power Play") - XCTAssertEqual(f.isPenalty, true) - XCTAssertEqual(f.shootingPlay, true) - } - - func testSoccerCleaner() throws { - let json = """ - { - "id": "p6", - "redCard": true, - "addedClock": {"value": 5.0}, - "fieldPositionX": 12.3, - "fieldPositionY": 45.6, - "goalPositionX": 1.0, - "goalPositionY": 2.0, - "goalPositionZ": 3.0 - } - """.data(using: .utf8)! - let raw = try JSONDecoder().decode(RawPlay.self, from: json) - let f = SportCleaners.cleanSoccer(raw) - XCTAssertEqual(f.redCard, true) - XCTAssertEqual(f.addedClock, 5.0) - XCTAssertEqual(f.fieldPosition?.x, 12.3) - XCTAssertEqual(f.fieldPosition?.y, 45.6) - XCTAssertEqual(f.goalPosition?.z, 3.0) - } -} diff --git a/project.yml b/project.yml index a1cc7b27..2497a323 100644 --- a/project.yml +++ b/project.yml @@ -6,10 +6,6 @@ options: createIntermediateGroups: true generateEmptyDirectories: true -packages: - PlayByPlayKit: - path: PlayByPlayKit - settings: base: SWIFT_VERSION: "5.9" @@ -61,8 +57,6 @@ targets: embed: true codeSign: true optional: true - - package: PlayByPlayKit - product: PlayByPlayKit BroadcastBrainTests: type: bundle.unit-test From aa4e83c0d0d0c0a6129bfcb6debccf4f82b6581c Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:05:21 -0700 Subject: [PATCH 06/18] fix: restore PlayByPlayKit + Plays/PlaysDB surfaces (vital infra dropped in merge) --- BroadcastBrain.xcodeproj/project.pbxproj | 46 ++ BroadcastBrain/BroadcastBrainApp.swift | 6 +- BroadcastBrain/ContentView.swift | 2 + BroadcastBrain/Stores/AppStore.swift | 6 +- BroadcastBrain/Stores/PlayByPlayStore.swift | 168 +++++++ BroadcastBrain/Views/PlaysDBView.swift | 362 ++++++++++++++ BroadcastBrain/Views/PlaysSearchView.swift | 446 ++++++++++++++++++ BroadcastBrain/Views/PlaysStreamView.swift | 149 ++++++ BroadcastBrain/Views/SidebarView.swift | 2 + PlayByPlayKit/.gitignore | 6 + PlayByPlayKit/Package.swift | 17 + .../PlayByPlayKit/AthleteResponse.swift | 14 + .../Sources/PlayByPlayKit/Compactor.swift | 146 ++++++ .../Sources/PlayByPlayKit/ESPNClient.swift | 29 ++ .../Sources/PlayByPlayKit/Helpers.swift | 59 +++ .../Sources/PlayByPlayKit/League.swift | 45 ++ .../Sources/PlayByPlayKit/LiveSession.swift | 153 ++++++ .../Sources/PlayByPlayKit/Models.swift | 97 ++++ .../Sources/PlayByPlayKit/PlayByPlay.swift | 41 ++ .../PlayByPlayKit/PlayByPlayError.swift | 30 ++ .../Sources/PlayByPlayKit/PlaysFetcher.swift | 104 ++++ .../Sources/PlayByPlayKit/RawPlay.swift | 146 ++++++ .../Sources/PlayByPlayKit/Scoreboard.swift | 66 +++ .../PlayByPlayKit/SessionStorage.swift | 46 ++ .../Sources/PlayByPlayKit/SportCleaners.swift | 106 +++++ .../Sources/PlayByPlayKit/SportFields.swift | 116 +++++ .../PlayByPlayKitTests/CompactorTests.swift | 152 ++++++ .../PlayByPlayKitTests/LeagueTests.swift | 38 ++ .../PlayByPlayKitTests/LiveSessionTests.swift | 197 ++++++++ .../PlayByPlayKitTests/MockURLProtocol.swift | 56 +++ .../PlayByPlayKitTests/ScoreboardTests.swift | 60 +++ .../SessionStorageTests.swift | 95 ++++ .../SportCleanerTests.swift | 125 +++++ project.yml | 6 + 34 files changed, 3134 insertions(+), 3 deletions(-) create mode 100644 BroadcastBrain/Stores/PlayByPlayStore.swift create mode 100644 BroadcastBrain/Views/PlaysDBView.swift create mode 100644 BroadcastBrain/Views/PlaysSearchView.swift create mode 100644 BroadcastBrain/Views/PlaysStreamView.swift create mode 100644 PlayByPlayKit/.gitignore create mode 100644 PlayByPlayKit/Package.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/League.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Models.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/RawPlay.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/Scoreboard.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift create mode 100644 PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift create mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift create mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift create mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift create mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift create mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift create mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift create mode 100644 PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift diff --git a/BroadcastBrain.xcodeproj/project.pbxproj b/BroadcastBrain.xcodeproj/project.pbxproj index e943bbd9..42af6ba0 100644 --- a/BroadcastBrain.xcodeproj/project.pbxproj +++ b/BroadcastBrain.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 034498E25A8850984493C9E2 /* SessionStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD1186F00AC31EE683675AE6 /* SessionStoreTests.swift */; }; 053617CC8A80BFBB884CF402 /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */; }; 06A1F33ECBAF18586AC02A37 /* NewsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA68D7CA900438A10D7B4AC9 /* NewsService.swift */; }; + 0CC48F247E683B3FB185A6FB /* PlayByPlayStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 846A697EC3777956030AC4C3 /* PlayByPlayStore.swift */; }; 0F02EBD664051BF052EF7012 /* ModelCodableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2491DE25F4F75DA94526903 /* ModelCodableTests.swift */; }; 162B595396D5974D448E5A8C /* AppStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5C2E3CFAB5CA8C1AD68FB5B /* AppStore.swift */; }; 164F7E394D28280CBD14A11D /* StackCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10B521A0B659765D883F5E4C /* StackCard.swift */; }; @@ -23,6 +24,7 @@ 45CB73E5789C135680D10F96 /* FlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9C5C443A7D8D3D41E5B0E13 /* FlowLayout.swift */; }; 4888A82003BDA03F00D954CD /* LivePill.swift in Sources */ = {isa = PBXBuildFile; fileRef = B79E4BA0F9248D3466873BBE /* LivePill.swift */; }; 4DD529CF07EB0CCAB762BEAF /* NewsTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE805D3AE864A2EC89074CF1 /* NewsTabView.swift */; }; + 5874FC398254108334E944D0 /* PlaysSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 721C2BA2DE9BCD5F29F526F0 /* PlaysSearchView.swift */; }; 5982407B776A2A4BF04125BA /* StatCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE64AD9C32691F3111C8595F /* StatCardView.swift */; }; 67EED72EDEC3D8621574A4BC /* ResearchCenterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */; }; 70BA18D24CCC880D502CADD7 /* SquadsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */; }; @@ -42,14 +44,17 @@ AE9607AB8A5E0C197FFB861E /* PlayerCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 029080D103ECBCC33E9E38F8 /* PlayerCellView.swift */; }; B0DA6E09C0BD2DD22E1CCC99 /* match_cache.json in Resources */ = {isa = PBXBuildFile; fileRef = AF50D005DA852CAE53DC0E99 /* match_cache.json */; }; B28DD1DE6BE6197370BB602C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB90A6DC8002673826C8BD0 /* ContentView.swift */; }; + B2FBCA5535B628A8827395B7 /* PlaysStreamView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C131AA2D56A147325E0E848 /* PlaysStreamView.swift */; }; B6F4346E4C192BF816F68EAA /* Cactus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82B9451069B6343C41C337AC /* Cactus.swift */; }; BA8DD13242C5D90231FBF21E /* ArchiveDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05EF9474EB26DF74B8D7FDAA /* ArchiveDetailView.swift */; }; + BBE476D5CF788B4125A50962 /* PlaysDBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */; }; C072623647D8C5AF5C70080D /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBAB314A003AE79E3D7E3791 /* GeminiService.swift */; }; C2EC1CB5DC0D4914B540E12A /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF9FC0FE9D60DC37A1594C96 /* Session.swift */; }; C51482DD2F2F981AD8D640F5 /* SportradarBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EAD55D55FDE50021FA38E3 /* SportradarBadge.swift */; }; CC3B9BF6F21086368795B456 /* TeamSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1F0EA67AFC55CE71E2374 /* TeamSetupView.swift */; }; D2F4BB6524F4500D144AF80C /* CactusService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90AFD39809B3E0BE8DF8644B /* CactusService.swift */; }; D72A2274675152B2E545ED57 /* TacticalSpottingBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1F12695D4CB88A451D3918D /* TacticalSpottingBoardView.swift */; }; + DC5AA753C120F87BE6240707 /* PlayByPlayKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5C1A4F9118E151B9F0F57F22 /* PlayByPlayKit */; }; DF2E26836A96D0D12400BA94 /* ListeningDot.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE877181D0D2EB6F44FCF490 /* ListeningDot.swift */; }; E05C57FFDF0F3B9977139753 /* LatencyTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AE6D73A8667738DD33BAF2B /* LatencyTag.swift */; }; E16958E56C7E41CCDE6D3B46 /* GameFetchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D12F4621EA52FEBDFBBA9E09 /* GameFetchService.swift */; }; @@ -97,11 +102,14 @@ 51919B20535309C89D4E15B9 /* Tokens.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tokens.swift; sourceTree = ""; }; 54D3D58CDEAD133FF9CB941E /* CommentatorStylePickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommentatorStylePickerView.swift; sourceTree = ""; }; 57DC475ADA91F2B5E0A8A94C /* MockResponderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockResponderTests.swift; sourceTree = ""; }; + 721C2BA2DE9BCD5F29F526F0 /* PlaysSearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaysSearchView.swift; sourceTree = ""; }; 757AB2F3C722DB4440337D1A /* PressToTalkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PressToTalkButton.swift; sourceTree = ""; }; + 7C131AA2D56A147325E0E848 /* PlaysStreamView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaysStreamView.swift; sourceTree = ""; }; 7CE728CE31ACC8F9DB7324B9 /* MockResponder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockResponder.swift; sourceTree = ""; }; 7DD86CEF67DA77208349168F /* BroadcastBrainTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BroadcastBrainTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 82A885FF039D9F376DE27C84 /* DottedGrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DottedGrid.swift; sourceTree = ""; }; 82B9451069B6343C41C337AC /* Cactus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cactus.swift; sourceTree = ""; }; + 846A697EC3777956030AC4C3 /* PlayByPlayStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayByPlayStore.swift; sourceTree = ""; }; 8AE6D73A8667738DD33BAF2B /* LatencyTag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LatencyTag.swift; sourceTree = ""; }; 8CC045EB8451818A6CD5A1ED /* ArchivesListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArchivesListView.swift; sourceTree = ""; }; 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SquadsView.swift; sourceTree = ""; }; @@ -117,6 +125,7 @@ B4F1237976FCC7179733FC75 /* ChatMessageRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatMessageRow.swift; sourceTree = ""; }; B79E4BA0F9248D3466873BBE /* LivePill.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LivePill.swift; sourceTree = ""; }; B83E5A0C129A26A3CC625311 /* AudioCaptureService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioCaptureService.swift; sourceTree = ""; }; + B94DFFB69D5F724350D835B4 /* PlayByPlayKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = PlayByPlayKit; path = PlayByPlayKit; sourceTree = SOURCE_ROOT; }; B9C5C443A7D8D3D41E5B0E13 /* FlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowLayout.swift; sourceTree = ""; }; BAB90A6DC8002673826C8BD0 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; C3A6A719D484016893C42760 /* MatchCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatchCache.swift; sourceTree = ""; }; @@ -130,6 +139,7 @@ EA68D7CA900438A10D7B4AC9 /* NewsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsService.swift; sourceTree = ""; }; EE877181D0D2EB6F44FCF490 /* ListeningDot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListeningDot.swift; sourceTree = ""; }; EF6CAC9075A33368706F52FE /* ThemeStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeStore.swift; sourceTree = ""; }; + F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaysDBView.swift; sourceTree = ""; }; F1F12695D4CB88A451D3918D /* TacticalSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TacticalSpottingBoardView.swift; sourceTree = ""; }; FBAB314A003AE79E3D7E3791 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = ""; }; @@ -143,6 +153,7 @@ buildActionMask = 2147483647; files = ( 70BC25E15A41151CA931A4B9 /* cactus-macos.xcframework in Frameworks */, + DC5AA753C120F87BE6240707 /* PlayByPlayKit in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -157,6 +168,9 @@ 54D3D58CDEAD133FF9CB941E /* CommentatorStylePickerView.swift */, 01550DE4B92113B1173C6B2F /* LivePaneView.swift */, FE805D3AE864A2EC89074CF1 /* NewsTabView.swift */, + F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */, + 721C2BA2DE9BCD5F29F526F0 /* PlaysSearchView.swift */, + 7C131AA2D56A147325E0E848 /* PlaysStreamView.swift */, 2268C5BB146969E1B046A49E /* ResearchCenterView.swift */, FD1F4DAD40C5C4BFB52EA58D /* SidebarView.swift */, 8F4CA2B25FE5241CA80B742B /* SquadsView.swift */, @@ -264,6 +278,7 @@ children = ( 5E133AC1178766FED41CC012 /* BroadcastBrain */, 2FB4C7AF75A217215F604EB7 /* BroadcastBrainTests */, + F1AA7256D7D83E51F35D717F /* Packages */, D1C7F98E649425E4E53622C6 /* Frameworks */, 65A284292BEEBC0943964CCE /* Products */, ); @@ -273,6 +288,7 @@ isa = PBXGroup; children = ( A5C2E3CFAB5CA8C1AD68FB5B /* AppStore.swift */, + 846A697EC3777956030AC4C3 /* PlayByPlayStore.swift */, C9F5FE8926459F794E4A039D /* SessionStore.swift */, EF6CAC9075A33368706F52FE /* ThemeStore.swift */, ); @@ -287,6 +303,14 @@ name = Frameworks; sourceTree = ""; }; + F1AA7256D7D83E51F35D717F /* Packages */ = { + isa = PBXGroup; + children = ( + B94DFFB69D5F724350D835B4 /* PlayByPlayKit */, + ); + name = Packages; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -323,6 +347,7 @@ ); name = BroadcastBrain; packageProductDependencies = ( + 5C1A4F9118E151B9F0F57F22 /* PlayByPlayKit */, ); productName = BroadcastBrain; productReference = 1BDB3FB2A46D89FB8F6E528D /* BroadcastBrain.app */; @@ -357,6 +382,9 @@ ); mainGroup = AFF55C48CD22E09820BEB37C; minimizedProjectReferenceProxies = 1; + packageReferences = ( + D325D9FCCDF26CC90AFB3972 /* XCLocalSwiftPackageReference "PlayByPlayKit" */, + ); preferredProjectObjectVersion = 77; projectDirPath = ""; projectRoot = ""; @@ -417,7 +445,11 @@ E31D20151B71FBD3257BF1D8 /* MockResponder.swift in Sources */, 06A1F33ECBAF18586AC02A37 /* NewsService.swift in Sources */, 4DD529CF07EB0CCAB762BEAF /* NewsTabView.swift in Sources */, + 0CC48F247E683B3FB185A6FB /* PlayByPlayStore.swift in Sources */, AE9607AB8A5E0C197FFB861E /* PlayerCellView.swift in Sources */, + BBE476D5CF788B4125A50962 /* PlaysDBView.swift in Sources */, + 5874FC398254108334E944D0 /* PlaysSearchView.swift in Sources */, + B2FBCA5535B628A8827395B7 /* PlaysStreamView.swift in Sources */, 41B921C4FB590088E94910D6 /* PressToTalkButton.swift in Sources */, 67EED72EDEC3D8621574A4BC /* ResearchCenterView.swift in Sources */, C2EC1CB5DC0D4914B540E12A /* Session.swift in Sources */, @@ -692,6 +724,20 @@ defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + D325D9FCCDF26CC90AFB3972 /* XCLocalSwiftPackageReference "PlayByPlayKit" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = PlayByPlayKit; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 5C1A4F9118E151B9F0F57F22 /* PlayByPlayKit */ = { + isa = XCSwiftPackageProductDependency; + productName = PlayByPlayKit; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = B8AC317D5AF7C3382A569AB7 /* Project object */; } diff --git a/BroadcastBrain/BroadcastBrainApp.swift b/BroadcastBrain/BroadcastBrainApp.swift index 2ad637a9..c99ddc75 100644 --- a/BroadcastBrain/BroadcastBrainApp.swift +++ b/BroadcastBrain/BroadcastBrainApp.swift @@ -19,7 +19,11 @@ struct BroadcastBrainApp: App { private static func makeStore() -> AppStore { let sessionStore = SessionStore() let cactus: CactusService = makeCactusService() - return AppStore(sessionStore: sessionStore, cactus: cactus) + let cacheDir = FileManager.default + .urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] + .appendingPathComponent("BroadcastBrain/playbyplay", isDirectory: true) + let pbp = PlayByPlayStore(cacheDirectory: cacheDir) + return AppStore(sessionStore: sessionStore, cactus: cactus, playByPlayStore: pbp) } private static func makeCactusService() -> CactusService { diff --git a/BroadcastBrain/ContentView.swift b/BroadcastBrain/ContentView.swift index 06c0678b..c4da1a02 100644 --- a/BroadcastBrain/ContentView.swift +++ b/BroadcastBrain/ContentView.swift @@ -29,6 +29,8 @@ struct ContentView: View { case .research: ResearchCenterView() case .news: NewsTabView() case .archive: ArchivesListView() + case .plays: PlaysSearchView() + case .playsDB: PlaysDBView() } } } diff --git a/BroadcastBrain/Stores/AppStore.swift b/BroadcastBrain/Stores/AppStore.swift index eab9ba68..d7595ad0 100644 --- a/BroadcastBrain/Stores/AppStore.swift +++ b/BroadcastBrain/Stores/AppStore.swift @@ -2,7 +2,7 @@ import Foundation import Observation enum Surface: String, CaseIterable, Identifiable { - case live, squads, research, news, archive + case live, squads, research, news, archive, plays, playsDB var id: String { rawValue } } @@ -38,15 +38,17 @@ final class AppStore { let sessionStore: SessionStore let cactus: CactusService + let playByPlayStore: PlayByPlayStore // Saved cache location — overrides bundled resource after first user fetch private static let savedCacheURL: URL = FileManager.default .urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] .appendingPathComponent("BroadcastBrain/match_cache.json") - init(sessionStore: SessionStore, cactus: CactusService) { + init(sessionStore: SessionStore, cactus: CactusService, playByPlayStore: PlayByPlayStore) { self.sessionStore = sessionStore self.cactus = cactus + self.playByPlayStore = playByPlayStore // Only user-saved cache counts — no bundled fallback, so first launch always // forces the team setup screen for a tailored experience. diff --git a/BroadcastBrain/Stores/PlayByPlayStore.swift b/BroadcastBrain/Stores/PlayByPlayStore.swift new file mode 100644 index 00000000..e458842d --- /dev/null +++ b/BroadcastBrain/Stores/PlayByPlayStore.swift @@ -0,0 +1,168 @@ +import Foundation +import Observation +import PlayByPlayKit + +struct SavedGameEntry: Identifiable, Hashable { + let fileURL: URL + let leagueKey: String + let game: CompactGame + let modifiedAt: Date + var id: String { fileURL.path } +} + +@MainActor +@Observable +final class PlayByPlayStore { + let leagues: [League] = League.all + var selectedLeague: League + var games: [Game] = [] + var searchText: String = "" + var loadingGames: Bool = false + var gamesError: String? + + var selectedGame: Game? + var currentCompact: CompactGame? + var streamError: String? + var isStreaming: Bool = false + var lastUpdated: Date? + + var plays: [CompactPlay] { + guard let c = currentCompact else { return [] } + return c.periods.flatMap { $0.plays } + } + + let cacheDirectory: URL + + private var activeSession: LiveSession? + private var streamTask: Task? + + init(cacheDirectory: URL) { + self.cacheDirectory = cacheDirectory + self.selectedLeague = League.all.first(where: { $0.key == "nba" }) ?? League.all[0] + try? FileManager.default.createDirectory(at: cacheDirectory, withIntermediateDirectories: true) + } + + var filteredGames: [Game] { + let q = searchText.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() + guard !q.isEmpty else { return games } + return games.filter { g in + g.name.lowercased().contains(q) + || g.shortName.lowercased().contains(q) + || g.homeTeam.lowercased().contains(q) + || g.awayTeam.lowercased().contains(q) + } + } + + func loadLiveGames() async { + loadingGames = true + gamesError = nil + defer { loadingGames = false } + do { + let league = selectedLeague + games = try await PlayByPlay.getLiveGames(league) + } catch { + games = [] + gamesError = String(describing: error) + } + } + + func selectLeague(_ league: League) { + guard league != selectedLeague else { return } + selectedLeague = league + games = [] + } + + func startStreaming(_ game: Game) { + stopStreaming() + + selectedGame = game + currentCompact = nil + streamError = nil + isStreaming = true + lastUpdated = nil + + let league = selectedLeague + let cacheDir = cacheDirectory + let session = PlayByPlay.liveSession( + league: league, + game: game, + cacheDirectory: cacheDir, + pollInterval: 0.5, + maxConsecutiveTransientFailures: 20, + onTransientError: nil + ) + activeSession = session + + streamTask = Task { [weak self] in + await session.start() + let stream = await session.deltas + do { + for try await delta in stream { + await MainActor.run { + guard let self else { return } + self.currentCompact = delta.state + self.lastUpdated = Date() + } + if Task.isCancelled { break } + } + } catch { + await MainActor.run { + self?.streamError = String(describing: error) + self?.isStreaming = false + } + } + await MainActor.run { + self?.isStreaming = false + } + } + } + + func stopStreaming() { + streamTask?.cancel() + streamTask = nil + if let session = activeSession { + Task { await session.stop() } + } + activeSession = nil + isStreaming = false + } + + func clearSelection() { + stopStreaming() + selectedGame = nil + currentCompact = nil + streamError = nil + lastUpdated = nil + } + + func listSavedGames() -> [SavedGameEntry] { + let fm = FileManager.default + guard let leagueDirs = try? fm.contentsOfDirectory( + at: cacheDirectory, + includingPropertiesForKeys: [.isDirectoryKey] + ) else { return [] } + + let decoder = JSONDecoder() + var entries: [SavedGameEntry] = [] + for dir in leagueDirs { + var isDir: ObjCBool = false + guard fm.fileExists(atPath: dir.path, isDirectory: &isDir), isDir.boolValue else { continue } + guard let files = try? fm.contentsOfDirectory( + at: dir, + includingPropertiesForKeys: [.contentModificationDateKey] + ) else { continue } + for file in files where file.pathExtension == "json" && !file.lastPathComponent.hasPrefix(".") { + guard let data = try? Data(contentsOf: file), + let game = try? decoder.decode(CompactGame.self, from: data) else { continue } + let mtime = (try? file.resourceValues(forKeys: [.contentModificationDateKey]).contentModificationDate) ?? Date.distantPast + entries.append(SavedGameEntry( + fileURL: file, + leagueKey: dir.lastPathComponent, + game: game, + modifiedAt: mtime + )) + } + } + return entries.sorted { $0.modifiedAt > $1.modifiedAt } + } +} diff --git a/BroadcastBrain/Views/PlaysDBView.swift b/BroadcastBrain/Views/PlaysDBView.swift new file mode 100644 index 00000000..ee48b88b --- /dev/null +++ b/BroadcastBrain/Views/PlaysDBView.swift @@ -0,0 +1,362 @@ +import SwiftUI +import PlayByPlayKit + +struct PlaysDBView: View { + @Environment(AppStore.self) private var store + + @State private var entries: [SavedGameEntry] = [] + @State private var selected: SavedGameEntry? + @State private var query: String = "" + + var body: some View { + VStack(spacing: 0) { + StatusBarView( + matchTitle: selected?.game.game.shortName ?? "Plays DB · ESPN cache", + isAirplane: false, + latencyMs: nil + ) + + if let sel = selected { + detailHeader(sel) + detailView(sel) + } else { + listHeader + listView + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.bgBase) + .onAppear { reload() } + } + + // MARK: - List header + + private var listHeader: some View { + HStack(spacing: 12) { + Text("SAVED PLAYS") + .font(Typography.sectionHead) + .tracking(1.4) + .foregroundStyle(Color.textSubtle) + + countPill("\(entries.count) GAMES") + + Spacer() + + searchField + + refreshButton + } + .padding(.horizontal, 20) + .padding(.vertical, 12) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { + Rectangle().fill(Color.bbBorder).frame(height: 1) + } + } + + private var searchField: some View { + HStack(spacing: 6) { + Image(systemName: "magnifyingglass") + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(Color.textSubtle) + TextField("Search saved games", text: $query) + .textFieldStyle(.plain) + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + if !query.isEmpty { + Button { query = "" } label: { + Image(systemName: "xmark.circle.fill") + .font(.system(size: 10)) + .foregroundStyle(Color.textSubtle) + } + .buttonStyle(.plain) + } + } + .padding(.horizontal, 8) + .padding(.vertical, 6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) + .frame(width: 240) + } + + private var refreshButton: some View { + Button { + reload() + } label: { + Image(systemName: "arrow.clockwise") + .font(.system(size: 11, weight: .semibold)) + .foregroundStyle(Color.textMuted) + .frame(width: 32, height: 30) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) + .help("Re-scan saved games") + } + + private func countPill(_ text: String) -> some View { + Text(text) + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 6) + .padding(.vertical, 3) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 3)) + .overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.bbBorder, lineWidth: 1)) + } + + // MARK: - List body + + private var filtered: [SavedGameEntry] { + let q = query.trimmingCharacters(in: .whitespaces).lowercased() + guard !q.isEmpty else { return entries } + return entries.filter { + $0.game.game.shortName.lowercased().contains(q) + || $0.leagueKey.lowercased().contains(q) + } + } + + private var listView: some View { + ScrollView { + LazyVStack(spacing: 10) { + if entries.isEmpty { + emptyState + } else if filtered.isEmpty { + noMatchState + } else { + ForEach(filtered) { entry in + SavedGameRow(entry: entry) + .contentShape(Rectangle()) + .onTapGesture { selected = entry } + } + } + } + .padding(20) + } + } + + private var emptyState: some View { + VStack(spacing: 10) { + Image(systemName: "tray") + .font(.system(size: 28, weight: .light)) + .foregroundStyle(Color.textSubtle) + Text("No saved games yet") + .font(Typography.body) + .foregroundStyle(Color.textPrimary) + Text("Start streaming a game from the Plays tab — each play is cached here for offline scrubbing.") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .multilineTextAlignment(.center) + .frame(maxWidth: 380) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 48) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) + .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1)) + } + + private var noMatchState: some View { + Text("No saved games match ‘\(query)’") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .frame(maxWidth: .infinity) + .padding(.vertical, 32) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) + .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1)) + } + + // MARK: - Detail + + private func detailHeader(_ entry: SavedGameEntry) -> some View { + HStack(spacing: 12) { + Button { selected = nil } label: { + HStack(spacing: 4) { + Image(systemName: "chevron.left") + .font(.system(size: 10, weight: .semibold)) + Text("ALL SAVED GAMES") + .font(.system(size: 10, weight: .semibold, design: .monospaced)) + .tracking(1.2) + } + .foregroundStyle(Color.textMuted) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) + + leagueBadge(entry.leagueKey) + + Text(entry.game.game.shortName) + .font(.system(size: 14, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + + Text(entry.game.game.statusDetail) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + + Spacer() + + HStack(spacing: 6) { + Text("\(entry.game.totalPlays)") + .font(.system(size: 14, weight: .bold, design: .monospaced)) + .foregroundStyle(Color.verified) + Text("PLAYS") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(Color.textSubtle) + } + } + .padding(.horizontal, 20) + .padding(.vertical, 12) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { + Rectangle().fill(Color.bbBorder).frame(height: 1) + } + } + + private func detailView(_ entry: SavedGameEntry) -> some View { + ScrollView { + LazyVStack(alignment: .leading, spacing: 10, pinnedViews: [.sectionHeaders]) { + ForEach(entry.game.periods, id: \.number) { period in + Section { + VStack(alignment: .leading, spacing: 6) { + ForEach(period.plays) { play in + PlayRow(play: play, compact: entry.game) + } + } + .padding(.bottom, 8) + } header: { + HStack(spacing: 10) { + Text(period.displayValue ?? "Period \(period.number)") + .font(.system(size: 10, weight: .semibold, design: .monospaced)) + .tracking(1.6) + .foregroundStyle(Color.textSubtle) + Rectangle().fill(Color.bbBorder).frame(height: 1) + Text("\(period.plays.count)") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + .padding(.vertical, 6) + .background(Color.bgBase) + } + } + } + .padding(20) + } + } + + // MARK: - League badge + + private func leagueBadge(_ key: String) -> some View { + let accent = PlaysDBView.leagueAccent(key) + return Text(key.uppercased()) + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(accent) + .padding(.horizontal, 6) + .padding(.vertical, 3) + .background(accent.opacity(0.12), in: RoundedRectangle(cornerRadius: 3)) + .overlay(RoundedRectangle(cornerRadius: 3).stroke(accent.opacity(0.3), lineWidth: 1)) + } + + static func leagueAccent(_ key: String) -> Color { + switch key.lowercased() { + case let k where k.contains("nba"): return Color(hex: "#E87A00") + case let k where k.contains("mlb"): return Color(hex: "#3B82F6") + case let k where k.contains("nfl"): return Color(hex: "#8B5CF6") + case let k where k.contains("nhl"): return Color(hex: "#22C55E") + case let k where k.contains("mls"), + let k where k.contains("epl"), + let k where k.contains("uefa"): return Color.verified + default: return Color.textMuted + } + } + + private func reload() { + entries = store.playByPlayStore.listSavedGames() + } +} + +// MARK: - Saved game row + +private struct SavedGameRow: View { + let entry: SavedGameEntry + + @State private var hovering = false + + private var accent: Color { PlaysDBView.leagueAccent(entry.leagueKey) } + + var body: some View { + HStack(alignment: .center, spacing: 0) { + Rectangle() + .fill(accent) + .frame(width: 3) + + // League badge + Text(entry.leagueKey.uppercased()) + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(accent) + .frame(width: 52, alignment: .center) + .padding(.vertical, 4) + .background(accent.opacity(0.1), in: RoundedRectangle(cornerRadius: 3)) + .overlay(RoundedRectangle(cornerRadius: 3).stroke(accent.opacity(0.25), lineWidth: 1)) + .padding(.leading, 14) + .padding(.trailing, 14) + + // Matchup + VStack(alignment: .leading, spacing: 3) { + Text(entry.game.game.shortName) + .font(.system(size: 15, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + .lineLimit(1) + HStack(spacing: 8) { + Text(entry.game.game.statusDetail) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + if !entry.game.game.awayScore.isEmpty, !entry.game.game.homeScore.isEmpty { + Text("·") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + Text("\(entry.game.game.awayScore)–\(entry.game.game.homeScore)") + .font(Typography.chip) + .foregroundStyle(Color.textMuted) + } + } + } + + Spacer() + + // Play count hero stat + VStack(alignment: .trailing, spacing: 2) { + HStack(spacing: 5) { + Text("\(entry.game.totalPlays)") + .font(.system(size: 15, weight: .bold, design: .monospaced)) + .foregroundStyle(Color.verified) + Text("PLAYS") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(Color.textSubtle) + } + Text(entry.modifiedAt.formatted(date: .abbreviated, time: .shortened)) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + + Image(systemName: "chevron.right") + .font(.system(size: 10, weight: .semibold)) + .foregroundStyle(hovering ? Color.textPrimary : Color.textSubtle) + .padding(.leading, 12) + .padding(.trailing, 14) + } + .padding(.vertical, 12) + .frame(maxWidth: .infinity) + .background(hovering ? Color.bgHover : Color.bgRaised) + .overlay( + RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1) + ) + .clipShape(RoundedRectangle(cornerRadius: 6)) + .onHover { hovering = $0 } + } +} diff --git a/BroadcastBrain/Views/PlaysSearchView.swift b/BroadcastBrain/Views/PlaysSearchView.swift new file mode 100644 index 00000000..eada45e4 --- /dev/null +++ b/BroadcastBrain/Views/PlaysSearchView.swift @@ -0,0 +1,446 @@ +import SwiftUI +import PlayByPlayKit + +struct PlaysSearchView: View { + @Environment(AppStore.self) private var store + + var body: some View { + @Bindable var pbp = store.playByPlayStore + + VStack(spacing: 0) { + StatusBarView( + matchTitle: "Plays · ESPN feed", + isAirplane: false, + latencyMs: nil + ) + + header(pbp: pbp) + + if pbp.selectedGame != nil { + PlaysStreamView() + } else { + scoreboard(pbp: pbp) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.bgBase) + .task { + if pbp.games.isEmpty && pbp.selectedGame == nil { + await pbp.loadLiveGames() + } + } + } + + // MARK: - Header + + private func header(pbp: PlayByPlayStore) -> some View { + HStack(spacing: 12) { + leaguePicker(pbp: pbp) + searchField(pbp: pbp) + refreshButton(pbp: pbp) + } + .padding(.horizontal, 20) + .padding(.vertical, 12) + .background(Color.bgRaised) + .overlay(alignment: .bottom) { + Rectangle().fill(Color.bbBorder).frame(height: 1) + } + } + + private func leaguePicker(pbp: PlayByPlayStore) -> some View { + Menu { + ForEach(pbp.leagues, id: \.key) { league in + Button(league.displayName) { + pbp.selectedLeague = league + pbp.games = [] + Task { await pbp.loadLiveGames() } + } + } + } label: { + LeagueDropdownLabel(name: pbp.selectedLeague.displayName) + } + .menuStyle(.borderlessButton) + .menuIndicator(.hidden) + .fixedSize() + } + + private func searchField(pbp: PlayByPlayStore) -> some View { + SearchFieldRow( + text: Binding( + get: { pbp.searchText }, + set: { pbp.searchText = $0 } + ) + ) + } + + private func refreshButton(pbp: PlayByPlayStore) -> some View { + Button { + Task { await pbp.loadLiveGames() } + } label: { + Group { + if pbp.loadingGames { + ProgressView().controlSize(.small) + } else { + Image(systemName: "arrow.clockwise") + .font(.system(size: 11, weight: .semibold)) + .foregroundStyle(Color.textMuted) + } + } + .frame(width: 32, height: 30) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) + .help("Refresh live games") + } + + // MARK: - Scoreboard + + private func scoreboard(pbp: PlayByPlayStore) -> some View { + ScrollView { + LazyVStack(spacing: 18, pinnedViews: [.sectionHeaders]) { + if let err = pbp.gamesError { + errorBanner(err) + } + + let grouped = GameGroup.group(pbp.filteredGames) + + if grouped.isEmpty && !pbp.loadingGames { + emptyState(leagueName: pbp.selectedLeague.displayName, + hasQuery: !pbp.searchText.isEmpty) + } + + ForEach(grouped, id: \.status) { bucket in + Section { + VStack(spacing: 8) { + ForEach(bucket.games) { game in + GameRow(game: game) + .contentShape(Rectangle()) + .onTapGesture { pbp.startStreaming(game) } + } + } + } header: { + sectionHeader(bucket) + } + } + } + .padding(20) + } + } + + private func sectionHeader(_ bucket: GameGroup) -> some View { + HStack(spacing: 10) { + if bucket.status == .live { + LiveDot() + } + Text(bucket.status.label) + .font(.system(size: 10, weight: .semibold, design: .monospaced)) + .tracking(1.6) + .foregroundStyle(bucket.status == .live ? Color.live : Color.textSubtle) + Rectangle().fill(Color.bbBorder).frame(height: 1) + Text("\(bucket.games.count)") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + .padding(.vertical, 6) + .background(Color.bgBase) + } + + private func errorBanner(_ text: String) -> some View { + HStack(spacing: 8) { + Image(systemName: "exclamationmark.triangle.fill") + .font(.system(size: 11)) + .foregroundStyle(Color.live) + Text(text) + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + } + .padding(.horizontal, 12) + .padding(.vertical, 10) + .frame(maxWidth: .infinity, alignment: .leading) + .background(Color.live.opacity(0.08), in: RoundedRectangle(cornerRadius: 6)) + .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.live.opacity(0.3), lineWidth: 1)) + } + + private func emptyState(leagueName: String, hasQuery: Bool) -> some View { + VStack(spacing: 10) { + Image(systemName: hasQuery ? "magnifyingglass" : "sportscourt") + .font(.system(size: 28, weight: .light)) + .foregroundStyle(Color.textSubtle) + Text(hasQuery ? "No matches" : "No live games") + .font(Typography.body) + .foregroundStyle(Color.textPrimary) + Text(hasQuery + ? "Try a different team name or switch leagues." + : "\(leagueName) has no games in progress. Check back later or refresh.") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .multilineTextAlignment(.center) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 48) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) + .overlay(RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1)) + } +} + +// MARK: - Grouping + +enum GameStatus: Int, CaseIterable { + case live, scheduled, final, other + + var label: String { + switch self { + case .live: return "LIVE NOW" + case .scheduled: return "UPCOMING" + case .final: return "COMPLETED" + case .other: return "OTHER" + } + } + + static func from(_ raw: String) -> GameStatus { + let s = raw.lowercased() + if s.contains("in progress") || s.contains("halftime") || s.contains("delay") { return .live } + if s.contains("scheduled") || s.contains("pre") || s.contains("upcoming") { return .scheduled } + if s.contains("final") || s.contains("full time") || s.contains("end of") { return .final } + return .other + } +} + +struct GameGroup { + let status: GameStatus + let games: [Game] + + static func group(_ games: [Game]) -> [GameGroup] { + var byStatus: [GameStatus: [Game]] = [:] + for g in games { + byStatus[GameStatus.from(g.status), default: []].append(g) + } + return GameStatus.allCases.compactMap { s in + guard let list = byStatus[s], !list.isEmpty else { return nil } + return GameGroup(status: s, games: list) + } + } +} + +// MARK: - Row + +private struct GameRow: View { + let game: Game + @State private var hovering = false + + private var status: GameStatus { GameStatus.from(game.status) } + + private var homeWin: Bool { + guard let h = Int(game.homeScore), let a = Int(game.awayScore) else { return false } + return h > a + } + + private var awayWin: Bool { + guard let h = Int(game.homeScore), let a = Int(game.awayScore) else { return false } + return a > h + } + + private var accentColor: Color { + switch status { + case .live: return Color.live + case .scheduled: return Color.esoteric + case .final: return Color.verified + case .other: return Color.bbBorder + } + } + + var body: some View { + HStack(alignment: .center, spacing: 0) { + // Accent stripe + Rectangle() + .fill(accentColor) + .frame(width: 3) + + // Status pill column (fixed width) + statusPill + .frame(width: 90, alignment: .leading) + .padding(.leading, 14) + + // Matchup (fixed width) + HStack(spacing: 8) { + Text(awayAbbr) + .font(.system(size: 16, weight: .bold, design: .monospaced)) + .foregroundStyle(awayWin && status == .final ? Color.textPrimary : Color.textMuted) + Text("@") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + Text(homeAbbr) + .font(.system(size: 16, weight: .bold, design: .monospaced)) + .foregroundStyle(homeWin && status == .final ? Color.textPrimary : Color.textMuted) + } + .frame(width: 160, alignment: .leading) + + // Teams + score + VStack(alignment: .leading, spacing: 3) { + teamLine(name: game.awayTeam, score: game.awayScore, isWinner: awayWin) + teamLine(name: game.homeTeam, score: game.homeScore, isWinner: homeWin) + } + + Spacer() + + // Period / detail + Text(game.period.isEmpty ? game.statusDetail : game.period) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + .lineLimit(1) + + Image(systemName: "chevron.right") + .font(.system(size: 10, weight: .semibold)) + .foregroundStyle(hovering ? Color.textPrimary : Color.textSubtle) + .padding(.leading, 12) + .padding(.trailing, 14) + } + .padding(.vertical, 12) + .frame(maxWidth: .infinity) + .background(hovering ? Color.bgHover : Color.bgRaised) + .overlay( + RoundedRectangle(cornerRadius: 6).stroke(Color.bbBorder, lineWidth: 1) + ) + .clipShape(RoundedRectangle(cornerRadius: 6)) + .onHover { hovering = $0 } + } + + // MARK: sub-views + + private var awayAbbr: String { game.awayTeamAbbr ?? String(game.awayTeam.prefix(3)).uppercased() } + private var homeAbbr: String { game.homeTeamAbbr ?? String(game.homeTeam.prefix(3)).uppercased() } + + @ViewBuilder + private var statusPill: some View { + switch status { + case .live: + HStack(spacing: 5) { + LiveDot() + Text("LIVE") + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(Color.live) + } + .padding(.horizontal, 6) + .padding(.vertical, 3) + .background(Color.live.opacity(0.12), in: RoundedRectangle(cornerRadius: 3)) + .overlay(RoundedRectangle(cornerRadius: 3).stroke(Color.live.opacity(0.35), lineWidth: 1)) + case .scheduled: + pill("UPCOMING", color: .esoteric) + case .final: + pill("FINAL", color: .textSubtle) + case .other: + pill(game.status.uppercased(), color: .textSubtle) + } + } + + private func pill(_ text: String, color: Color) -> some View { + Text(text) + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(color) + .padding(.horizontal, 6) + .padding(.vertical, 3) + .background(color.opacity(0.1), in: RoundedRectangle(cornerRadius: 3)) + .overlay(RoundedRectangle(cornerRadius: 3).stroke(color.opacity(0.25), lineWidth: 1)) + } + + private func teamLine(name: String, score: String, isWinner: Bool) -> some View { + HStack(spacing: 8) { + Text(name) + .font(.system(size: 12, weight: isWinner ? .semibold : .regular, design: .monospaced)) + .foregroundStyle(isWinner ? Color.textPrimary : Color.textMuted) + .lineLimit(1) + Spacer(minLength: 6) + Text(score) + .font(.system(size: 13, weight: .bold, design: .monospaced)) + .foregroundStyle(isWinner ? Color.textPrimary : Color.textMuted) + .frame(minWidth: 28, alignment: .trailing) + } + .frame(maxWidth: 280) + } +} + +private struct LeagueDropdownLabel: View { + let name: String + @State private var hovering = false + + var body: some View { + HStack(spacing: 10) { + Text("LEAGUE") + .font(.system(size: 8, weight: .bold, design: .monospaced)) + .tracking(1.4) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 5) + .padding(.vertical, 2) + .background(Color.bgBase, in: RoundedRectangle(cornerRadius: 2)) + .overlay(RoundedRectangle(cornerRadius: 2).stroke(Color.bbBorder, lineWidth: 1)) + + Text(name.uppercased()) + .font(.system(size: 12, weight: .semibold, design: .monospaced)) + .tracking(0.6) + .foregroundStyle(Color.textPrimary) + + Rectangle() + .fill(Color.bbBorder) + .frame(width: 1, height: 16) + + Image(systemName: "chevron.down") + .font(.system(size: 10, weight: .bold)) + .foregroundStyle(hovering ? Color.textPrimary : Color.textMuted) + } + .padding(.horizontal, 10) + .padding(.vertical, 8) + .background(hovering ? Color.bgHover : Color.bgRaised) + .overlay( + RoundedRectangle(cornerRadius: 6) + .stroke(Color.bbBorder, lineWidth: 1) + ) + .clipShape(RoundedRectangle(cornerRadius: 6)) + .contentShape(Rectangle()) + .onHover { hovering = $0 } + } +} + +private struct SearchFieldRow: View { + @Binding var text: String + + var body: some View { + HStack(spacing: 6) { + Image(systemName: "magnifyingglass") + .font(.system(size: 10, weight: .medium)) + .foregroundStyle(Color.textSubtle) + TextField("Filter by team", text: $text) + .textFieldStyle(.plain) + .font(Typography.chip) + .foregroundStyle(Color.textPrimary) + if !text.isEmpty { + Button { text = "" } label: { + Image(systemName: "xmark.circle.fill") + .font(.system(size: 10)) + .foregroundStyle(Color.textSubtle) + } + .buttonStyle(.plain) + } + } + .padding(.horizontal, 8) + .padding(.vertical, 6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) + .frame(maxWidth: .infinity) + } +} + +private struct LiveDot: View { + @State private var pulse = false + var body: some View { + Circle() + .fill(Color.live) + .frame(width: 6, height: 6) + .scaleEffect(pulse ? 1.3 : 0.85) + .opacity(pulse ? 0.5 : 1.0) + .animation(.easeInOut(duration: 0.7).repeatForever(), value: pulse) + .onAppear { pulse = true } + } +} diff --git a/BroadcastBrain/Views/PlaysStreamView.swift b/BroadcastBrain/Views/PlaysStreamView.swift new file mode 100644 index 00000000..b121f05e --- /dev/null +++ b/BroadcastBrain/Views/PlaysStreamView.swift @@ -0,0 +1,149 @@ +import SwiftUI +import PlayByPlayKit + +struct PlaysStreamView: View { + @Environment(AppStore.self) private var store + + private var pbp: PlayByPlayStore { store.playByPlayStore } + + var body: some View { + VStack(spacing: 0) { + header + Divider().background(Color.bbBorder) + + if let err = pbp.streamError { + Text(err) + .font(Typography.body) + .foregroundStyle(Color.live) + .padding(12) + } + + ScrollView { + LazyVStack(alignment: .leading, spacing: 6) { + ForEach(pbp.plays.reversed()) { play in + PlayRow(play: play, compact: pbp.currentCompact) + } + } + .padding(16) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(Color.bgBase) + } + + private var header: some View { + HStack(spacing: 12) { + Button { pbp.clearSelection() } label: { + HStack(spacing: 4) { + Image(systemName: "chevron.left") + .font(.system(size: 10, weight: .semibold)) + Text("ALL GAMES") + .font(.system(size: 10, weight: .semibold, design: .monospaced)) + .tracking(1.2) + } + .foregroundStyle(Color.textMuted) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) + .help("Back to game list") + + VStack(alignment: .leading, spacing: 2) { + Text(pbp.selectedGame?.shortName ?? "") + .font(.system(size: 14, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textPrimary) + Text(streamStatus) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + Spacer() + if let game = pbp.currentCompact?.game { + Text("\(game.awayTeam) \(game.awayScore) — \(game.homeScore) \(game.homeTeam)") + .font(Typography.statLabel) + .foregroundStyle(Color.textMuted) + } + Button { + pbp.clearSelection() + } label: { + HStack(spacing: 6) { + Image(systemName: "stop.fill") + .font(.system(size: 9)) + Text("STOP") + .font(.system(size: 10, weight: .bold, design: .monospaced)) + .tracking(1.2) + } + .foregroundStyle(Color.live) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(Color.live.opacity(0.1), in: RoundedRectangle(cornerRadius: 5)) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.live.opacity(0.35), lineWidth: 1)) + } + .buttonStyle(.plain) + .help("Stop streaming") + } + .padding(.horizontal, 20) + .padding(.vertical, 12) + .background(Color.bgRaised) + } + + private var streamStatus: String { + if pbp.streamError != nil { return "stopped · error" } + if pbp.isStreaming { return "streaming · polling every 500ms · \(pbp.plays.count) plays" } + return "\(pbp.plays.count) plays" + } +} + +struct PlayRow: View { + let play: CompactPlay + let compact: CompactGame? + + var body: some View { + HStack(alignment: .top, spacing: 10) { + VStack(alignment: .leading, spacing: 2) { + Text(periodLabel) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + Text(play.clock ?? "") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + .frame(width: 62, alignment: .leading) + + VStack(alignment: .leading, spacing: 4) { + Text(headline) + .font(Typography.body) + .foregroundStyle(Color.textPrimary) + .fixedSize(horizontal: false, vertical: true) + if let teamName = teamName { + Text(teamName) + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + } + Spacer() + if play.scoringPlay == true { + Text("SCORE") + .font(Typography.chip) + .foregroundStyle(Color.verified) + } + } + .padding(10) + .background(Color.bgRaised) + .clipShape(RoundedRectangle(cornerRadius: 6)) + } + + private var periodLabel: String { + play.period?.displayValue ?? play.period.map { "P\($0.number)" } ?? "" + } + + private var headline: String { + play.text ?? play.type ?? "—" + } + + private var teamName: String? { + guard let id = play.teamId, let team = compact?.teams[id] else { return nil } + return team.name ?? team.abbreviation + } +} diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index 8a7ba6ea..36ea6ff8 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -12,6 +12,8 @@ struct SidebarView: View { surfaceRow(title: "Research", systemImage: "book", surface: .research) surfaceRow(title: "News", systemImage: "newspaper", surface: .news) surfaceRow(title: "Archive", systemImage: "archivebox", surface: .archive) + surfaceRow(title: "Plays", systemImage: "sportscourt", surface: .plays) + surfaceRow(title: "Plays DB", systemImage: "tray.full", surface: .playsDB) } } .listStyle(.sidebar) diff --git a/PlayByPlayKit/.gitignore b/PlayByPlayKit/.gitignore new file mode 100644 index 00000000..7635adac --- /dev/null +++ b/PlayByPlayKit/.gitignore @@ -0,0 +1,6 @@ +.build/ +.swiftpm/ +Packages/ +*.xcodeproj +DerivedData/ +.DS_Store diff --git a/PlayByPlayKit/Package.swift b/PlayByPlayKit/Package.swift new file mode 100644 index 00000000..f42ac28f --- /dev/null +++ b/PlayByPlayKit/Package.swift @@ -0,0 +1,17 @@ +// swift-tools-version: 5.9 +import PackageDescription + +let package = Package( + name: "PlayByPlayKit", + platforms: [ + .iOS(.v15), + .macOS(.v12), + ], + products: [ + .library(name: "PlayByPlayKit", targets: ["PlayByPlayKit"]), + ], + targets: [ + .target(name: "PlayByPlayKit"), + .testTarget(name: "PlayByPlayKitTests", dependencies: ["PlayByPlayKit"]), + ] +) diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift b/PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift new file mode 100644 index 00000000..ecd7b138 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/AthleteResponse.swift @@ -0,0 +1,14 @@ +import Foundation + +struct AthleteResponse: Decodable { + let id: String? + let displayName: String? + let fullName: String? + let jersey: String? + let position: Position? + + struct Position: Decodable { + let abbreviation: String? + let displayName: String? + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift b/PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift new file mode 100644 index 00000000..3cd3ff80 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/Compactor.swift @@ -0,0 +1,146 @@ +import Foundation + +enum Compactor { + static func compactPlay( + _ raw: RawPlay, + sport: String, + athletes: inout [String: Athlete] + ) -> CompactPlay { + var participants: [CompactParticipant]? + if let parts = raw.participants, !parts.isEmpty { + participants = parts.map { p in + let id = ESPNRef.extractId(from: p.athlete?.ref) + return CompactParticipant(athleteId: id, type: p.type, order: p.order) + } + } + + var sportFields: SportFields? + switch sport { + case "baseball": + sportFields = .baseball(SportCleaners.cleanBaseball(raw)) + case "basketball": + sportFields = .basketball(SportCleaners.cleanBasketball(raw)) + case "football": + sportFields = .football(SportCleaners.cleanFootball(raw)) + case "hockey": + sportFields = .hockey(SportCleaners.cleanHockey(raw)) + case "soccer": + sportFields = .soccer(SportCleaners.cleanSoccer(raw)) + default: + sportFields = nil + } + + let periodInfo: PeriodInfo? = raw.period.map { p in + PeriodInfo(number: p.number ?? 0, type: p.type, displayValue: p.displayValue) + } + + return CompactPlay( + id: raw.id, + seq: raw.sequenceNumber, + type: raw.type?.text, + text: raw.text, + awayScore: raw.awayScore, + homeScore: raw.homeScore, + clock: raw.clock?.displayValue, + scoringPlay: raw.scoringPlay, + scoreValue: raw.scoreValue, + wallclock: raw.wallclock, + teamId: ESPNRef.extractId(from: raw.team?.ref), + participants: participants, + period: periodInfo, + sportFields: sportFields + ) + } + + static func compactGame( + league: League, + game: Game, + rawPlays: [RawPlay], + athleteMap: [String: AthleteResponse] + ) -> CompactGame { + var athletes: [String: Athlete] = [:] + var teams: [String: TeamRef] = [:] + + if let id = game.homeTeamId { + teams[id] = TeamRef(name: game.homeTeam, abbreviation: game.homeTeamAbbr) + } + if let id = game.awayTeamId { + teams[id] = TeamRef(name: game.awayTeam, abbreviation: game.awayTeamAbbr) + } + + // Pre-populate athletes from resolved refs. + for (ref, a) in athleteMap { + let id = a.id ?? ESPNRef.extractId(from: ref) + guard let id, let name = a.displayName ?? a.fullName else { continue } + if athletes[id] == nil { + athletes[id] = Athlete( + name: name, + jersey: a.jersey, + position: a.position?.abbreviation ?? a.position?.displayName + ) + } + } + + struct PeriodKey: Hashable { + let number: Int + let type: String + } + var orderedKeys: [PeriodKey] = [] + var byKey: [PeriodKey: (type: String?, displayValue: String?, plays: [CompactPlay])] = [:] + + for raw in rawPlays { + let cp = compactPlay(raw, sport: league.sport, athletes: &athletes) + let number = raw.period?.number ?? 0 + let typeStr = raw.period?.type ?? "" + let key = PeriodKey(number: number, type: typeStr) + if byKey[key] == nil { + byKey[key] = (type: raw.period?.type, displayValue: raw.period?.displayValue, plays: []) + orderedKeys.append(key) + } + byKey[key]!.plays.append(cp) + } + + let periods = orderedKeys.map { key -> CompactPeriod in + let v = byKey[key]! + return CompactPeriod(number: key.number, type: v.type, displayValue: v.displayValue, plays: v.plays) + } + + return CompactGame( + league: LeagueRef(key: league.key, sport: league.sport, league: league.league), + game: GameSummary( + id: game.id, + name: game.name, + shortName: game.shortName, + status: game.status, + statusDetail: game.statusDetail, + awayTeam: game.awayTeam, + homeTeam: game.homeTeam, + awayScore: game.awayScore, + homeScore: game.homeScore + ), + totalPlays: rawPlays.count, + athletes: athletes, + teams: teams, + periods: periods + ) + } + + /// Returns the last play ID across all periods (walking back-to-front). + static func lastCompactPlayId(_ game: CompactGame?) -> String? { + guard let game else { return nil } + for period in game.periods.reversed() { + if let last = period.plays.last { return last.id } + } + return nil + } + + /// Returns plays in `next` that appear after `lastId` in `next`'s own order. + /// If `lastId` is nil (cold start), all plays are considered new. + /// If `lastId` isn't found in `next`, all of `next`'s plays are considered new. + static func diffNewPlays(prev: CompactGame?, next: CompactGame) -> [CompactPlay] { + let allNext = next.periods.flatMap { $0.plays } + guard let lastId = lastCompactPlayId(prev) else { return allNext } + guard let idx = allNext.firstIndex(where: { $0.id == lastId }) else { return allNext } + return Array(allNext[allNext.index(after: idx)...]) + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift b/PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift new file mode 100644 index 00000000..9f380cba --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/ESPNClient.swift @@ -0,0 +1,29 @@ +import Foundation + +struct ESPNClient: Sendable { + let session: URLSession + + init(session: URLSession = .shared) { + self.session = session + } + + func fetchJSON(_ url: URL, as type: T.Type = T.self) async throws -> T { + let data: Data + let response: URLResponse + do { + (data, response) = try await session.data(from: url) + } catch { + throw error + } + + if let http = response as? HTTPURLResponse, !(200..<300).contains(http.statusCode) { + throw PlayByPlayError.http(status: http.statusCode, url: url) + } + + do { + return try JSONDecoder().decode(T.self, from: data) + } catch { + throw PlayByPlayError(decoding: error, context: url.absoluteString) + } + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift b/PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift new file mode 100644 index 00000000..d330f466 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/Helpers.swift @@ -0,0 +1,59 @@ +import Foundation + +public struct Coordinate: Hashable, Sendable, Codable { + public let x: Double? + public let y: Double? + public init(x: Double?, y: Double?) { + self.x = x + self.y = y + } +} + +public struct PitchCount: Hashable, Sendable, Codable { + public let balls: Int? + public let strikes: Int? + public init(balls: Int?, strikes: Int?) { + self.balls = balls + self.strikes = strikes + } +} + +public struct DriveMarker: Hashable, Sendable, Codable { + public let down: Int? + public let distance: Int? + public let yardLine: Int? + public let yardsToEndzone: Int? + public let downDistance: String? + public let possession: String? + public let teamId: String? +} + +public struct TeamParticipant: Hashable, Sendable, Codable { + public let teamId: String? + public let order: Int? + public let type: String? +} + +public struct FieldPosition: Hashable, Sendable, Codable { + public let x: Double? + public let y: Double? +} + +public struct GoalPosition: Hashable, Sendable, Codable { + public let x: Double? + public let y: Double? + public let z: Double? +} + +enum ESPNRef { + static func extractId(from url: String?) -> String? { + guard let url else { return nil } + guard let regex = try? NSRegularExpression(pattern: #"/(?:teams|athletes|positions)/(\d+)"#) else { return nil } + let range = NSRange(url.startIndex..., in: url) + guard let match = regex.firstMatch(in: url, range: range), match.numberOfRanges >= 2 else { + return nil + } + guard let r = Range(match.range(at: 1), in: url) else { return nil } + return String(url[r]) + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/League.swift b/PlayByPlayKit/Sources/PlayByPlayKit/League.swift new file mode 100644 index 00000000..f7a4574c --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/League.swift @@ -0,0 +1,45 @@ +import Foundation + +public struct League: Hashable, Sendable, Codable { + public let key: String + public let sport: String + public let league: String + public let displayName: String + + public init(key: String, sport: String, league: String, displayName: String) { + self.key = key + self.sport = sport + self.league = league + self.displayName = displayName + } +} + +public extension League { + static let all: [League] = [ + League(key: "mlb", sport: "baseball", league: "mlb", displayName: "MLB — Baseball"), + League(key: "nba", sport: "basketball", league: "nba", displayName: "NBA — Basketball"), + League(key: "wnba", sport: "basketball", league: "wnba", displayName: "WNBA — Basketball"), + League(key: "ncaam", sport: "basketball", league: "mens-college-basketball", displayName: "NCAAM — College Basketball"), + League(key: "ncaaw", sport: "basketball", league: "womens-college-basketball", displayName: "NCAAW — College Basketball"), + League(key: "nfl", sport: "football", league: "nfl", displayName: "NFL — Football"), + League(key: "ncaaf", sport: "football", league: "college-football", displayName: "NCAAF — College Football"), + League(key: "nhl", sport: "hockey", league: "nhl", displayName: "NHL — Hockey"), + League(key: "epl", sport: "soccer", league: "eng.1", displayName: "EPL — Soccer"), + League(key: "laliga", sport: "soccer", league: "esp.1", displayName: "La Liga — Soccer"), + League(key: "seriea", sport: "soccer", league: "ita.1", displayName: "Serie A — Soccer"), + League(key: "bundesliga", sport: "soccer", league: "ger.1", displayName: "Bundesliga — Soccer"), + League(key: "ligue1", sport: "soccer", league: "fra.1", displayName: "Ligue 1 — Soccer"), + League(key: "ucl", sport: "soccer", league: "uefa.champions", displayName: "UEFA Champions League — Soccer"), + League(key: "mls", sport: "soccer", league: "usa.1", displayName: "MLS — Soccer"), + ] +} + +enum ESPNEndpoints { + static func scoreboardURL(_ l: League) -> URL { + URL(string: "https://site.api.espn.com/apis/site/v2/sports/\(l.sport)/\(l.league)/scoreboard")! + } + + static func playByPlayURL(_ l: League, gameId: String, limit: Int = 1000) -> URL { + URL(string: "https://sports.core.api.espn.com/v2/sports/\(l.sport)/leagues/\(l.league)/events/\(gameId)/competitions/\(gameId)/plays?limit=\(limit)")! + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift b/PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift new file mode 100644 index 00000000..d1c90e28 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/LiveSession.swift @@ -0,0 +1,153 @@ +import Foundation + +public actor LiveSession { + private let league: League + private let game: Game + private let cacheDirectory: URL + private let pollInterval: TimeInterval + private let maxConsecutiveTransientFailures: Int + private let onTransientError: (@Sendable (Error) -> Void)? + private let client: ESPNClient + private let fetcher: PlaysFetcher + private let athleteCache = AthleteCache() + + private var state: CompactGame? + private var pollTask: Task? + private var continuation: AsyncThrowingStream.Continuation? + private var stream: AsyncThrowingStream? + private var consecutiveFailures: Int = 0 + private var started = false + + init( + league: League, + game: Game, + cacheDirectory: URL, + pollInterval: TimeInterval, + maxConsecutiveTransientFailures: Int, + onTransientError: (@Sendable (Error) -> Void)?, + session: URLSession + ) { + self.league = league + self.game = game + self.cacheDirectory = cacheDirectory + self.pollInterval = pollInterval + self.maxConsecutiveTransientFailures = maxConsecutiveTransientFailures + self.onTransientError = onTransientError + self.client = ESPNClient(session: session) + self.fetcher = PlaysFetcher(client: client) + } + + public nonisolated var deltas: AsyncThrowingStream { + get async { + await makeStreamIfNeeded() + } + } + + private func makeStreamIfNeeded() -> AsyncThrowingStream { + if let stream { return stream } + let (s, cont) = AsyncThrowingStream.makeStream() + self.stream = s + self.continuation = cont + cont.onTermination = { [weak self] _ in + Task { [weak self] in await self?.stop() } + } + return s + } + + public func currentState() -> CompactGame? { state } + + public func start() async { + guard !started else { return } + started = true + _ = makeStreamIfNeeded() + + // Seed from disk if present. + let url = SessionStorage.cacheFileURL( + root: cacheDirectory, + leagueKey: league.key, + shortName: game.shortName + ) + if let disk = try? SessionStorage.read(url) { + self.state = disk + await athleteCache.seed(disk.athletes) + } + + pollTask = Task { [weak self] in + await self?.pollLoop(cacheURL: url) + } + } + + public func stop() async { + pollTask?.cancel() + pollTask = nil + continuation?.finish() + continuation = nil + } + + private func pollLoop(cacheURL: URL) async { + while !Task.isCancelled { + await tickOnce(cacheURL: cacheURL) + if Task.isCancelled { return } + if pollTask == nil { return } + do { + try await cancellableSleep(pollInterval) + } catch { + return + } + } + } + + private func tickOnce(cacheURL: URL) async { + do { + let rawPlays = try await fetcher.fetchRawPlays(league: league, gameId: game.id) + await fetcher.resolveAthletes(for: rawPlays, cache: athleteCache) + let resolvedMap = await athleteCache.snapshot() + let newCompact = Compactor.compactGame( + league: league, + game: game, + rawPlays: rawPlays, + athleteMap: resolvedMap + ) + let newPlays = Compactor.diffNewPlays(prev: state, next: newCompact) + if !newPlays.isEmpty || state == nil { + state = newCompact + try SessionStorage.write(newCompact, to: cacheURL) + continuation?.yield(PlayDelta(newPlays: newPlays, state: newCompact)) + } + consecutiveFailures = 0 + } catch { + if isPermanent(error) { + continuation?.finish(throwing: error) + pollTask?.cancel() + pollTask = nil + return + } + consecutiveFailures += 1 + onTransientError?(error) + if consecutiveFailures >= maxConsecutiveTransientFailures { + continuation?.finish(throwing: error) + pollTask?.cancel() + pollTask = nil + } + } + } + + private func cancellableSleep(_ seconds: TimeInterval) async throws { + let nanos = UInt64(max(0, seconds) * 1_000_000_000) + try await Task.sleep(nanoseconds: nanos) + } + + private func isPermanent(_ error: Error) -> Bool { + if let e = error as? PlayByPlayError { + switch e { + case .http(let status, _): + return (400..<500).contains(status) + case .decoding, .invalidAthleteRef: + return true + case .io, .cancelled: + return false + } + } + return false + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/Models.swift b/PlayByPlayKit/Sources/PlayByPlayKit/Models.swift new file mode 100644 index 00000000..6446aad3 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/Models.swift @@ -0,0 +1,97 @@ +import Foundation + +public struct Game: Identifiable, Hashable, Sendable, Codable { + public let id: String + public let name: String + public let shortName: String + public let status: String + public let statusDetail: String + public let homeTeam: String + public let awayTeam: String + public let homeScore: String + public let awayScore: String + public let period: String + public let homeTeamId: String? + public let awayTeamId: String? + public let homeTeamAbbr: String? + public let awayTeamAbbr: String? +} + +public struct Athlete: Hashable, Sendable, Codable { + public let name: String + public let jersey: String? + public let position: String? +} + +public struct CompactParticipant: Hashable, Sendable, Codable { + public let athleteId: String? + public let type: String? + public let order: Int? +} + +public struct LeagueRef: Hashable, Sendable, Codable { + public let key: String + public let sport: String + public let league: String +} + +public struct GameSummary: Hashable, Sendable, Codable { + public let id: String + public let name: String + public let shortName: String + public let status: String + public let statusDetail: String + public let awayTeam: String + public let homeTeam: String + public let awayScore: String + public let homeScore: String +} + +public struct TeamRef: Hashable, Sendable, Codable { + public let name: String? + public let abbreviation: String? +} + +public struct CompactPlay: Identifiable, Hashable, Sendable, Codable { + public let id: String + public var seq: String? + public var type: String? + public var text: String? + public var awayScore: Int? + public var homeScore: Int? + public var clock: String? + public var scoringPlay: Bool? + public var scoreValue: Int? + public var wallclock: String? + public var teamId: String? + public var participants: [CompactParticipant]? + public var period: PeriodInfo? + public var sportFields: SportFields? +} + +public struct PeriodInfo: Hashable, Sendable, Codable { + public let number: Int + public let type: String? + public let displayValue: String? +} + +public struct CompactPeriod: Hashable, Sendable, Codable { + public let number: Int + public let type: String? + public let displayValue: String? + public let plays: [CompactPlay] +} + +public struct CompactGame: Hashable, Sendable, Codable { + public let league: LeagueRef + public let game: GameSummary + public let totalPlays: Int + public let athletes: [String: Athlete] + public let teams: [String: TeamRef] + public let periods: [CompactPeriod] +} + +public struct PlayDelta: Sendable { + public let newPlays: [CompactPlay] + public let state: CompactGame +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift b/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift new file mode 100644 index 00000000..8a1ecb0b --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlay.swift @@ -0,0 +1,41 @@ +import Foundation + +public enum PlayByPlay { + public static var leagues: [League] { League.all } + + public static func getLiveGames(_ league: League, session: URLSession = .shared) async throws -> [Game] { + let client = ESPNClient(session: session) + let response: ScoreboardResponse = try await client.fetchJSON(ESPNEndpoints.scoreboardURL(league)) + return Scoreboard.toGames(response) + } + + public static func getPlays(_ league: League, game: Game, session: URLSession = .shared) async throws -> CompactGame { + let client = ESPNClient(session: session) + let fetcher = PlaysFetcher(client: client) + let rawPlays = try await fetcher.fetchRawPlays(league: league, gameId: game.id) + let cache = AthleteCache() + await fetcher.resolveAthletes(for: rawPlays, cache: cache) + let map = await cache.snapshot() + return Compactor.compactGame(league: league, game: game, rawPlays: rawPlays, athleteMap: map) + } + + public static func liveSession( + league: League, + game: Game, + cacheDirectory: URL, + pollInterval: TimeInterval = 10, + maxConsecutiveTransientFailures: Int = 10, + onTransientError: (@Sendable (Error) -> Void)? = nil, + session: URLSession = .shared + ) -> LiveSession { + LiveSession( + league: league, + game: game, + cacheDirectory: cacheDirectory, + pollInterval: pollInterval, + maxConsecutiveTransientFailures: maxConsecutiveTransientFailures, + onTransientError: onTransientError, + session: session + ) + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift b/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift new file mode 100644 index 00000000..9a593314 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/PlayByPlayError.swift @@ -0,0 +1,30 @@ +import Foundation + +public enum PlayByPlayError: Error, Sendable { + case http(status: Int, url: URL) + case decoding(underlying: String, context: String) + case io(underlying: String) + case invalidAthleteRef(String) + case cancelled + + init(decoding error: Error, context: String) { + self = .decoding(underlying: String(describing: error), context: context) + } + + init(io error: Error) { + self = .io(underlying: String(describing: error)) + } +} + +extension PlayByPlayError: Equatable { + public static func == (lhs: PlayByPlayError, rhs: PlayByPlayError) -> Bool { + switch (lhs, rhs) { + case let (.http(a, b), .http(c, d)): return a == c && b == d + case let (.decoding(a, b), .decoding(c, d)): return a == c && b == d + case let (.io(a), .io(b)): return a == b + case let (.invalidAthleteRef(a), .invalidAthleteRef(b)): return a == b + case (.cancelled, .cancelled): return true + default: return false + } + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift b/PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift new file mode 100644 index 00000000..f581a895 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/PlaysFetcher.swift @@ -0,0 +1,104 @@ +import Foundation + +actor AthleteCache { + private var entries: [String: AthleteResponse] = [:] + + func get(_ url: String) -> AthleteResponse? { entries[url] } + + func set(_ url: String, _ value: AthleteResponse) { entries[url] = value } + + func has(_ url: String) -> Bool { entries[url] != nil } + + func snapshot() -> [String: AthleteResponse] { entries } + + func seed(_ athletes: [String: Athlete]) { + // Seed cache with already-known athletes so we don't refetch. + // Keyed by the original $ref URL, which we don't have here — + // so we key by athleteId URL shape that `extractId` recovers. + // Instead of reconstructing URLs, we just record the IDs as already-known; + // the fetcher filters its $ref list by ID when the map knows that ID. + for (id, a) in athletes { + // Use synthetic key "id:" so fetcher can check by ID. + entries["id:\(id)"] = AthleteResponse( + id: id, + displayName: a.name, + fullName: a.name, + jersey: a.jersey, + position: a.position.map { AthleteResponse.Position(abbreviation: $0, displayName: $0) } + ) + } + } + + func hasId(_ id: String) -> Bool { entries["id:\(id)"] != nil } + + func byId(_ id: String) -> AthleteResponse? { entries["id:\(id)"] } +} + +struct PlaysFetcher { + let client: ESPNClient + + init(client: ESPNClient = ESPNClient()) { + self.client = client + } + + func fetchRawPlays(league: League, gameId: String) async throws -> [RawPlay] { + let url = ESPNEndpoints.playByPlayURL(league, gameId: gameId) + let response: PlayByPlayResponse = try await client.fetchJSON(url) + return response.items ?? [] + } + + /// Resolve every athlete $ref into the cache. Concurrency bounded to `maxInFlight`. + func resolveAthletes(for plays: [RawPlay], cache: AthleteCache, maxInFlight: Int = 8) async { + var unique = Set() + for play in plays { + for p in play.participants ?? [] { + if let ref = p.athlete?.ref, !ref.isEmpty { + unique.insert(ref) + } + } + } + + var toFetch: [String] = [] + for ref in unique { + if await cache.has(ref) { continue } + if let id = ESPNRef.extractId(from: ref), await cache.hasId(id) { continue } + toFetch.append(ref) + } + + guard !toFetch.isEmpty else { return } + + await withTaskGroup(of: (String, AthleteResponse?).self) { group in + var index = 0 + var active = 0 + + func launchNext() { + guard index < toFetch.count else { return } + let ref = toFetch[index] + index += 1 + active += 1 + group.addTask { + guard let url = URL(string: ref) else { return (ref, nil) } + let response: AthleteResponse? = try? await self.client.fetchJSON(url) + return (ref, response) + } + } + + let initial = min(maxInFlight, toFetch.count) + for _ in 0.. [Game] { + (response.events ?? []).compactMap { event in + guard let comp = event.competitions.first, + let home = comp.competitors.first(where: { $0.homeAway == "home" }), + let away = comp.competitors.first(where: { $0.homeAway == "away" }) + else { return nil } + + return Game( + id: event.id, + name: event.name, + shortName: event.shortName, + status: comp.status.type.description, + statusDetail: comp.status.type.detail, + homeTeam: home.team.displayName, + awayTeam: away.team.displayName, + homeScore: home.score ?? "0", + awayScore: away.score ?? "0", + period: comp.status.type.detail, + homeTeamId: home.id, + awayTeamId: away.id, + homeTeamAbbr: home.team.abbreviation, + awayTeamAbbr: away.team.abbreviation + ) + } + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift b/PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift new file mode 100644 index 00000000..62e20bd3 --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/SessionStorage.swift @@ -0,0 +1,46 @@ +import Foundation + +enum SessionStorage { + static func cacheFileURL(root: URL, leagueKey: String, shortName: String, date: Date = Date()) -> URL { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd" + formatter.timeZone = TimeZone(identifier: "UTC") + let dateStr = formatter.string(from: date) + let sanitized = shortName.replacingOccurrences(of: " ", with: "_") + let leagueDir = root.appendingPathComponent(leagueKey, isDirectory: true) + return leagueDir.appendingPathComponent("\(sanitized)_\(dateStr).json") + } + + static func read(_ url: URL) throws -> CompactGame? { + guard FileManager.default.fileExists(atPath: url.path) else { return nil } + do { + let data = try Data(contentsOf: url) + return try JSONDecoder().decode(CompactGame.self, from: data) + } catch { + throw PlayByPlayError(io: error) + } + } + + static func write(_ game: CompactGame, to url: URL) throws { + do { + try FileManager.default.createDirectory( + at: url.deletingLastPathComponent(), + withIntermediateDirectories: true + ) + let encoder = JSONEncoder() + encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + let data = try encoder.encode(game) + + let tempURL = url.deletingLastPathComponent() + .appendingPathComponent(".\(url.lastPathComponent).tmp") + try data.write(to: tempURL, options: .atomic) + if FileManager.default.fileExists(atPath: url.path) { + _ = try FileManager.default.replaceItemAt(url, withItemAt: tempURL) + } else { + try FileManager.default.moveItem(at: tempURL, to: url) + } + } catch { + throw PlayByPlayError(io: error) + } + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift b/PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift new file mode 100644 index 00000000..94899f8a --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/SportCleaners.swift @@ -0,0 +1,106 @@ +import Foundation + +/// Sentinel values ESPN uses to indicate "no court position" on basketball plays. +private let basketballSentinelX: Double = -214748340 +private let basketballSentinelY: Double = -214748365 + +enum SportCleaners { + static func cleanBaseball(_ raw: RawPlay) -> BaseballFields { + var f = BaseballFields() + if let c = raw.pitchCoordinate { f.pitchCoordinate = Coordinate(x: c.x, y: c.y) } + if let t = raw.pitchType?.text { f.pitchType = t } + f.pitchVelocity = raw.pitchVelocity + if let c = raw.hitCoordinate { f.hitCoordinate = Coordinate(x: c.x, y: c.y) } + f.trajectory = raw.trajectory + f.atBatId = raw.atBatId + f.batOrder = raw.batOrder + f.atBatPitchNumber = raw.atBatPitchNumber + f.bats = raw.bats?.abbreviation + f.pitches = raw.pitches?.abbreviation + if let pc = raw.pitchCount { + f.pitchCount = PitchCount(balls: pc.balls, strikes: pc.strikes) + } + f.outs = raw.outs + f.rbiCount = raw.rbiCount + f.awayHits = raw.awayHits + f.homeHits = raw.homeHits + f.awayErrors = raw.awayErrors + f.homeErrors = raw.homeErrors + f.doublePlay = raw.doublePlay + f.triplePlay = raw.triplePlay + f.summaryType = raw.summaryType + return f + } + + static func cleanBasketball(_ raw: RawPlay) -> BasketballFields { + var f = BasketballFields() + if let c = raw.coordinate, c.x != basketballSentinelX, c.y != basketballSentinelY { + f.coordinate = Coordinate(x: c.x, y: c.y) + } + f.pointsAttempted = raw.pointsAttempted + f.shootingPlay = raw.shootingPlay + return f + } + + static func cleanFootball(_ raw: RawPlay) -> FootballFields { + var f = FootballFields() + f.start = driveMarker(raw.start) + f.end = driveMarker(raw.end) + f.statYardage = raw.statYardage + f.isTurnover = raw.isTurnover + if let tps = raw.teamParticipants, !tps.isEmpty { + f.teamParticipants = tps.map { tp in + TeamParticipant( + teamId: tp.id ?? ESPNRef.extractId(from: tp.team?.ref), + order: tp.order, + type: tp.type + ) + } + } + return f + } + + static func cleanHockey(_ raw: RawPlay) -> HockeyFields { + var f = HockeyFields() + f.strength = raw.strength?.text + f.isPenalty = raw.isPenalty + f.shootingPlay = raw.shootingPlay + return f + } + + static func cleanSoccer(_ raw: RawPlay) -> SoccerFields { + var f = SoccerFields() + f.redCard = raw.redCard + f.yellowCard = raw.yellowCard + f.penaltyKick = raw.penaltyKick + f.ownGoal = raw.ownGoal + f.shootout = raw.shootout + f.substitution = raw.substitution + f.addedClock = raw.addedClock?.value + if raw.fieldPositionX != nil || raw.fieldPositionY != nil { + f.fieldPosition = FieldPosition(x: raw.fieldPositionX, y: raw.fieldPositionY) + } + if raw.fieldPosition2X != nil || raw.fieldPosition2Y != nil { + f.fieldPosition2 = FieldPosition(x: raw.fieldPosition2X, y: raw.fieldPosition2Y) + } + if raw.goalPositionX != nil || raw.goalPositionY != nil || raw.goalPositionZ != nil { + f.goalPosition = GoalPosition(x: raw.goalPositionX, y: raw.goalPositionY, z: raw.goalPositionZ) + } + return f + } + + private static func driveMarker(_ m: RawDriveMarker?) -> DriveMarker? { + guard let m else { return nil } + let hasAny = m.down != nil || m.distance != nil || m.yardLine != nil || m.yardsToEndzone != nil || m.shortDownDistanceText != nil || m.possessionText != nil || m.team != nil + guard hasAny else { return nil } + return DriveMarker( + down: m.down, + distance: m.distance, + yardLine: m.yardLine, + yardsToEndzone: m.yardsToEndzone, + downDistance: m.shortDownDistanceText, + possession: m.possessionText, + teamId: ESPNRef.extractId(from: m.team?.ref) + ) + } +} diff --git a/PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift b/PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift new file mode 100644 index 00000000..8e0b31fa --- /dev/null +++ b/PlayByPlayKit/Sources/PlayByPlayKit/SportFields.swift @@ -0,0 +1,116 @@ +import Foundation + +public struct BaseballFields: Hashable, Sendable, Codable { + public var pitchCoordinate: Coordinate? + public var pitchType: String? + public var pitchVelocity: Double? + public var hitCoordinate: Coordinate? + public var trajectory: String? + public var atBatId: String? + public var batOrder: Int? + public var atBatPitchNumber: Int? + public var bats: String? + public var pitches: String? + public var pitchCount: PitchCount? + public var outs: Int? + public var rbiCount: Int? + public var awayHits: Int? + public var homeHits: Int? + public var awayErrors: Int? + public var homeErrors: Int? + public var doublePlay: Bool? + public var triplePlay: Bool? + public var summaryType: String? +} + +public struct BasketballFields: Hashable, Sendable, Codable { + public var coordinate: Coordinate? + public var pointsAttempted: Int? + public var shootingPlay: Bool? +} + +public struct FootballFields: Hashable, Sendable, Codable { + public var start: DriveMarker? + public var end: DriveMarker? + public var statYardage: Int? + public var isTurnover: Bool? + public var teamParticipants: [TeamParticipant]? +} + +public struct HockeyFields: Hashable, Sendable, Codable { + public var strength: String? + public var isPenalty: Bool? + public var shootingPlay: Bool? +} + +public struct SoccerFields: Hashable, Sendable, Codable { + public var redCard: Bool? + public var yellowCard: Bool? + public var penaltyKick: Bool? + public var ownGoal: Bool? + public var shootout: Bool? + public var substitution: Bool? + public var addedClock: Double? + public var fieldPosition: FieldPosition? + public var fieldPosition2: FieldPosition? + public var goalPosition: GoalPosition? +} + +public enum SportFields: Hashable, Sendable { + case baseball(BaseballFields) + case basketball(BasketballFields) + case football(FootballFields) + case hockey(HockeyFields) + case soccer(SoccerFields) +} + +extension SportFields: Codable { + private enum CodingKeys: String, CodingKey { + case sport + case data + } + + public func encode(to encoder: Encoder) throws { + var c = encoder.container(keyedBy: CodingKeys.self) + switch self { + case .baseball(let v): + try c.encode("baseball", forKey: .sport) + try c.encode(v, forKey: .data) + case .basketball(let v): + try c.encode("basketball", forKey: .sport) + try c.encode(v, forKey: .data) + case .football(let v): + try c.encode("football", forKey: .sport) + try c.encode(v, forKey: .data) + case .hockey(let v): + try c.encode("hockey", forKey: .sport) + try c.encode(v, forKey: .data) + case .soccer(let v): + try c.encode("soccer", forKey: .sport) + try c.encode(v, forKey: .data) + } + } + + public init(from decoder: Decoder) throws { + let c = try decoder.container(keyedBy: CodingKeys.self) + let sport = try c.decode(String.self, forKey: .sport) + switch sport { + case "baseball": + self = .baseball(try c.decode(BaseballFields.self, forKey: .data)) + case "basketball": + self = .basketball(try c.decode(BasketballFields.self, forKey: .data)) + case "football": + self = .football(try c.decode(FootballFields.self, forKey: .data)) + case "hockey": + self = .hockey(try c.decode(HockeyFields.self, forKey: .data)) + case "soccer": + self = .soccer(try c.decode(SoccerFields.self, forKey: .data)) + default: + throw DecodingError.dataCorruptedError( + forKey: .sport, + in: c, + debugDescription: "Unknown sport: \(sport)" + ) + } + } +} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift new file mode 100644 index 00000000..248de647 --- /dev/null +++ b/PlayByPlayKit/Tests/PlayByPlayKitTests/CompactorTests.swift @@ -0,0 +1,152 @@ +import XCTest +@testable import PlayByPlayKit + +final class CompactorTests: XCTestCase { + private func sampleGame() -> Game { + Game( + id: "g1", name: "A at B", shortName: "A @ B", + status: "In Progress", statusDetail: "Top 5th", + homeTeam: "B", awayTeam: "A", + homeScore: "2", awayScore: "1", + period: "Top 5th", + homeTeamId: "100", awayTeamId: "200", + homeTeamAbbr: "B", awayTeamAbbr: "A" + ) + } + + private let mlb = League(key: "mlb", sport: "baseball", league: "mlb", displayName: "MLB") + + private func rawPlays(_ json: String) throws -> [RawPlay] { + let data = json.data(using: .utf8)! + return try JSONDecoder().decode([RawPlay].self, from: data) + } + + func testCompactGroupsByPeriodInOrder() throws { + let plays = try rawPlays(""" + [ + {"id":"1","period":{"number":1,"type":"Top","displayValue":"Top 1st"}}, + {"id":"2","period":{"number":1,"type":"Bot","displayValue":"Bot 1st"}}, + {"id":"3","period":{"number":2,"type":"Top","displayValue":"Top 2nd"}}, + {"id":"4","period":{"number":2,"type":"Top","displayValue":"Top 2nd"}} + ] + """) + + let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) + + XCTAssertEqual(compact.totalPlays, 4) + XCTAssertEqual(compact.periods.count, 3) + XCTAssertEqual(compact.periods[0].plays.map { $0.id }, ["1"]) + XCTAssertEqual(compact.periods[1].plays.map { $0.id }, ["2"]) + XCTAssertEqual(compact.periods[2].plays.map { $0.id }, ["3", "4"]) + } + + func testCompactPopulatesTeams() throws { + let plays = try rawPlays("[]") + let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) + XCTAssertEqual(compact.teams["100"]?.name, "B") + XCTAssertEqual(compact.teams["200"]?.name, "A") + XCTAssertEqual(compact.teams["100"]?.abbreviation, "B") + } + + func testCompactPopulatesAthletesFromMap() throws { + let plays = try rawPlays(""" + [{"id":"1","participants":[{"athlete":{"$ref":"https://example.com/athletes/5?x=y"},"type":"batter"}]}] + """) + + let map: [String: AthleteResponse] = [ + "https://example.com/athletes/5?x=y": AthleteResponse( + id: "5", + displayName: "Jane Doe", + fullName: "Jane A Doe", + jersey: "42", + position: AthleteResponse.Position(abbreviation: "SS", displayName: "Shortstop") + ) + ] + + let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: map) + XCTAssertEqual(compact.athletes["5"]?.name, "Jane Doe") + XCTAssertEqual(compact.athletes["5"]?.jersey, "42") + XCTAssertEqual(compact.athletes["5"]?.position, "SS") + XCTAssertEqual(compact.periods.first?.plays.first?.participants?.first?.athleteId, "5") + } + + func testLastCompactPlayIdWalksBackward() throws { + let plays = try rawPlays(""" + [ + {"id":"1","period":{"number":1,"type":"Top"}}, + {"id":"2","period":{"number":2,"type":"Top"}} + ] + """) + let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) + XCTAssertEqual(Compactor.lastCompactPlayId(compact), "2") + XCTAssertNil(Compactor.lastCompactPlayId(nil)) + } + + func testDiffNewPlaysReturnsAllWhenNoPrev() throws { + let plays = try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"}]") + let compact = Compactor.compactGame(league: mlb, game: sampleGame(), rawPlays: plays, athleteMap: [:]) + let delta = Compactor.diffNewPlays(prev: nil, next: compact) + XCTAssertEqual(delta.map { $0.id }, ["1", "2"]) + } + + func testDiffNewPlaysFiltersBeforeLastId() throws { + let prev = Compactor.compactGame( + league: mlb, game: sampleGame(), + rawPlays: try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"}]"), + athleteMap: [:] + ) + let next = Compactor.compactGame( + league: mlb, game: sampleGame(), + rawPlays: try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"},{\"id\":\"3\"},{\"id\":\"4\"}]"), + athleteMap: [:] + ) + let delta = Compactor.diffNewPlays(prev: prev, next: next) + XCTAssertEqual(delta.map { $0.id }, ["3", "4"]) + } + + func testDiffNewPlaysReturnsAllWhenLastIdMissing() throws { + let prev = Compactor.compactGame( + league: mlb, game: sampleGame(), + rawPlays: try rawPlays("[{\"id\":\"X\"}]"), + athleteMap: [:] + ) + let next = Compactor.compactGame( + league: mlb, game: sampleGame(), + rawPlays: try rawPlays("[{\"id\":\"1\"},{\"id\":\"2\"}]"), + athleteMap: [:] + ) + let delta = Compactor.diffNewPlays(prev: prev, next: next) + XCTAssertEqual(delta.map { $0.id }, ["1", "2"]) + } + + func testSportFieldsEnumDispatchesCorrectly() throws { + let nba = League(key: "nba", sport: "basketball", league: "nba", displayName: "NBA") + let plays = try rawPlays("[{\"id\":\"1\",\"coordinate\":{\"x\":5,\"y\":5},\"pointsAttempted\":3}]") + let compact = Compactor.compactGame(league: nba, game: sampleGame(), rawPlays: plays, athleteMap: [:]) + let first = compact.periods.first?.plays.first + if case let .basketball(f) = first?.sportFields { + XCTAssertEqual(f.coordinate?.x, 5) + XCTAssertEqual(f.pointsAttempted, 3) + } else { + XCTFail("expected basketball sport fields") + } + } + + func testSportFieldsEnumRoundTrip() throws { + let nfl = League(key: "nfl", sport: "football", league: "nfl", displayName: "NFL") + let plays = try rawPlays("[{\"id\":\"1\",\"start\":{\"down\":1,\"distance\":10}}]") + let compact = Compactor.compactGame(league: nfl, game: sampleGame(), rawPlays: plays, athleteMap: [:]) + + let encoder = JSONEncoder() + encoder.outputFormatting = [.sortedKeys] + let data = try encoder.encode(compact) + let decoded = try JSONDecoder().decode(CompactGame.self, from: data) + + if case let .football(f) = decoded.periods.first?.plays.first?.sportFields { + XCTAssertEqual(f.start?.down, 1) + XCTAssertEqual(f.start?.distance, 10) + } else { + XCTFail("expected football on round-trip") + } + } +} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift new file mode 100644 index 00000000..868e0828 --- /dev/null +++ b/PlayByPlayKit/Tests/PlayByPlayKitTests/LeagueTests.swift @@ -0,0 +1,38 @@ +import XCTest +@testable import PlayByPlayKit + +final class LeagueTests: XCTestCase { + func testAllLeaguesCount() { + XCTAssertEqual(League.all.count, 15) + } + + func testMLBLeague() { + let mlb = League.all.first { $0.key == "mlb" } + XCTAssertNotNil(mlb) + XCTAssertEqual(mlb?.sport, "baseball") + XCTAssertEqual(mlb?.league, "mlb") + } + + func testScoreboardURL() { + let mlb = League.all.first { $0.key == "mlb" }! + XCTAssertEqual( + ESPNEndpoints.scoreboardURL(mlb).absoluteString, + "https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/scoreboard" + ) + } + + func testPlayByPlayURL() { + let epl = League.all.first { $0.key == "epl" }! + XCTAssertEqual( + ESPNEndpoints.playByPlayURL(epl, gameId: "12345").absoluteString, + "https://sports.core.api.espn.com/v2/sports/soccer/leagues/eng.1/events/12345/competitions/12345/plays?limit=1000" + ) + } + + func testExtractIdFromRef() { + XCTAssertEqual(ESPNRef.extractId(from: "https://example.com/v2/sports/x/athletes/33333?lang=en"), "33333") + XCTAssertEqual(ESPNRef.extractId(from: "/teams/17"), "17") + XCTAssertNil(ESPNRef.extractId(from: nil)) + XCTAssertNil(ESPNRef.extractId(from: "no-match-here")) + } +} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift new file mode 100644 index 00000000..4f7809ea --- /dev/null +++ b/PlayByPlayKit/Tests/PlayByPlayKitTests/LiveSessionTests.swift @@ -0,0 +1,197 @@ +import XCTest +@testable import PlayByPlayKit + +final class LiveSessionTests: XCTestCase { + private let mlb = League(key: "mlb", sport: "baseball", league: "mlb", displayName: "MLB") + + private func sampleGame() -> Game { + Game( + id: "401", + name: "A at B", shortName: "A @ B", + status: "In Progress", statusDetail: "Top 5th", + homeTeam: "B", awayTeam: "A", + homeScore: "0", awayScore: "0", + period: "Top 5th", + homeTeamId: "100", awayTeamId: "200", + homeTeamAbbr: "B", awayTeamAbbr: "A" + ) + } + + private func tempDir() -> URL { + let url = FileManager.default.temporaryDirectory + .appendingPathComponent("PlayByPlayKitTests-\(UUID().uuidString)", isDirectory: true) + try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true) + return url + } + + override func setUp() { + MockURLProtocol.reset() + } + + override func tearDown() { + MockURLProtocol.reset() + } + + private func playsResponse(_ ids: [String]) -> Data { + let items = ids.map { #"{"id":"\#($0)"}"# }.joined(separator: ",") + let json = #"{"items":[\#(items)]}"# + return json.data(using: .utf8)! + } + + func testColdStartEmitsInitialDelta() async throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + MockURLProtocol.handler = { url in + .init(statusCode: 200, body: self.playsResponse(["1", "2"])) + } + + let session = PlayByPlay.liveSession( + league: mlb, game: sampleGame(), + cacheDirectory: dir, + pollInterval: 3600, + session: MockURLProtocol.session() + ) + + let stream = await session.deltas + await session.start() + + var iter = stream.makeAsyncIterator() + let delta = try await iter.next() + XCTAssertNotNil(delta) + XCTAssertEqual(delta?.newPlays.map { $0.id }, ["1", "2"]) + XCTAssertEqual(delta?.state.totalPlays, 2) + + await session.stop() + } + + func testResumeSuppressesUnchangedPollThenEmitsNew() async throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + + var callCount = 0 + MockURLProtocol.handler = { url in + MockURLProtocol.lock.lock() + callCount += 1 + let c = callCount + MockURLProtocol.lock.unlock() + if c == 1 { + return .init(statusCode: 200, body: self.playsResponse(["1", "2"])) + } else { + return .init(statusCode: 200, body: self.playsResponse(["1", "2", "3"])) + } + } + + let session = PlayByPlay.liveSession( + league: mlb, game: sampleGame(), + cacheDirectory: dir, + pollInterval: 0.05, + session: MockURLProtocol.session() + ) + + let stream = await session.deltas + await session.start() + + var iter = stream.makeAsyncIterator() + + let first = try await iter.next() + XCTAssertEqual(first?.newPlays.map { $0.id }, ["1", "2"]) + + let second = try await iter.next() + XCTAssertEqual(second?.newPlays.map { $0.id }, ["3"]) + XCTAssertEqual(second?.state.totalPlays, 3) + + await session.stop() + } + + func testPermanentErrorThrowsIntoStream() async throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + + MockURLProtocol.handler = { _ in .init(statusCode: 404, body: Data()) } + + let session = PlayByPlay.liveSession( + league: mlb, game: sampleGame(), + cacheDirectory: dir, + pollInterval: 0.05, + session: MockURLProtocol.session() + ) + let stream = await session.deltas + await session.start() + + var iter = stream.makeAsyncIterator() + do { + _ = try await iter.next() + XCTFail("expected error") + } catch let error as PlayByPlayError { + if case .http(let status, _) = error { + XCTAssertEqual(status, 404) + } else { + XCTFail("expected .http(404)") + } + } + await session.stop() + } + + func testTransientErrorRetries() async throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + + var callCount = 0 + MockURLProtocol.handler = { _ in + MockURLProtocol.lock.lock() + callCount += 1 + let c = callCount + MockURLProtocol.lock.unlock() + if c == 1 { + return .init(statusCode: 503, body: Data()) + } + let json = #"{"items":[{"id":"1"}]}"# + return .init(statusCode: 200, body: json.data(using: .utf8)!) + } + + var transientCount = 0 + let lock = NSLock() + + let session = PlayByPlay.liveSession( + league: mlb, game: sampleGame(), + cacheDirectory: dir, + pollInterval: 0.05, + onTransientError: { _ in + lock.lock() + transientCount += 1 + lock.unlock() + }, + session: MockURLProtocol.session() + ) + let stream = await session.deltas + await session.start() + var iter = stream.makeAsyncIterator() + let delta = try await iter.next() + XCTAssertEqual(delta?.newPlays.map { $0.id }, ["1"]) + lock.lock() + XCTAssertEqual(transientCount, 1) + lock.unlock() + await session.stop() + } + + func testStopEndsStreamCleanly() async throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + MockURLProtocol.handler = { _ in + .init(statusCode: 200, body: self.playsResponse(["1"])) + } + let session = PlayByPlay.liveSession( + league: mlb, game: sampleGame(), + cacheDirectory: dir, + pollInterval: 3600, + session: MockURLProtocol.session() + ) + let stream = await session.deltas + await session.start() + var iter = stream.makeAsyncIterator() + _ = try await iter.next() + await session.stop() + let final = try await iter.next() + XCTAssertNil(final, "stream should terminate after stop()") + } +} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift new file mode 100644 index 00000000..9182c6dd --- /dev/null +++ b/PlayByPlayKit/Tests/PlayByPlayKitTests/MockURLProtocol.swift @@ -0,0 +1,56 @@ +import Foundation + +final class MockURLProtocol: URLProtocol, @unchecked Sendable { + struct Response { + let statusCode: Int + let body: Data + } + + static let lock = NSLock() + nonisolated(unsafe) static var handler: (@Sendable (URL) -> Response)? + nonisolated(unsafe) static var requestLog: [URL] = [] + + override class func canInit(with request: URLRequest) -> Bool { true } + override class func canonicalRequest(for request: URLRequest) -> URLRequest { request } + + override func startLoading() { + guard let url = request.url else { + client?.urlProtocol(self, didFailWithError: URLError(.badURL)) + return + } + MockURLProtocol.lock.lock() + MockURLProtocol.requestLog.append(url) + let handler = MockURLProtocol.handler + MockURLProtocol.lock.unlock() + + guard let handler else { + client?.urlProtocol(self, didFailWithError: URLError(.notConnectedToInternet)) + return + } + let response = handler(url) + let http = HTTPURLResponse( + url: url, + statusCode: response.statusCode, + httpVersion: "HTTP/1.1", + headerFields: ["Content-Type": "application/json"] + )! + client?.urlProtocol(self, didReceive: http, cacheStoragePolicy: .notAllowed) + client?.urlProtocol(self, didLoad: response.body) + client?.urlProtocolDidFinishLoading(self) + } + + override func stopLoading() {} + + static func reset() { + lock.lock() + defer { lock.unlock() } + handler = nil + requestLog = [] + } + + static func session() -> URLSession { + let config = URLSessionConfiguration.ephemeral + config.protocolClasses = [MockURLProtocol.self] + return URLSession(configuration: config) + } +} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift new file mode 100644 index 00000000..ef480273 --- /dev/null +++ b/PlayByPlayKit/Tests/PlayByPlayKitTests/ScoreboardTests.swift @@ -0,0 +1,60 @@ +import XCTest +@testable import PlayByPlayKit + +final class ScoreboardTests: XCTestCase { + func testDecodeAndToGames() throws { + let json = """ + { + "events": [ + { + "id": "401570000", + "name": "New York Yankees at Boston Red Sox", + "shortName": "NYY @ BOS", + "competitions": [ + { + "competitors": [ + { + "id": "10", + "homeAway": "home", + "score": "3", + "team": { "displayName": "Boston Red Sox", "abbreviation": "BOS" } + }, + { + "id": "9", + "homeAway": "away", + "score": "2", + "team": { "displayName": "New York Yankees", "abbreviation": "NYY" } + } + ], + "status": { + "type": { "description": "In Progress", "detail": "Top 7th" } + } + } + ] + } + ] + } + """.data(using: .utf8)! + + let response = try JSONDecoder().decode(ScoreboardResponse.self, from: json) + let games = Scoreboard.toGames(response) + XCTAssertEqual(games.count, 1) + let g = games[0] + XCTAssertEqual(g.id, "401570000") + XCTAssertEqual(g.homeTeam, "Boston Red Sox") + XCTAssertEqual(g.awayTeam, "New York Yankees") + XCTAssertEqual(g.homeScore, "3") + XCTAssertEqual(g.awayScore, "2") + XCTAssertEqual(g.homeTeamId, "10") + XCTAssertEqual(g.awayTeamId, "9") + XCTAssertEqual(g.homeTeamAbbr, "BOS") + XCTAssertEqual(g.status, "In Progress") + XCTAssertEqual(g.statusDetail, "Top 7th") + } + + func testEmptyScoreboard() throws { + let json = #"{"events":[]}"#.data(using: .utf8)! + let response = try JSONDecoder().decode(ScoreboardResponse.self, from: json) + XCTAssertEqual(Scoreboard.toGames(response).count, 0) + } +} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift new file mode 100644 index 00000000..0364ab36 --- /dev/null +++ b/PlayByPlayKit/Tests/PlayByPlayKitTests/SessionStorageTests.swift @@ -0,0 +1,95 @@ +import XCTest +@testable import PlayByPlayKit + +final class SessionStorageTests: XCTestCase { + private func tempDir() -> URL { + let url = FileManager.default.temporaryDirectory + .appendingPathComponent("PlayByPlayKitTests-\(UUID().uuidString)", isDirectory: true) + try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true) + return url + } + + private func makeCompact() -> CompactGame { + CompactGame( + league: LeagueRef(key: "mlb", sport: "baseball", league: "mlb"), + game: GameSummary( + id: "g1", name: "A at B", shortName: "A @ B", + status: "In Progress", statusDetail: "Top 5th", + awayTeam: "A", homeTeam: "B", awayScore: "1", homeScore: "2" + ), + totalPlays: 2, + athletes: ["5": Athlete(name: "Jane Doe", jersey: "42", position: "SS")], + teams: ["100": TeamRef(name: "B", abbreviation: "B")], + periods: [ + CompactPeriod( + number: 1, + type: "Top", + displayValue: "Top 1st", + plays: [ + CompactPlay(id: "p1"), + CompactPlay(id: "p2") + ] + ) + ] + ) + } + + func testCacheFileURLFormat() { + let root = URL(fileURLWithPath: "/tmp/root") + let date = ISO8601DateFormatter().date(from: "2026-04-19T10:00:00Z")! + let url = SessionStorage.cacheFileURL( + root: root, + leagueKey: "mlb", + shortName: "NYY @ BOS", + date: date + ) + XCTAssertEqual(url.path, "/tmp/root/mlb/NYY_@_BOS_2026-04-19.json") + } + + func testWriteReadRoundTrip() throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + + let compact = makeCompact() + let url = dir.appendingPathComponent("test.json") + try SessionStorage.write(compact, to: url) + + let loaded = try SessionStorage.read(url) + XCTAssertEqual(loaded, compact) + } + + func testReadReturnsNilWhenFileMissing() throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + let url = dir.appendingPathComponent("missing.json") + XCTAssertNil(try SessionStorage.read(url)) + } + + func testWriteCreatesIntermediateDirectories() throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + let url = dir.appendingPathComponent("mlb").appendingPathComponent("game.json") + try SessionStorage.write(makeCompact(), to: url) + XCTAssertTrue(FileManager.default.fileExists(atPath: url.path)) + } + + func testWriteOverwritesExistingFile() throws { + let dir = tempDir() + defer { try? FileManager.default.removeItem(at: dir) } + let url = dir.appendingPathComponent("game.json") + try SessionStorage.write(makeCompact(), to: url) + try SessionStorage.write(makeCompact(), to: url) // second write should succeed + XCTAssertNotNil(try SessionStorage.read(url)) + } +} + +extension CompactPlay { + init(id: String) { + self.init( + id: id, seq: nil, type: nil, text: nil, + awayScore: nil, homeScore: nil, clock: nil, + scoringPlay: nil, scoreValue: nil, wallclock: nil, + teamId: nil, participants: nil, period: nil, sportFields: nil + ) + } +} diff --git a/PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift b/PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift new file mode 100644 index 00000000..c047f060 --- /dev/null +++ b/PlayByPlayKit/Tests/PlayByPlayKitTests/SportCleanerTests.swift @@ -0,0 +1,125 @@ +import XCTest +@testable import PlayByPlayKit + +final class SportCleanerTests: XCTestCase { + func testBaseballCleanerPassesThroughFields() throws { + let json = """ + { + "id": "p1", + "pitchCoordinate": {"x": 1.0, "y": 2.0}, + "pitchType": {"text": "Fastball"}, + "pitchVelocity": 95.5, + "bats": {"abbreviation": "L"}, + "pitchCount": {"balls": 2, "strikes": 1}, + "outs": 1, + "doublePlay": true, + "homeHits": 5 + } + """.data(using: .utf8)! + let raw = try JSONDecoder().decode(RawPlay.self, from: json) + let f = SportCleaners.cleanBaseball(raw) + XCTAssertEqual(f.pitchCoordinate?.x, 1.0) + XCTAssertEqual(f.pitchType, "Fastball") + XCTAssertEqual(f.pitchVelocity, 95.5) + XCTAssertEqual(f.bats, "L") + XCTAssertEqual(f.pitchCount?.balls, 2) + XCTAssertEqual(f.pitchCount?.strikes, 1) + XCTAssertEqual(f.outs, 1) + XCTAssertEqual(f.doublePlay, true) + XCTAssertEqual(f.homeHits, 5) + } + + func testBasketballCleanerDropsSentinel() throws { + let json = """ + { + "id": "p2", + "coordinate": {"x": -214748340, "y": -214748365}, + "pointsAttempted": 3, + "shootingPlay": true + } + """.data(using: .utf8)! + let raw = try JSONDecoder().decode(RawPlay.self, from: json) + let f = SportCleaners.cleanBasketball(raw) + XCTAssertNil(f.coordinate, "sentinel coordinate must be dropped") + XCTAssertEqual(f.pointsAttempted, 3) + XCTAssertEqual(f.shootingPlay, true) + } + + func testBasketballCleanerKeepsRealCoordinate() throws { + let json = """ + {"id":"p3","coordinate":{"x":12.5,"y":-7.3}} + """.data(using: .utf8)! + let raw = try JSONDecoder().decode(RawPlay.self, from: json) + let f = SportCleaners.cleanBasketball(raw) + XCTAssertEqual(f.coordinate?.x, 12.5) + XCTAssertEqual(f.coordinate?.y, -7.3) + } + + func testFootballCleanerBuildsDriveMarkers() throws { + let json = """ + { + "id": "p4", + "start": { + "down": 3, + "distance": 7, + "yardLine": 45, + "yardsToEndzone": 55, + "team": {"$ref": "https://example.com/teams/17?lang=en"} + }, + "end": { + "down": 4, + "distance": 1, + "shortDownDistanceText": "4th & 1", + "possessionText": "NE 46" + }, + "statYardage": 6, + "teamParticipants": [ + {"id": "17", "order": 1, "type": "offense"} + ] + } + """.data(using: .utf8)! + let raw = try JSONDecoder().decode(RawPlay.self, from: json) + let f = SportCleaners.cleanFootball(raw) + XCTAssertEqual(f.start?.down, 3) + XCTAssertEqual(f.start?.distance, 7) + XCTAssertEqual(f.start?.teamId, "17") + XCTAssertEqual(f.end?.downDistance, "4th & 1") + XCTAssertEqual(f.end?.possession, "NE 46") + XCTAssertEqual(f.statYardage, 6) + XCTAssertEqual(f.teamParticipants?.first?.teamId, "17") + XCTAssertEqual(f.teamParticipants?.first?.order, 1) + } + + func testHockeyCleaner() throws { + let json = """ + {"id":"p5","strength":{"text":"Power Play"},"isPenalty":true,"shootingPlay":true} + """.data(using: .utf8)! + let raw = try JSONDecoder().decode(RawPlay.self, from: json) + let f = SportCleaners.cleanHockey(raw) + XCTAssertEqual(f.strength, "Power Play") + XCTAssertEqual(f.isPenalty, true) + XCTAssertEqual(f.shootingPlay, true) + } + + func testSoccerCleaner() throws { + let json = """ + { + "id": "p6", + "redCard": true, + "addedClock": {"value": 5.0}, + "fieldPositionX": 12.3, + "fieldPositionY": 45.6, + "goalPositionX": 1.0, + "goalPositionY": 2.0, + "goalPositionZ": 3.0 + } + """.data(using: .utf8)! + let raw = try JSONDecoder().decode(RawPlay.self, from: json) + let f = SportCleaners.cleanSoccer(raw) + XCTAssertEqual(f.redCard, true) + XCTAssertEqual(f.addedClock, 5.0) + XCTAssertEqual(f.fieldPosition?.x, 12.3) + XCTAssertEqual(f.fieldPosition?.y, 45.6) + XCTAssertEqual(f.goalPosition?.z, 3.0) + } +} diff --git a/project.yml b/project.yml index 2497a323..a1cc7b27 100644 --- a/project.yml +++ b/project.yml @@ -6,6 +6,10 @@ options: createIntermediateGroups: true generateEmptyDirectories: true +packages: + PlayByPlayKit: + path: PlayByPlayKit + settings: base: SWIFT_VERSION: "5.9" @@ -57,6 +61,8 @@ targets: embed: true codeSign: true optional: true + - package: PlayByPlayKit + product: PlayByPlayKit BroadcastBrainTests: type: bundle.unit-test From 9c91a7f5ccc5dfbdf7e92c7cf73ab9501916736e Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:14:25 -0700 Subject: [PATCH 07/18] fix: restore main's UI architecture; layer teammate's TeamSetupView/NewsTabView/News surface on top; light-mode setup screen with stronger dots + full coverage --- BroadcastBrain.xcodeproj/project.pbxproj | 4 + BroadcastBrain/ContentView.swift | 26 +- BroadcastBrain/Stores/AppStore.swift | 108 ++-- BroadcastBrain/Views/Components/Tokens.swift | 57 +- BroadcastBrain/Views/NewMatchSheet.swift | 240 ++++++++ BroadcastBrain/Views/SidebarView.swift | 587 +++++++++++++++++-- BroadcastBrain/Views/TeamSetupView.swift | 11 +- 7 files changed, 897 insertions(+), 136 deletions(-) create mode 100644 BroadcastBrain/Views/NewMatchSheet.swift diff --git a/BroadcastBrain.xcodeproj/project.pbxproj b/BroadcastBrain.xcodeproj/project.pbxproj index 42af6ba0..191d4a22 100644 --- a/BroadcastBrain.xcodeproj/project.pbxproj +++ b/BroadcastBrain.xcodeproj/project.pbxproj @@ -50,6 +50,7 @@ BBE476D5CF788B4125A50962 /* PlaysDBView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */; }; C072623647D8C5AF5C70080D /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = FBAB314A003AE79E3D7E3791 /* GeminiService.swift */; }; C2EC1CB5DC0D4914B540E12A /* Session.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF9FC0FE9D60DC37A1594C96 /* Session.swift */; }; + C418A911A2E29B77BEAEDAF8 /* NewMatchSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E714CFC5D1F7C7748D159C9D /* NewMatchSheet.swift */; }; C51482DD2F2F981AD8D640F5 /* SportradarBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46EAD55D55FDE50021FA38E3 /* SportradarBadge.swift */; }; CC3B9BF6F21086368795B456 /* TeamSetupView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1F0EA67AFC55CE71E2374 /* TeamSetupView.swift */; }; D2F4BB6524F4500D144AF80C /* CactusService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90AFD39809B3E0BE8DF8644B /* CactusService.swift */; }; @@ -136,6 +137,7 @@ E3CC277C30947157232CFF61 /* StatsFirstSpottingBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsFirstSpottingBoardView.swift; sourceTree = ""; }; E5059B3472C8B2022AC33356 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; E53DB1034B149B17293FE383 /* GlassSegmentedPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlassSegmentedPicker.swift; sourceTree = ""; }; + E714CFC5D1F7C7748D159C9D /* NewMatchSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewMatchSheet.swift; sourceTree = ""; }; EA68D7CA900438A10D7B4AC9 /* NewsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsService.swift; sourceTree = ""; }; EE877181D0D2EB6F44FCF490 /* ListeningDot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListeningDot.swift; sourceTree = ""; }; EF6CAC9075A33368706F52FE /* ThemeStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThemeStore.swift; sourceTree = ""; }; @@ -167,6 +169,7 @@ 8CC045EB8451818A6CD5A1ED /* ArchivesListView.swift */, 54D3D58CDEAD133FF9CB941E /* CommentatorStylePickerView.swift */, 01550DE4B92113B1173C6B2F /* LivePaneView.swift */, + E714CFC5D1F7C7748D159C9D /* NewMatchSheet.swift */, FE805D3AE864A2EC89074CF1 /* NewsTabView.swift */, F1762BD9961ECE5CAC332508 /* PlaysDBView.swift */, 721C2BA2DE9BCD5F29F526F0 /* PlaysSearchView.swift */, @@ -443,6 +446,7 @@ 4888A82003BDA03F00D954CD /* LivePill.swift in Sources */, 3689ED92510A4D081B6CBB1E /* MatchCache.swift in Sources */, E31D20151B71FBD3257BF1D8 /* MockResponder.swift in Sources */, + C418A911A2E29B77BEAEDAF8 /* NewMatchSheet.swift in Sources */, 06A1F33ECBAF18586AC02A37 /* NewsService.swift in Sources */, 4DD529CF07EB0CCAB762BEAF /* NewsTabView.swift in Sources */, 0CC48F247E683B3FB185A6FB /* PlayByPlayStore.swift in Sources */, diff --git a/BroadcastBrain/ContentView.swift b/BroadcastBrain/ContentView.swift index c4da1a02..801665a5 100644 --- a/BroadcastBrain/ContentView.swift +++ b/BroadcastBrain/ContentView.swift @@ -2,20 +2,30 @@ import SwiftUI struct ContentView: View { @Environment(AppStore.self) private var store + @Environment(ThemeStore.self) private var theme var body: some View { - ZStack { - NavigationSplitView { - SidebarView() - .navigationSplitViewColumnWidth(min: 220, ideal: 260) - } detail: { - detailView - } - .background(Color.bgBase) + @Bindable var bindable = store + Group { if store.showingSetup { TeamSetupView() .transition(.opacity) + } else { + HStack(spacing: 0) { + SidebarView() + .frame(width: theme.sidebarCollapsed ? 68 : 260) + + detailView + .frame(maxWidth: .infinity, maxHeight: .infinity) + } + .ignoresSafeArea(.container, edges: .top) + .background(Color.bgBase) + .animation(.easeInOut(duration: 0.2), value: theme.sidebarCollapsed) + .sheet(isPresented: $bindable.showNewMatchSheet) { + NewMatchSheet() + .environment(store) + } } } .animation(.easeInOut(duration: 0.2), value: store.showingSetup) diff --git a/BroadcastBrain/Stores/AppStore.swift b/BroadcastBrain/Stores/AppStore.swift index d7595ad0..7b136225 100644 --- a/BroadcastBrain/Stores/AppStore.swift +++ b/BroadcastBrain/Stores/AppStore.swift @@ -12,15 +12,17 @@ enum SpottingMode: String, CaseIterable, Identifiable { var label: String { switch self { - case .stats: return "STATS" - case .story: return "STORY" + case .stats: return "STATS" + case .story: return "STORY" case .tactical: return "TACTICAL" } } } enum LiveState: Equatable { - case idle, listening, processing + case idle + case listening + case processing case error(String) } @@ -32,31 +34,36 @@ final class AppStore { var liveState: LiveState = .idle var partialTranscript: String = "" var lastLatencyMs: Int? - var spottingMode: SpottingMode? = nil + /// When true the ContentView presents NewMatchSheet. Driven by the sidebar + /// `+ New Session` button. Dismissed on Cancel or Create. + var showNewMatchSheet: Bool = false + /// Shows TeamSetupView full-screen when true (first launch or user-triggered refresh). var showingSetup: Bool = false - private(set) var matchCache: MatchCache? + var spottingMode: SpottingMode? = nil let sessionStore: SessionStore let cactus: CactusService + var matchCache: MatchCache? let playByPlayStore: PlayByPlayStore - // Saved cache location — overrides bundled resource after first user fetch - private static let savedCacheURL: URL = FileManager.default - .urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] - .appendingPathComponent("BroadcastBrain/match_cache.json") - init(sessionStore: SessionStore, cactus: CactusService, playByPlayStore: PlayByPlayStore) { self.sessionStore = sessionStore self.cactus = cactus self.playByPlayStore = playByPlayStore - // Only user-saved cache counts — no bundled fallback, so first launch always - // forces the team setup screen for a tailored experience. - let initialCache = Self.loadSavedCache() - self.matchCache = initialCache + if let url = Bundle.main.url(forResource: "match_cache", withExtension: "json"), + let data = try? Data(contentsOf: url), + let cache = try? JSONDecoder().decode(MatchCache.self, from: data) { + self.matchCache = cache + } else { + self.matchCache = nil + } - let title = initialCache?.title ?? "New Match" + // Seed the default hackathon match so first launch has something live. + let seededMatch = Match.sampleArgFra2022 + let title = seededMatch.title + // Reuse an empty session for today's match if one already exists. let cal = Calendar.current if let reusable = sessionStore.sessions.first(where: { s in s.title == title @@ -68,35 +75,13 @@ final class AppStore { }) { self.currentSession = reusable } else { - let fresh = Session(title: title) + let fresh = Session(title: title, match: seededMatch) self.currentSession = fresh sessionStore.save(fresh) } + // Sweep any stray empty duplicate sessions (from pre-fix launches) sessionStore.purgeEmptyDuplicates(except: self.currentSession.id) - - // Show setup screen if there's no cache at all - if self.matchCache == nil { - self.showingSetup = true - } - } - - // Called by TeamSetupView after a successful fetch - func loadMatchCache(_ cache: MatchCache) { - matchCache = cache - spottingMode = nil - showingSetup = false - Self.persistCache(cache) - - // Start a fresh session for the new match - let fresh = Session(title: cache.title) - sessionStore.save(fresh) - currentSession = fresh - selectedSurface = .research - } - - func presentSetup() { - showingSetup = true } func appendStatCard(_ card: StatCard) { @@ -120,27 +105,48 @@ final class AppStore { sessionStore.save(currentSession) } + /// Triggered by the sidebar `+ New Session` button. Opens the match form. + /// The actual session is created when the user submits via `createSession(from:)`. func newSession() { - let title = matchCache?.title ?? "New Session" - let s = Session(title: title) + showNewMatchSheet = true + } + + /// Called from NewMatchSheet when the user taps Create. + func createSession(from match: Match) { + let s = Session(title: match.title, match: match) sessionStore.save(s) currentSession = s selectedArchiveId = nil selectedSurface = .live + showNewMatchSheet = false } - // MARK: - Cache persistence + /// Used by endMatch — reuses the current match for a fresh session without + /// asking the commentator to re-enter match details. + func newSessionKeepingCurrentMatch() { + let reusedMatch = currentSession.match ?? Match.sampleArgFra2022 + let s = Session(title: reusedMatch.title, match: reusedMatch) + sessionStore.save(s) + currentSession = s + selectedArchiveId = nil + selectedSurface = .live + } - private static func loadSavedCache() -> MatchCache? { - guard FileManager.default.fileExists(atPath: savedCacheURL.path), - let data = try? Data(contentsOf: savedCacheURL) else { return nil } - return try? JSONDecoder().decode(MatchCache.self, from: data) + /// Called by TeamSetupView after the fetch completes — swaps the in-memory + /// match cache and starts a fresh session for the new matchup. + func loadMatchCache(_ cache: MatchCache) { + matchCache = cache + showingSetup = false + + let fresh = Session(title: cache.title) + sessionStore.save(fresh) + currentSession = fresh + selectedArchiveId = nil + selectedSurface = .research } - private static func persistCache(_ cache: MatchCache) { - let dir = savedCacheURL.deletingLastPathComponent() - try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) - let enc = JSONEncoder(); enc.outputFormatting = [.prettyPrinted, .sortedKeys] - try? enc.encode(cache).write(to: savedCacheURL, options: .atomic) + /// Called by the sidebar "refresh" button to reopen the setup flow. + func presentSetup() { + showingSetup = true } } diff --git a/BroadcastBrain/Views/Components/Tokens.swift b/BroadcastBrain/Views/Components/Tokens.swift index 2a816465..28e2cc59 100644 --- a/BroadcastBrain/Views/Components/Tokens.swift +++ b/BroadcastBrain/Views/Components/Tokens.swift @@ -1,3 +1,4 @@ +import AppKit import SwiftUI extension Color { @@ -11,19 +12,49 @@ extension Color { self.init(red: r, green: g, blue: b) } - static let bgBase = Color(hex: "#050505") - static let bgRaised = Color(hex: "#0A0A0A") - static let bgSubtle = Color(hex: "#141414") - static let bgHover = Color(hex: "#171717") - static let bbBorder = Color(hex: "#262626") - static let borderSoft = Color(hex: "#1A1A1A") - static let textPrimary = Color(hex: "#FAFAFA") - static let textMuted = Color(hex: "#A3A3A3") - static let textSubtle = Color(hex: "#737373") - static let live = Color(hex: "#EF4444") - static let verified = Color(hex: "#10B981") - static let esoteric = Color(hex: "#F59E0B") - static let tactical = Color(hex: "#F97316") + /// A color that resolves at draw time based on the current NSAppearance. + /// Works with `.preferredColorScheme(...)` — when the app-level scheme flips, + /// NSAppearance flips with it and this color re-resolves. + static func themed(light lightHex: String, dark darkHex: String) -> Color { + let ns = NSColor(name: nil) { appearance in + let isDark = appearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua + return NSColor(hex: isDark ? darkHex : lightHex) + } + return Color(nsColor: ns) + } + + // ── Theme tokens ──────────────────────────────────────────────── + static let bgBase = Color.themed(light: "#F7F7F6", dark: "#050505") + static let bgRaised = Color.themed(light: "#FFFFFF", dark: "#0A0A0A") + static let bgSubtle = Color.themed(light: "#EFEFED", dark: "#141414") + static let bgHover = Color.themed(light: "#E6E6E3", dark: "#171717") + static let bbBorder = Color.themed(light: "#D4D4D3", dark: "#262626") + static let borderSoft = Color.themed(light: "#E5E5E4", dark: "#1A1A1A") + static let textPrimary = Color.themed(light: "#0A0A0A", dark: "#FAFAFA") + static let textMuted = Color.themed(light: "#525251", dark: "#A3A3A3") + static let textSubtle = Color.themed(light: "#8A8A89", dark: "#737373") + + // Strong edge used to separate the sidebar from the main content — inverts + // with theme so it's always visible: near-black in light mode, near-white in dark. + static let sidebarEdge = Color.themed(light: "#0A0A0A", dark: "#FAFAFA") + + // Semantic accents — same hue, slightly shifted for contrast in light mode. + static let live = Color.themed(light: "#DC2626", dark: "#EF4444") + static let verified = Color.themed(light: "#059669", dark: "#10B981") + static let esoteric = Color.themed(light: "#D97706", dark: "#F59E0B") + static let tactical = Color.themed(light: "#D97706", dark: "#F59E0B") +} + +extension NSColor { + fileprivate convenience init(hex: String) { + let s = hex.trimmingCharacters(in: .alphanumerics.inverted) + var v: UInt64 = 0 + Scanner(string: s).scanHexInt64(&v) + let r = CGFloat((v & 0xFF0000) >> 16) / 255 + let g = CGFloat((v & 0x00FF00) >> 8) / 255 + let b = CGFloat(v & 0x0000FF) / 255 + self.init(srgbRed: r, green: g, blue: b, alpha: 1) + } } enum Typography { diff --git a/BroadcastBrain/Views/NewMatchSheet.swift b/BroadcastBrain/Views/NewMatchSheet.swift new file mode 100644 index 00000000..ccd29b7e --- /dev/null +++ b/BroadcastBrain/Views/NewMatchSheet.swift @@ -0,0 +1,240 @@ +import SwiftUI + +/// Modal form presented when the commentator starts a new match session. +/// Captures sport, teams, tournament, and venue — saved as a `Match` on the +/// new `Session`. +struct NewMatchSheet: View { + @Environment(AppStore.self) private var store + @Environment(\.dismiss) private var dismiss + + @State private var sport: Sport = .soccer + @State private var homeTeam: String = "" + @State private var awayTeam: String = "" + @State private var tournament: String = "" + @State private var venue: String = "" + @State private var matchDate: Date = Date() + @State private var hasDate: Bool = false + + var body: some View { + VStack(spacing: 0) { + header + form + footer + } + .frame(width: 520) + .background(Color.bgRaised) + .overlay( + RoundedRectangle(cornerRadius: 10) + .stroke(Color.bbBorder, lineWidth: 1) + ) + .clipShape(RoundedRectangle(cornerRadius: 10)) + } + + private var header: some View { + HStack(spacing: 10) { + Image(systemName: "sparkles") + .font(.system(size: 14)) + .foregroundStyle(Color.live) + Text("NEW MATCH") + .font(Typography.sectionHead) + .foregroundStyle(Color.textPrimary) + .tracking(0.6) + Spacer() + Button(action: { store.showNewMatchSheet = false; dismiss() }) { + Image(systemName: "xmark") + .font(.system(size: 11, weight: .medium)) + .foregroundStyle(Color.textSubtle) + .padding(6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) + } + .buttonStyle(.plain) + } + .padding(.horizontal, 20) + .padding(.vertical, 16) + .background(Color.bgSubtle) + .overlay(alignment: .bottom) { + Rectangle().fill(Color.bbBorder).frame(height: 1) + } + } + + private var form: some View { + VStack(alignment: .leading, spacing: 18) { + field("SPORT") { + HStack(spacing: 6) { + ForEach(primarySports, id: \.self) { option in + sportPill(option) + } + Menu { + ForEach(Sport.allCases.filter { !primarySports.contains($0) }, id: \.self) { s in + Button(s.displayName) { sport = s } + } + } label: { + HStack(spacing: 4) { + Text(primarySports.contains(sport) ? "More" : sport.displayName.uppercased()) + .font(Typography.chip) + Image(systemName: "chevron.down") + .font(.system(size: 8)) + } + .foregroundStyle(!primarySports.contains(sport) ? Color.textPrimary : Color.textMuted) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(!primarySports.contains(sport) ? Color.live.opacity(0.12) : Color.bgSubtle, + in: Capsule()) + .overlay( + Capsule().stroke( + !primarySports.contains(sport) ? Color.live : Color.bbBorder, + lineWidth: 1 + ) + ) + } + .buttonStyle(.plain) + .menuStyle(.borderlessButton) + .menuIndicator(.hidden) + .fixedSize() + } + } + + HStack(spacing: 14) { + field("HOME TEAM") { + textField("Argentina", text: $homeTeam) + } + field("AWAY TEAM") { + textField("France", text: $awayTeam) + } + } + + field("TOURNAMENT") { + textField("2022 World Cup Final", text: $tournament) + } + + field("VENUE") { + textField("Lusail Stadium · Lusail, Qatar", text: $venue) + } + + field("MATCH DATE") { + HStack(spacing: 10) { + Toggle(isOn: $hasDate) { EmptyView() } + .toggleStyle(.switch) + .labelsHidden() + .controlSize(.small) + if hasDate { + DatePicker("", selection: $matchDate, displayedComponents: [.date]) + .labelsHidden() + .datePickerStyle(.compact) + } else { + Text("Not set") + .font(Typography.chip) + .foregroundStyle(Color.textSubtle) + } + Spacer() + } + } + } + .padding(20) + } + + private var footer: some View { + VStack(spacing: 8) { + Divider().background(Color.bbBorder) + HStack(spacing: 10) { + Button(action: { store.showNewMatchSheet = false; dismiss() }) { + Text("CANCEL") + .font(Typography.chip) + .tracking(0.6) + .foregroundStyle(Color.textMuted) + .frame(maxWidth: .infinity) + .padding(.vertical, 11) + .background(Color.bgSubtle) + .overlay(RoundedRectangle(cornerRadius: 5).stroke(Color.bbBorder, lineWidth: 1)) + .clipShape(RoundedRectangle(cornerRadius: 5)) + } + .buttonStyle(.plain) + + Button(action: submit) { + HStack(spacing: 8) { + Image(systemName: "arrow.right.circle.fill") + .font(.system(size: 12)) + Text("CREATE MATCH") + .font(Typography.chip) + .tracking(0.6) + } + .frame(maxWidth: .infinity) + .padding(.vertical, 11) + .foregroundStyle(Color.textPrimary) + .background(canSubmit ? Color.live : Color.bgHover) + .clipShape(RoundedRectangle(cornerRadius: 5)) + } + .buttonStyle(.plain) + .disabled(!canSubmit) + } + .padding(.horizontal, 20) + .padding(.vertical, 14) + } + .background(Color.bgSubtle) + } + + private var canSubmit: Bool { + !homeTeam.trimmingCharacters(in: .whitespaces).isEmpty + && !awayTeam.trimmingCharacters(in: .whitespaces).isEmpty + } + + private var primarySports: [Sport] { + [.soccer, .basketball, .baseball, .americanFootball, .hockey] + } + + @ViewBuilder + private func field(_ label: String, @ViewBuilder content: () -> Content) -> some View { + VStack(alignment: .leading, spacing: 6) { + Text(label) + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + .tracking(1.4) + content() + } + } + + private func textField(_ placeholder: String, text: Binding) -> some View { + TextField(placeholder, text: text) + .textFieldStyle(.plain) + .font(Typography.body) + .foregroundStyle(Color.textPrimary) + .padding(.horizontal, 10) + .padding(.vertical, 9) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + } + + private func sportPill(_ s: Sport) -> some View { + Button(action: { sport = s }) { + Text(s.displayName.uppercased()) + .font(Typography.chip) + .tracking(0.5) + .foregroundStyle(sport == s ? Color.textPrimary : Color.textMuted) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(sport == s ? Color.live.opacity(0.15) : Color.bgSubtle, + in: Capsule()) + .overlay( + Capsule().stroke( + sport == s ? Color.live : Color.bbBorder, + lineWidth: 1 + ) + ) + } + .buttonStyle(.plain) + } + + private func submit() { + guard canSubmit else { return } + let match = Match( + sport: sport, + homeTeam: homeTeam.trimmingCharacters(in: .whitespaces), + awayTeam: awayTeam.trimmingCharacters(in: .whitespaces), + tournament: tournament.trimmingCharacters(in: .whitespaces), + venue: venue.trimmingCharacters(in: .whitespaces), + matchDate: hasDate ? matchDate : nil + ) + store.createSession(from: match) + dismiss() + } +} diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index 36ea6ff8..14a47b69 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -2,91 +2,554 @@ import SwiftUI struct SidebarView: View { @Environment(AppStore.self) private var store + @Environment(ThemeStore.self) private var theme + @Namespace private var glassNamespace var body: some View { VStack(spacing: 0) { - List { - Section { - surfaceRow(title: "Live", systemImage: "dot.radiowaves.left.and.right", surface: .live) - surfaceRow(title: "Squads", systemImage: "person.2", surface: .squads) - surfaceRow(title: "Research", systemImage: "book", surface: .research) - surfaceRow(title: "News", systemImage: "newspaper", surface: .news) - surfaceRow(title: "Archive", systemImage: "archivebox", surface: .archive) - surfaceRow(title: "Plays", systemImage: "sportscourt", surface: .plays) - surfaceRow(title: "Plays DB", systemImage: "tray.full", surface: .playsDB) + BrandHeader(collapsed: theme.sidebarCollapsed) + + ScrollView { + VStack(spacing: theme.sidebarCollapsed ? 10 : 18) { + if !theme.sidebarCollapsed { + MatchContextCard( + title: store.currentSession.title, + isLive: store.liveState == .listening + ) + .padding(.horizontal, 12) + } + + VStack(alignment: .leading, spacing: 6) { + if !theme.sidebarCollapsed { + SectionLabel(text: "WORKSPACE") + .padding(.horizontal, 16) + } + + VStack(spacing: 2) { + surfaceRow(title: "Live", systemImage: "dot.radiowaves.left.and.right", surface: .live) + surfaceRow(title: "Squads", systemImage: "person.2.fill", surface: .squads) + surfaceRow(title: "Research", systemImage: "book.fill", surface: .research) + surfaceRow(title: "News", systemImage: "newspaper.fill", surface: .news) + surfaceRow(title: "Archive", systemImage: "archivebox.fill", surface: .archive) + surfaceRow(title: "Plays", systemImage: "sportscourt.fill", surface: .plays) + surfaceRow(title: "Plays DB", systemImage: "tray.full.fill", surface: .playsDB) + } + .padding(.horizontal, theme.sidebarCollapsed ? 8 : 8) + } } + .padding(.top, 14) + .padding(.bottom, 12) } - .listStyle(.sidebar) - .scrollContentBackground(.hidden) - .background(Color.bgBase) - Divider().background(Color.bbBorder) + Spacer(minLength: 0) + + NewSessionButton(collapsed: theme.sidebarCollapsed) { store.newSession() } + .padding(.horizontal, theme.sidebarCollapsed ? 10 : 12) + .padding(.top, 10) - Button(action: { store.presentSetup() }) { - HStack(spacing: 8) { - Image(systemName: "arrow.trianglehead.2.clockwise") - .foregroundStyle(Color.textMuted) - .font(.system(size: 12)) + SidebarFooterControls(collapsed: theme.sidebarCollapsed) + .padding(.horizontal, theme.sidebarCollapsed ? 10 : 12) + .padding(.top, 10) + .padding(.bottom, 12) + } + .background(Color.bgBase) + .overlay(alignment: .trailing) { + Rectangle() + .fill(Color.sidebarEdge) + .frame(width: 1) + } + } + + private func surfaceRow(title: String, systemImage: String, surface: Surface) -> some View { + let selected: Bool = { + if surface == .archive { + return store.selectedSurface == .archive + } + return store.selectedArchiveId == nil && store.selectedSurface == surface + }() + + let accessory: SidebarRowAccessory? = { + if surface == .live && store.liveState == .listening { return .livePill } + if surface == .archive && !store.sessionStore.sessions.isEmpty { + return .count(store.sessionStore.sessions.count) + } + return nil + }() + + return SidebarRow( + title: title, + systemImage: systemImage, + selected: selected, + accessory: accessory, + collapsed: theme.sidebarCollapsed, + glassNamespace: glassNamespace + ) { + withAnimation(.spring(response: 0.38, dampingFraction: 0.82)) { + store.selectedArchiveId = nil + store.selectedSurface = surface + } + } + } +} + +// MARK: - Brand header + +private struct BrandHeader: View { + let collapsed: Bool + @Environment(ThemeStore.self) private var theme + + var body: some View { + Group { + if collapsed { + VStack(spacing: 10) { + LogoMark() + .frame(width: 30, height: 30) + CollapseChevron(collapsed: true) { theme.toggleSidebar() } + } + } else { + HStack(spacing: 10) { + LogoMark() + .frame(width: 30, height: 30) VStack(alignment: .leading, spacing: 1) { - Text("NEW MATCH") - .font(Typography.chip) + Text("BROADCAST") + .font(.system(size: 11, weight: .bold, design: .monospaced)) + .tracking(1.6) + .foregroundStyle(Color.textPrimary) + Text("BRAIN") + .font(.system(size: 11, weight: .bold, design: .monospaced)) + .tracking(1.6) .foregroundStyle(Color.textPrimary) - if let title = store.matchCache?.title { - Text(title.components(separatedBy: " · ").first ?? title) - .font(.system(size: 9, design: .monospaced)) - .foregroundStyle(Color.textSubtle) - .lineLimit(1) - } } Spacer() + CollapseChevron(collapsed: false) { theme.toggleSidebar() } + } + } + } + .frame(maxWidth: .infinity, alignment: collapsed ? .center : .leading) + .padding(.horizontal, collapsed ? 0 : 16) + .padding(.top, 34) + .padding(.bottom, 14) + .overlay(alignment: .bottom) { + Rectangle().fill(Color.borderSoft).frame(height: 1) + } + } +} + +private struct CollapseChevron: View { + let collapsed: Bool + let action: () -> Void + @State private var hovering = false + + var body: some View { + Button(action: action) { + Image(systemName: collapsed ? "chevron.right" : "chevron.left") + .font(.system(size: 11, weight: .semibold)) + .foregroundStyle(hovering ? Color.textPrimary : Color.textSubtle) + .frame(width: 24, height: 24) + .background(hovering ? Color.bgSubtle : Color.clear, in: RoundedRectangle(cornerRadius: 4)) + } + .buttonStyle(.plain) + .onHover { hovering = $0 } + .help(collapsed ? "Expand sidebar" : "Collapse sidebar") + } +} + +private struct LogoMark: View { + var body: some View { + GeometryReader { geo in + let s = geo.size.width + let scale = s / 64 + ZStack { + RoundedRectangle(cornerRadius: 7).fill(Color.bgRaised) + RoundedRectangle(cornerRadius: 7).stroke(Color.bbBorder, lineWidth: 1) + Canvas { ctx, _ in + let bars: [(x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat, red: Bool)] = [ + (0, 0, 3, 32, false), + (7, 4, 3, 10, false), + (14, 2, 3, 14, false), + (21, 6, 3, 6, true), + (28, 3, 3, 12, false), + (7, 18, 3, 10, false), + (14, 16, 3, 14, false), + (21, 20, 3, 6, false), + (28, 17, 3, 12, false), + ] + for b in bars { + let rect = CGRect( + x: (16 + b.x) * scale, + y: (16 + b.y) * scale, + width: b.w * scale, + height: b.h * scale + ) + ctx.fill( + Path(rect), + with: .color(b.red ? Color.live : Color.textPrimary) + ) + } } - .padding(12) } - .buttonStyle(.plain) - .background(Color.bgBase) - - Button(action: { store.newSession() }) { - HStack { - Image(systemName: "plus.circle") - .foregroundStyle(Color.textMuted) - Text("New Session") + } + } +} + +// MARK: - Match context card + +private struct MatchContextCard: View { + let title: String + let isLive: Bool + + private var parts: (home: String, away: String, subtitle: String) { + let pieces = title.components(separatedBy: " · ") + let matchup = pieces.first ?? title + let sub = pieces.dropFirst().joined(separator: " · ") + let teams = matchup.components(separatedBy: " vs ") + let home = teams.first.map(abbrev) ?? "—" + let away = teams.dropFirst().first.map(abbrev) ?? "—" + return (home, away, sub.isEmpty ? "TODAY" : sub.uppercased()) + } + + private func abbrev(_ country: String) -> String { + let cleaned = country.trimmingCharacters(in: .whitespaces) + return String(cleaned.prefix(3)).uppercased() + } + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + HStack(spacing: 6) { + Text("CURRENT MATCH") + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .tracking(1.6) + .foregroundStyle(Color.textSubtle) + Spacer() + if isLive { + Circle() + .fill(Color.live) + .frame(width: 6, height: 6) + } + } + + HStack(alignment: .firstTextBaseline, spacing: 6) { + Text(parts.home) + .font(.system(size: 15, weight: .bold, design: .monospaced)) + .tracking(0.5) + .foregroundStyle(Color.textPrimary) + Text("vs") + .font(.system(size: 10, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + Text(parts.away) + .font(.system(size: 15, weight: .bold, design: .monospaced)) + .tracking(0.5) + .foregroundStyle(Color.textPrimary) + Spacer() + } + + Text(parts.subtitle) + .font(.system(size: 9, weight: .medium, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(Color.textMuted) + .lineLimit(1) + } + .padding(.horizontal, 12) + .padding(.vertical, 12) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) + .overlay( + RoundedRectangle(cornerRadius: 6).stroke(Color.borderSoft, lineWidth: 1) + ) + } +} + +// MARK: - Section label + +private struct SectionLabel: View { + let text: String + var body: some View { + Text(text) + .font(.system(size: 9, weight: .semibold, design: .monospaced)) + .tracking(1.8) + .foregroundStyle(Color.textSubtle) + } +} + +// MARK: - Sidebar row + +private enum SidebarRowAccessory: Equatable { + case livePill + case count(Int) +} + +private struct SidebarRow: View { + let title: String + let systemImage: String + let selected: Bool + let accessory: SidebarRowAccessory? + let collapsed: Bool + let glassNamespace: Namespace.ID + let action: () -> Void + + @State private var hovering = false + + var body: some View { + Button(action: action) { + HStack(spacing: collapsed ? 0 : 10) { + if !collapsed { + Image(systemName: systemImage) + .font(.system(size: 13)) + .foregroundStyle(selected ? Color.textPrimary : Color.textMuted) + .frame(width: 18) + + Text(title) .font(Typography.body) - .foregroundStyle(Color.textPrimary) + .foregroundStyle(selected ? Color.textPrimary : Color.textMuted) + Spacer() + + accessoryView + + } else { + ZStack { + Image(systemName: systemImage) + .font(.system(size: 15)) + .foregroundStyle(selected ? Color.textPrimary : Color.textMuted) + + // Collapsed: represent the accessory as a compact dot/dot+count. + if case .livePill = accessory { + Circle() + .fill(Color.live) + .frame(width: 6, height: 6) + .overlay(Circle().stroke(Color.bgBase, lineWidth: 1.5)) + .offset(x: 10, y: -10) + } + } + .frame(maxWidth: .infinity) } - .padding(12) } - .buttonStyle(.plain) - .background(Color.bgBase) + .padding(.horizontal, collapsed ? 0 : 10) + .padding(.vertical, collapsed ? 10 : 8) + .frame(maxWidth: .infinity) + .background(rowBackground) + .overlay(alignment: .leading) { + if selected { + Rectangle() + .fill(Color.live) + .frame(width: 2) + .padding(.vertical, 6) + } + } + .contentShape(Rectangle()) } - .background(Color.bgBase) + .buttonStyle(.plain) + .onHover { hovering = $0 } + .help(collapsed ? title : "") } - private func surfaceRow(title: String, systemImage: String, surface: Surface) -> some View { - // Archive surface is "selected" whenever the user has navigated there, - // regardless of whether they're looking at the list or a specific session. - let selected: Bool = { - if surface == .archive { - return store.selectedSurface == .archive + @ViewBuilder + private var rowBackground: some View { + if selected { + LiquidGlassBackground(intensity: 1.0) + .matchedGeometryEffect(id: "sidebar.selection.glass", in: glassNamespace) + } else if hovering { + LiquidGlassBackground(intensity: 0.45) + } else { + Color.clear + } + } + + @ViewBuilder + private var accessoryView: some View { + switch accessory { + case .livePill: + LivePill() + case .count(let n): + Text("\(n)") + .font(.system(size: 10, weight: .semibold, design: .monospaced)) + .foregroundStyle(Color.textSubtle) + .padding(.horizontal, 6) + .padding(.vertical, 2) + .background(Color.bgRaised, in: RoundedRectangle(cornerRadius: 3)) + .overlay( + RoundedRectangle(cornerRadius: 3).stroke(Color.borderSoft, lineWidth: 1) + ) + case .none: + EmptyView() + } + } +} + +// MARK: - Liquid glass selection background + +/// Frosted, translucent "liquid glass" treatment for the sidebar selection / +/// hover highlight. Uses `.regularMaterial` for the frost, a top-bright sheen +/// gradient for the wet-glass feel, and a gradient rim stroke for the edge +/// highlight. `intensity` scales the sheen + stroke + shadow so the same +/// primitive renders both the strong selected state and a lighter hover state. +private struct LiquidGlassBackground: View { + let intensity: Double + + private let corner: CGFloat = 8 + + var body: some View { + ZStack { + RoundedRectangle(cornerRadius: corner, style: .continuous) + .fill(.regularMaterial) + + RoundedRectangle(cornerRadius: corner, style: .continuous) + .fill( + LinearGradient( + colors: [ + Color.primary.opacity(0.10 * intensity), + Color.primary.opacity(0.02 * intensity), + Color.clear + ], + startPoint: .top, + endPoint: .bottom + ) + ) + + RoundedRectangle(cornerRadius: corner, style: .continuous) + .strokeBorder( + LinearGradient( + colors: [ + Color.primary.opacity(0.22 * intensity), + Color.primary.opacity(0.05 * intensity) + ], + startPoint: .top, + endPoint: .bottom + ), + lineWidth: 0.6 + ) + } + .shadow(color: Color.black.opacity(0.14 * intensity), radius: 5, y: 2) + } +} + +// MARK: - New Session button + +private struct NewSessionButton: View { + let collapsed: Bool + let action: () -> Void + @State private var hovering = false + + var body: some View { + Button(action: action) { + HStack(spacing: collapsed ? 0 : 8) { + Image(systemName: "plus") + .font(.system(size: collapsed ? 14 : 11, weight: .bold)) + .foregroundStyle(hovering ? Color.textPrimary : Color.textMuted) + if !collapsed { + Text("NEW SESSION") + .font(.system(size: 10, weight: .bold, design: .monospaced)) + .tracking(1.6) + .foregroundStyle(hovering ? Color.textPrimary : Color.textMuted) + Spacer() + } } - return store.selectedArchiveId == nil && store.selectedSurface == surface - }() + .padding(.horizontal, collapsed ? 0 : 12) + .padding(.vertical, collapsed ? 10 : 10) + .frame(maxWidth: .infinity) + .background(hovering ? Color.bgSubtle : Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) + .overlay( + RoundedRectangle(cornerRadius: 6) + .stroke(hovering ? Color.bbBorder : Color.borderSoft, lineWidth: 1) + ) + } + .buttonStyle(.plain) + .onHover { hovering = $0 } + .help(collapsed ? "New session" : "") + } +} + +// MARK: - Footer controls (theme toggle + collapse toggle + status) + +private struct SidebarFooterControls: View { + let collapsed: Bool + @Environment(ThemeStore.self) private var theme + + var body: some View { + VStack(spacing: 8) { + if collapsed { + IconButton(systemImage: theme.mode == .dark ? "sun.max" : "moon", + help: theme.mode == .dark ? "Light mode" : "Dark mode") { + theme.toggleMode() + } + IconButton(systemImage: "sidebar.left", help: "Expand sidebar") { + theme.toggleSidebar() + } + } else { + FooterPillButton( + systemImage: theme.mode == .dark ? "sun.max" : "moon", + label: theme.mode == .dark ? "LIGHT MODE" : "DARK MODE" + ) { + theme.toggleMode() + } + } + } + } +} + +private struct FooterPillButton: View { + let systemImage: String + let label: String + let action: () -> Void + @State private var hovering = false + + var body: some View { + Button(action: action) { + HStack(spacing: 6) { + Image(systemName: systemImage) + .font(.system(size: 10, weight: .semibold)) + .foregroundStyle(hovering ? Color.textPrimary : Color.textMuted) + Text(label) + .font(.system(size: 9, weight: .bold, design: .monospaced)) + .tracking(1.4) + .foregroundStyle(hovering ? Color.textPrimary : Color.textMuted) + } + .padding(.horizontal, 10) + .padding(.vertical, 6) + .frame(maxWidth: .infinity) + .background(hovering ? Color.bgSubtle : Color.bgRaised, in: RoundedRectangle(cornerRadius: 5)) + .overlay( + RoundedRectangle(cornerRadius: 5) + .stroke(Color.borderSoft, lineWidth: 1) + ) + } + .buttonStyle(.plain) + .onHover { hovering = $0 } + } +} + +private struct IconButton: View { + let systemImage: String + let help: String + let action: () -> Void + @State private var hovering = false - return HStack { + var body: some View { + Button(action: action) { Image(systemName: systemImage) - .foregroundStyle(selected ? Color.live : Color.textMuted) - .frame(width: 18) - Text(title) - .font(Typography.body) - .foregroundStyle(Color.textPrimary) - Spacer() - if selected && surface == .live && store.liveState == .listening { LivePill() } - } - .padding(.vertical, 4) - .contentShape(Rectangle()) - .onTapGesture { - store.selectedArchiveId = nil - store.selectedSurface = surface + .font(.system(size: 13, weight: .semibold)) + .foregroundStyle(hovering ? Color.textPrimary : Color.textMuted) + .frame(width: 36, height: 36) + .background(hovering ? Color.bgSubtle : Color.bgRaised, in: RoundedRectangle(cornerRadius: 6)) + .overlay( + RoundedRectangle(cornerRadius: 6).stroke(Color.borderSoft, lineWidth: 1) + ) + } + .buttonStyle(.plain) + .onHover { hovering = $0 } + .help(help) + } +} + +private struct StatusDot: View { + let label: String + let color: Color + var body: some View { + HStack(spacing: 5) { + Circle().fill(color).frame(width: 5, height: 5) + Text(label) + .font(.system(size: 8, weight: .semibold, design: .monospaced)) + .tracking(1.2) + .foregroundStyle(Color.textSubtle) } } } diff --git a/BroadcastBrain/Views/TeamSetupView.swift b/BroadcastBrain/Views/TeamSetupView.swift index c9484604..cc742fba 100644 --- a/BroadcastBrain/Views/TeamSetupView.swift +++ b/BroadcastBrain/Views/TeamSetupView.swift @@ -10,8 +10,14 @@ struct TeamSetupView: View { var body: some View { ZStack { - Color.bgBase.ignoresSafeArea() - DottedGrid() + Color(hex: "#F7F7F6").ignoresSafeArea() + + DottedGrid( + dotColor: Color(hex: "#0A0A0A").opacity(0.22), + spacing: 22, + dotSize: 2.2 + ) + .ignoresSafeArea() VStack(spacing: 0) { Spacer() @@ -20,6 +26,7 @@ struct TeamSetupView: View { } .padding(40) } + .preferredColorScheme(.light) } private var card: some View { From 8d1c3c24ce506a4080186525612592a71bbc4e45 Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:34:21 -0700 Subject: [PATCH 08/18] style: align sidebar BrandHeader and page StatusBarView to matching 72pt height --- BroadcastBrain/Views/Components/StatusBarView.swift | 3 ++- BroadcastBrain/Views/SidebarView.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/BroadcastBrain/Views/Components/StatusBarView.swift b/BroadcastBrain/Views/Components/StatusBarView.swift index 22efd925..a9163092 100644 --- a/BroadcastBrain/Views/Components/StatusBarView.swift +++ b/BroadcastBrain/Views/Components/StatusBarView.swift @@ -22,7 +22,8 @@ struct StatusBarView: View { } .padding(.horizontal, 16) .padding(.top, 34) - .padding(.bottom, 12) + .padding(.bottom, 14) + .frame(height: 72, alignment: .bottom) .background(Color.bgRaised) .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index 14a47b69..11e89b83 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -128,7 +128,8 @@ private struct BrandHeader: View { .frame(maxWidth: .infinity, alignment: collapsed ? .center : .leading) .padding(.horizontal, collapsed ? 0 : 16) .padding(.top, 34) - .padding(.bottom, 14) + .padding(.bottom, 8) + .frame(height: 72, alignment: .bottom) .overlay(alignment: .bottom) { Rectangle().fill(Color.borderSoft).frame(height: 1) } From 9fc709d7bbe1046aacb4bb6508f0abf6ed109beb Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:41:37 -0700 Subject: [PATCH 09/18] style(research): add DottedGrid behind CommentatorStylePickerView --- BroadcastBrain/Views/ResearchCenterView.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/BroadcastBrain/Views/ResearchCenterView.swift b/BroadcastBrain/Views/ResearchCenterView.swift index ce6fd336..da6a694b 100644 --- a/BroadcastBrain/Views/ResearchCenterView.swift +++ b/BroadcastBrain/Views/ResearchCenterView.swift @@ -40,6 +40,7 @@ struct ResearchCenterView: View { if store.spottingMode == nil { ZStack { Color.bgBase + DottedGrid() CommentatorStylePickerView() } } else if store.spottingMode == .stats { From 328ec84468b952450d19471560c2ec8ce180019a Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:43:05 -0700 Subject: [PATCH 10/18] fix(research): remove duplicate StatusBarView from Stats/Story/Tactical boards --- BroadcastBrain/Views/StatsFirstSpottingBoardView.swift | 5 ----- BroadcastBrain/Views/StoryFirstSpottingBoardView.swift | 5 ----- BroadcastBrain/Views/TacticalSpottingBoardView.swift | 5 ----- 3 files changed, 15 deletions(-) diff --git a/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift b/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift index 94fc29a5..851620f5 100644 --- a/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift +++ b/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift @@ -18,11 +18,6 @@ struct StatsFirstSpottingBoardView: View { var body: some View { VStack(spacing: 0) { - StatusBarView( - matchTitle: store.currentSession.title, - isAirplane: true, - latencyMs: store.lastLatencyMs - ) subHeader ZStack { DottedGrid() diff --git a/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift b/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift index fa49129f..570f3625 100644 --- a/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift +++ b/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift @@ -16,11 +16,6 @@ struct StoryFirstSpottingBoardView: View { var body: some View { VStack(spacing: 0) { - StatusBarView( - matchTitle: store.currentSession.title, - isAirplane: true, - latencyMs: store.lastLatencyMs - ) subHeader ZStack { DottedGrid() diff --git a/BroadcastBrain/Views/TacticalSpottingBoardView.swift b/BroadcastBrain/Views/TacticalSpottingBoardView.swift index 0e5b4955..fd986f19 100644 --- a/BroadcastBrain/Views/TacticalSpottingBoardView.swift +++ b/BroadcastBrain/Views/TacticalSpottingBoardView.swift @@ -22,11 +22,6 @@ struct TacticalSpottingBoardView: View { var body: some View { VStack(spacing: 0) { - StatusBarView( - matchTitle: store.currentSession.title, - isAirplane: true, - latencyMs: store.lastLatencyMs - ) subHeader ZStack { DottedGrid() From e6f0ffb62ae8828857e9bcfd392834ede22fc075 Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:47:39 -0700 Subject: [PATCH 11/18] style(research): stronger dots on empty-state background (2.4pt, 22pt spacing, 28% opacity) --- BroadcastBrain/Views/ResearchCenterView.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/BroadcastBrain/Views/ResearchCenterView.swift b/BroadcastBrain/Views/ResearchCenterView.swift index da6a694b..cdcb683d 100644 --- a/BroadcastBrain/Views/ResearchCenterView.swift +++ b/BroadcastBrain/Views/ResearchCenterView.swift @@ -40,7 +40,11 @@ struct ResearchCenterView: View { if store.spottingMode == nil { ZStack { Color.bgBase - DottedGrid() + DottedGrid( + dotColor: Color.textPrimary.opacity(0.28), + spacing: 22, + dotSize: 2.4 + ) CommentatorStylePickerView() } } else if store.spottingMode == .stats { From b3ef13648c3dc227bab117efbde128269047597f Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:51:37 -0700 Subject: [PATCH 12/18] fix(research): remove CASES; MY STYLE becomes standalone back pill; NOTES now lives in StatusBar trailing slot (no overlap with LIVE) --- .../Views/Components/StatusBarView.swift | 13 +++++- BroadcastBrain/Views/ResearchCenterView.swift | 13 +++--- .../Views/StatsFirstSpottingBoardView.swift | 41 ++++++++----------- .../Views/StoryFirstSpottingBoardView.swift | 32 +++++++-------- .../Views/TacticalSpottingBoardView.swift | 29 +++++++------ 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/BroadcastBrain/Views/Components/StatusBarView.swift b/BroadcastBrain/Views/Components/StatusBarView.swift index a9163092..f3793a83 100644 --- a/BroadcastBrain/Views/Components/StatusBarView.swift +++ b/BroadcastBrain/Views/Components/StatusBarView.swift @@ -1,9 +1,10 @@ import SwiftUI -struct StatusBarView: View { +struct StatusBarView: View { let matchTitle: String let isAirplane: Bool let latencyMs: Int? + @ViewBuilder let trailing: () -> Trailing var body: some View { HStack(spacing: 12) { @@ -19,6 +20,7 @@ struct StatusBarView: View { LatencyTag(ms: ms) } LivePill() + trailing() } .padding(.horizontal, 16) .padding(.top, 34) @@ -30,3 +32,12 @@ struct StatusBarView: View { } } } + +extension StatusBarView where Trailing == EmptyView { + init(matchTitle: String, isAirplane: Bool, latencyMs: Int?) { + self.matchTitle = matchTitle + self.isAirplane = isAirplane + self.latencyMs = latencyMs + self.trailing = { EmptyView() } + } +} diff --git a/BroadcastBrain/Views/ResearchCenterView.swift b/BroadcastBrain/Views/ResearchCenterView.swift index cdcb683d..efa47b47 100644 --- a/BroadcastBrain/Views/ResearchCenterView.swift +++ b/BroadcastBrain/Views/ResearchCenterView.swift @@ -10,7 +10,11 @@ struct ResearchCenterView: View { matchTitle: store.currentSession.title, isAirplane: true, latencyMs: store.lastLatencyMs - ) + ) { + if store.spottingMode != nil { + notesToggle + } + } HStack(spacing: 0) { modeContent @@ -25,13 +29,6 @@ struct ResearchCenterView: View { } } .background(Color.bgBase) - .overlay(alignment: .topTrailing) { - if store.spottingMode != nil { - notesToggle - .padding(.top, 52) - .padding(.trailing, 16) - } - } .animation(.easeInOut(duration: 0.2), value: showingNotes) } diff --git a/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift b/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift index 851620f5..c03e8618 100644 --- a/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift +++ b/BroadcastBrain/Views/StatsFirstSpottingBoardView.swift @@ -61,12 +61,12 @@ struct StatsFirstSpottingBoardView: View { Spacer() - // Right cluster + // My Style back button (standalone, not part of density picker) + backButton + .padding(.trailing, 10) + + // Density picker HStack(spacing: 0) { - styleButton - Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) - casesButton - Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) densityPicker } .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) @@ -78,29 +78,24 @@ struct StatsFirstSpottingBoardView: View { .overlay(alignment: .bottom) { Rectangle().fill(Color.bbBorder).frame(height: 1) } } - private var styleButton: some View { + private var backButton: some View { Button { store.spottingMode = nil } label: { - Text("MY STYLE") - .font(Typography.chip) - .foregroundStyle(Color.textPrimary) - .padding(.horizontal, 12) - .padding(.vertical, 6) - .background(Color.bgHover) - } - .buttonStyle(.plain) - } - - private var casesButton: some View { - Button {} label: { - Text("CASES") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - .padding(.horizontal, 12) - .padding(.vertical, 6) + HStack(spacing: 4) { + Image(systemName: "chevron.left") + .font(.system(size: 10, weight: .semibold)) + Text("MY STYLE") + .font(Typography.chip) + } + .foregroundStyle(Color.textMuted) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) } .buttonStyle(.plain) + .help("Back to commentator style picker") } private var densityPicker: some View { diff --git a/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift b/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift index 570f3625..cd269f1a 100644 --- a/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift +++ b/BroadcastBrain/Views/StoryFirstSpottingBoardView.swift @@ -50,26 +50,24 @@ struct StoryFirstSpottingBoardView: View { Spacer() - HStack(spacing: 0) { - Button { store.spottingMode = nil } label: { + Button { store.spottingMode = nil } label: { + HStack(spacing: 4) { + Image(systemName: "chevron.left") + .font(.system(size: 10, weight: .semibold)) Text("MY STYLE") .font(Typography.chip) - .foregroundStyle(Color.textPrimary) - .padding(.horizontal, 12) - .padding(.vertical, 6) - .background(Color.bgHover) } - .buttonStyle(.plain) - Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) - Button {} label: { - Text("CASES") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - .padding(.horizontal, 12) - .padding(.vertical, 6) - } - .buttonStyle(.plain) - Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + .foregroundStyle(Color.textMuted) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) + .help("Back to commentator style picker") + .padding(.trailing, 10) + + HStack(spacing: 0) { strandPicker } .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) diff --git a/BroadcastBrain/Views/TacticalSpottingBoardView.swift b/BroadcastBrain/Views/TacticalSpottingBoardView.swift index fd986f19..2fadc66c 100644 --- a/BroadcastBrain/Views/TacticalSpottingBoardView.swift +++ b/BroadcastBrain/Views/TacticalSpottingBoardView.swift @@ -56,24 +56,23 @@ struct TacticalSpottingBoardView: View { Spacer() - HStack(spacing: 0) { - Button { store.spottingMode = nil } label: { + Button { store.spottingMode = nil } label: { + HStack(spacing: 4) { + Image(systemName: "chevron.left") + .font(.system(size: 10, weight: .semibold)) Text("MY STYLE") .font(Typography.chip) - .foregroundStyle(Color.textPrimary) - .padding(.horizontal, 12).padding(.vertical, 6) - .background(Color.bgHover) - } - .buttonStyle(.plain) - Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) - Button {} label: { - Text("CASES") - .font(Typography.chip) - .foregroundStyle(Color.textSubtle) - .padding(.horizontal, 12).padding(.vertical, 6) } - .buttonStyle(.plain) - Rectangle().fill(Color.bbBorder).frame(width: 1, height: 14) + .foregroundStyle(Color.textMuted) + .padding(.horizontal, 10).padding(.vertical, 6) + .background(Color.bgSubtle, in: RoundedRectangle(cornerRadius: 4)) + .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) + } + .buttonStyle(.plain) + .help("Back to commentator style picker") + .padding(.trailing, 10) + + HStack(spacing: 0) { densityPicker } .overlay(RoundedRectangle(cornerRadius: 4).stroke(Color.bbBorder, lineWidth: 1)) From 5913a727d8febd689876ced2a675cfd36c731052 Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 07:59:08 -0700 Subject: [PATCH 13/18] =?UTF-8?q?feat(sidebar):=20LANDING=20PAGE=20button?= =?UTF-8?q?=20in=20footer=20=E2=80=94=20opens=20localhost:3000=20in=20brow?= =?UTF-8?q?ser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BroadcastBrain/Views/SidebarView.swift | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index 11e89b83..6cf1e603 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -1,3 +1,4 @@ +import AppKit import SwiftUI struct SidebarView: View { @@ -465,6 +466,8 @@ private struct SidebarFooterControls: View { let collapsed: Bool @Environment(ThemeStore.self) private var theme + private static let landingURL = URL(string: "http://localhost:3000")! + var body: some View { VStack(spacing: 8) { if collapsed { @@ -472,6 +475,9 @@ private struct SidebarFooterControls: View { help: theme.mode == .dark ? "Light mode" : "Dark mode") { theme.toggleMode() } + IconButton(systemImage: "globe", help: "View landing page") { + NSWorkspace.shared.open(Self.landingURL) + } IconButton(systemImage: "sidebar.left", help: "Expand sidebar") { theme.toggleSidebar() } @@ -482,6 +488,12 @@ private struct SidebarFooterControls: View { ) { theme.toggleMode() } + FooterPillButton( + systemImage: "arrow.up.right.square", + label: "LANDING PAGE" + ) { + NSWorkspace.shared.open(Self.landingURL) + } } } } From df3adf4dc8ac758c5580c4132872fa8937ec67a0 Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 08:02:39 -0700 Subject: [PATCH 14/18] =?UTF-8?q?rebrand:=20BroadcastBrain=20=E2=86=92=20K?= =?UTF-8?q?leos=20(sidebar=20logo,=20setup=20header,=20app=20display=20nam?= =?UTF-8?q?e,=20usage=20descriptions)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BroadcastBrain/Info.plist | 10 ++++++---- BroadcastBrain/Views/SidebarView.swift | 14 ++++---------- BroadcastBrain/Views/TeamSetupView.swift | 2 +- project.yml | 8 +++++--- 4 files changed, 16 insertions(+), 18 deletions(-) diff --git a/BroadcastBrain/Info.plist b/BroadcastBrain/Info.plist index b296f345..7f2bd1e8 100644 --- a/BroadcastBrain/Info.plist +++ b/BroadcastBrain/Info.plist @@ -4,6 +4,8 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Kleos CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -11,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + Kleos CFBundlePackageType APPL CFBundleShortVersionString @@ -21,10 +23,10 @@ LSMinimumSystemVersion 14.0 NSHumanReadableCopyright - © 2026 BroadcastBrain + © 2026 Kleos NSMicrophoneUsageDescription - BroadcastBrain listens to match commentary to surface stats. + Kleos listens to match commentary to surface stats. NSSpeechRecognitionUsageDescription - BroadcastBrain transcribes your voice on-device to know which stat to surface. + Kleos transcribes your voice on-device to know which stat to surface. diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index 6cf1e603..44b78468 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -111,16 +111,10 @@ private struct BrandHeader: View { HStack(spacing: 10) { LogoMark() .frame(width: 30, height: 30) - VStack(alignment: .leading, spacing: 1) { - Text("BROADCAST") - .font(.system(size: 11, weight: .bold, design: .monospaced)) - .tracking(1.6) - .foregroundStyle(Color.textPrimary) - Text("BRAIN") - .font(.system(size: 11, weight: .bold, design: .monospaced)) - .tracking(1.6) - .foregroundStyle(Color.textPrimary) - } + Text("KLEOS") + .font(.system(size: 15, weight: .bold, design: .monospaced)) + .tracking(2.0) + .foregroundStyle(Color.textPrimary) Spacer() CollapseChevron(collapsed: false) { theme.toggleSidebar() } } diff --git a/BroadcastBrain/Views/TeamSetupView.swift b/BroadcastBrain/Views/TeamSetupView.swift index cc742fba..2e50f2f4 100644 --- a/BroadcastBrain/Views/TeamSetupView.swift +++ b/BroadcastBrain/Views/TeamSetupView.swift @@ -33,7 +33,7 @@ struct TeamSetupView: View { VStack(alignment: .leading, spacing: 0) { // Header HStack(spacing: 8) { - Text("BROADCASTBRAIN") + Text("KLEOS") .font(.system(size: 11, weight: .bold, design: .monospaced)) .foregroundStyle(Color.textSubtle) Spacer() diff --git a/project.yml b/project.yml index a1cc7b27..8bb96b83 100644 --- a/project.yml +++ b/project.yml @@ -36,9 +36,11 @@ targets: info: path: BroadcastBrain/Info.plist properties: - NSMicrophoneUsageDescription: "BroadcastBrain listens to match commentary to surface stats." - NSSpeechRecognitionUsageDescription: "BroadcastBrain transcribes your voice on-device to know which stat to surface." - NSHumanReadableCopyright: "© 2026 BroadcastBrain" + CFBundleName: "Kleos" + CFBundleDisplayName: "Kleos" + NSMicrophoneUsageDescription: "Kleos listens to match commentary to surface stats." + NSSpeechRecognitionUsageDescription: "Kleos transcribes your voice on-device to know which stat to surface." + NSHumanReadableCopyright: "© 2026 Kleos" CFBundleShortVersionString: "0.1.0" CFBundleVersion: "1" LSMinimumSystemVersion: "14.0" From 527c89b84b6ddf3f5e89a81199d57bba6bbe6a1b Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 08:06:52 -0700 Subject: [PATCH 15/18] chore(sidebar): remove LANDING PAGE footer button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the "LANDING PAGE" FooterPillButton and its collapsed-sidebar globe IconButton — both pointed at http://localhost:3000 which isn't where the landing page lives. Keeps the light/dark toggle and the expand-sidebar icon. Co-Authored-By: Claude Opus 4.7 (1M context) --- BroadcastBrain/Views/SidebarView.swift | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/BroadcastBrain/Views/SidebarView.swift b/BroadcastBrain/Views/SidebarView.swift index 44b78468..5e685af8 100644 --- a/BroadcastBrain/Views/SidebarView.swift +++ b/BroadcastBrain/Views/SidebarView.swift @@ -460,8 +460,6 @@ private struct SidebarFooterControls: View { let collapsed: Bool @Environment(ThemeStore.self) private var theme - private static let landingURL = URL(string: "http://localhost:3000")! - var body: some View { VStack(spacing: 8) { if collapsed { @@ -469,9 +467,6 @@ private struct SidebarFooterControls: View { help: theme.mode == .dark ? "Light mode" : "Dark mode") { theme.toggleMode() } - IconButton(systemImage: "globe", help: "View landing page") { - NSWorkspace.shared.open(Self.landingURL) - } IconButton(systemImage: "sidebar.left", help: "Expand sidebar") { theme.toggleSidebar() } @@ -482,12 +477,6 @@ private struct SidebarFooterControls: View { ) { theme.toggleMode() } - FooterPillButton( - systemImage: "arrow.up.right.square", - label: "LANDING PAGE" - ) { - NSWorkspace.shared.open(Self.landingURL) - } } } } From 95493e4d1e05cbe9f6b2c057ae5f0b62a841161c Mon Sep 17 00:00:00 2001 From: Nicolas Gomes Ferreira Dos Santos Date: Sun, 19 Apr 2026 08:24:56 -0700 Subject: [PATCH 16/18] docs(landing): remove Apple STT from pipeline, lean on Gemma 4 native audio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Teammate is removing Apple's SFSpeechRecognizer from the macOS app in favor of Gemma 4's native audio input (E4B on Cactus). The landing page's architecture narrative needs to match that story. ArchitectureDiagram: - dropped the "APPLE STT" pipeline stage; COMMENTATOR now flows directly into GEMMA 4 · CACTUS - updated gemma stage subtitle to call out native audio input - rewrote the supporting paragraph (no more "Apple captures audio, transcribes on-device") WhyWeWin: "Apple STT" → "Gemma 4 (native audio in)" in the voice-to-action latency bullet. Features: Live co-pilot body now credits Gemma 4 with taking audio natively, not Apple. Co-Authored-By: Claude Opus 4.7 (1M context) --- landing/components/ArchitectureDiagram.tsx | 18 +++++------------- landing/components/Features.tsx | 2 +- landing/components/WhyWeWin.tsx | 2 +- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/landing/components/ArchitectureDiagram.tsx b/landing/components/ArchitectureDiagram.tsx index 25131a64..b8f1cf01 100644 --- a/landing/components/ArchitectureDiagram.tsx +++ b/landing/components/ArchitectureDiagram.tsx @@ -12,18 +12,10 @@ const STAGES = [ accent: "live", icon: "mic", }, - { - id: "stt", - label: "APPLE STT", - sub: "On-device transcription", - chip: "< 200ms · ON-DEVICE", - accent: "text", - icon: "waveform", - }, { id: "gemma", label: "GEMMA 4 · CACTUS", - sub: "E4B · 4.5B params · tool calls", + sub: "Native audio input · E4B · 4.5B params", chip: "ON-DEVICE · HYBRID ROUTER", accent: "routing", icon: "brain", @@ -80,10 +72,10 @@ export function ArchitectureDiagram() {

Voice to stat card in a single pass — no round-trip to the cloud. - Apple captures audio, transcribes on-device. Gemma 4 on Cactus decides - what's relevant and calls deterministic tools against a - Sportradar-sourced match cache. The card renders in the booth in under - a second, airplane-mode-safe from kickoff onward. + Gemma 4 on Cactus takes the booth audio directly, decides what's + relevant, and calls deterministic tools against a Sportradar-sourced + match cache. The card renders in the booth in under a second, + airplane-mode-safe from kickoff onward.

diff --git a/landing/components/Features.tsx b/landing/components/Features.tsx index 4eb9593a..76258d43 100644 --- a/landing/components/Features.tsx +++ b/landing/components/Features.tsx @@ -29,7 +29,7 @@ export function Features() { Date: Sun, 19 Apr 2026 08:31:43 -0700 Subject: [PATCH 17/18] feat(landing): swap SVG mockups for real product screenshots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the placeholder SVG mockups with actual captures of the running app so the landing page shows the real UI (BROADCAST BRAIN sidebar, live transcript + stat cards pane, spotting board with ARG vs FRA stat cards). spotting-board-preview.png — Squads/spotting board (ARG vs FRA) live-dashboard-mockup.png — Live pane, ready for kick-off Features.tsx: feature-01 and feature-02 preview refs now point at the .png files. Old SVGs kept on disk for now in case we want to roll back. Co-Authored-By: Claude Opus 4.7 (1M context) --- landing/components/Features.tsx | 4 ++-- .../assets/product/live-dashboard-mockup.png | Bin 0 -> 359465 bytes .../assets/product/spotting-board-preview.png | Bin 0 -> 685630 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 landing/public/assets/product/live-dashboard-mockup.png create mode 100644 landing/public/assets/product/spotting-board-preview.png diff --git a/landing/components/Features.tsx b/landing/components/Features.tsx index 76258d43..20fa7804 100644 --- a/landing/components/Features.tsx +++ b/landing/components/Features.tsx @@ -22,7 +22,7 @@ export function Features() { number="01" title="Pre-match auto spotting board" body="Overnight at T-12h, BroadcastBrain ingests squads, tournament stats, match history, injuries, and news from Sportradar — then Gemma 4 writes the storylines, head-to-heads, and matchup notes. Opens offline. Works in airplane mode from load onward." - preview="/assets/product/spotting-board-preview.svg" + preview="/assets/product/spotting-board-preview.png" tag="FEATURE 01" accent="verified" /> @@ -30,7 +30,7 @@ export function Features() { number="02" title="Live co-pilot" body="The booth device listens. Gemma 4 on Cactus takes audio natively, decides which stat to surface, and the card lands in under a second. Ask anything by voice — career splits, head-to-head, streaks — and get a sourced answer instantly." - preview="/assets/product/live-dashboard-mockup.svg" + preview="/assets/product/live-dashboard-mockup.png" tag="FEATURE 02" accent="live" /> diff --git a/landing/public/assets/product/live-dashboard-mockup.png b/landing/public/assets/product/live-dashboard-mockup.png new file mode 100644 index 0000000000000000000000000000000000000000..06e7e3d671cf98ae2a6a7758703d2418943a9bda GIT binary patch literal 359465 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

FL&r@UA5w zH}6ENdsPcYCRuVXW?^&tcLe75ESiMmvlcqKChnJDd3D<4!5Oc8zz=BLP=Hb>+>*Ni{nPnZ%27= ze?G7$K~Ld|3J)^MofC%4G>|;wa}FB|gNAVy>dir`vJF)BAm6&Dc5W=GXSgO$>m$#w zMvZso!Y)F^X1#$*@+7@#J~%#X60md2iBCjOI@bikKX|PZ#3pDN2J%@OqX9`BI$XZK zpe}CL1lU8qaHc9W8q}%<%7a71Vu}QZh)~61>T`S?NN1m)9tayfH0pNOeC+6%AE}-x zJEeR@1>-aBI#?$ZIbn}ys=vJ!v?u07swTNEFmz%F^&Je;)Yq%2l#5xp#~L~I(H;*E;R441;E1bw8M$mlZ7%U|bh<;zrdhXCuTb zGjIgTr@+IZYimx3!+5eciO6Tx;a&SCbBSCb1$(Uj(IiHdLuZ)@w-IRhe5lhYm_oWX zW{Y^M7H+4lxXPZ}sQ9@5;Rap;XvoULny~;k z1r(q6EIyg&+xcUn6>g2zToQK{7x$jK;a0JesjvpC(m3{EYWFy!$svJ2J2Es-;tG#s zQ|}5SW)`oXqT$(JOET@`6dsl$LuUeGj493bn6(9fepssA*ay7WBl_Jx-6;PQ=<9t$qt3{pV zH;e3h$jYtX4C5@-EaE@!8|_5j?-vWWs_#jVgGy;!Fn)mf~{gNw^YwQjFQ60 zfZuF5ahE?(VXb?AE$#^GnYICPe0oj=6sVr|@XY!FwXW~U04-WTA32*3^&jnsuUy66 zsf-jv3qieaGqQOHd%!TJ_Rb~Kp5ix@jd!Hy7=!vmcY%uwrr6>2q`OvNIV?d<7|5!t zUPKV)QcPBpa(sM)^U&vAN3y1Ljc=soOn)2gKhJ8KY_cjC1JSd@ zS^*N*(VrdKH^Lv_lb1Q~GZ%lFdLl~6@&OW(@R4N0J>jR=&*%-P1)&T$a`Mb68?RBX zU~fsx9oaJ+ka?ybl zA8TJslb8|w#%P@}wySS`1ixgU07x)F0nh9BP9$;ob$vC9I=FoR?&{|SWbYaZxu4v9 zm{wk2@F~n|kB|*6CcgvCsvn0ji41XLov7 zByUv`R)y+ovyiLg>hXmG)?tNz?A#QO;H9WVR0pA*ct5Q#)_ex3bp@{M&kF_*8vxUR zopgWg-vprxLpbtGhGGf@jw(uJuNLj-V;uYc0k9ud$a`W``@lO*E78Zl7 zt@o~Pel#j7kpV-Qf*3Jml3TT@wf+DKfVtQC?Ir9jpbckII6G7o$hzz7?eC9h@G;O+ zDOJ`4l3@Cbm35uG^+Y!*0)L|OFdAHnqk!Cyg8uOEeD{?+{Xf1*YLS-P*?)N zn}aW^(=8g(0o0C!BEK@;J{(=e>(>U&BDN%>?YpthSlQoWD1hHjJBg^S^6@3Jcw;NQ zIT>8Z3ouR^en9Go-vhM!3J9gRppr$yuhdQP&p~PYv=dZnV||ee2@jqb?}c8~ zClvs}<0ux<(k6wJp~ncdy{6WIyz>nsP@cjTDM42t_ic-fYIf%=)$=%EGSmpiT=eHO zbN|31ahi`Q2mb&?R5<3bk;F@%Sl-9d{rjr$8o2$V=Z7pj!h7;Qaqv&KBtJo4N4Y)e z8UwNmP923-T|ww`RrA^KCdrl;)LNSX2vMvKAzw!`UjCDOqN-c5mORU*$B*S^c(V1{ z7Or3mOt|%2>7LD6L|>F@>EYi8AS~qC(5CK{FYZYL(4oEnr*QNX+tr53>xL!9uRDn6 zQTtMehMH@94qSkiV`TEJ{eYTR4q}5uc*+=zUU&^Tk_U!Soe3koSscS z``$+YwsK0FJRoPZC?|Jg^*8WGLi%oQ<)IUbIvgAr^T5?pa&M{d0)=!so&(ZCBei8J zUC^V2Yrsc5<@`3sm~SC3BOSn(L;^qSC6ZK zgOQBAaC`7~PTsQhg_j~vr97vMask#(oW_tb_i;nWDG-=5eZ7Y~H2-`rQl_`sqMk^L zYw~wO$7!1N_16SqhUsv!IBUO!%7d1T!9}}G?VG6IUPg2W6fL{j0aH$wCuA5~1C zN|6$bKio`a^_XSeYi66vntVONoewem@}Zfe5JM7)w@J*c?rj8|A?w+Uf-A`Q-XIhg zMvwkw+r=E1%41b! zBNP1^UGY?pNXjuu*Km+JbS&OzlX{VUwDHf};m}s@;K(O@^xrIb>$N+e9$L;t2P=Zp ze~6KzF88hG9`-zQ;wQ%yYU<@gbk_2tM=o zX|}7ZAf#Yq)shZpxIybch=cn1Wjr$|mpx#Hc1Y-K^iu;H&PYIw2OQ9>anE=I!ej;? zozMWoAcvL!hj(i|t%*Pr-Z1<6Y!s;O?aLSpn@jwe9kNbQYAq;(jNJlR>I+Uu``oFZ zO7oO%PqdW%xh2ihcIP}7&gYUq9#8_Ihjq;Yd|7HFz_`jRbqtv@>_^^PZyl|Vh8vAr zErMQ3oeC2vm&(I_1hRlTJ=JJFKm@{c=W!d;F7Q(iw89%|l(I=EG$topPRljibzQWD ze-UUq*QRlWUz9_g#GhBMxF+T)_-KEL`rdwn-1IadC!hpkbhI=_nab4wa*P_XnZtEw?_OF<1u^hq*yDJ&Jjy-NYpl z@QZg3IUM3VH_WRvWAZPDrsypZv$SpBG{%#j*S@!QVn_7HPAo?TA zOa9wQR}PZfUBs%2lBjXcXZf`>)VF$Z&tzVjK4+!N=fHoaoW=J*E}z%vS**Rlb`sTPi%ZQv=m6} z+}B;g)+PSTxFP#DPYuNGi15K}PR+t^o2SOdo_XG6H#jxZxtij*^W9Sw!;DxxeSMP; zj|KB98c35*OKCMH@-f+pw%IlrQrO}OtvmxZ^!@61(qqic;Cn}klL7!cbPt!~0Ge@y zI17|V!x=F^lGZNRpsGV%|-8t=f zhaU^@7EF^)6o@!9K0J2ks*j(RFNzGE*5^npUvqe%d+8AC8>NA}^ao>6J5#gDq(F$! zsyzyXa&tfCSRFzso|KpQEDEgtIrnGNEOUjVkNM1u92^|sjn_Q0$_x#W7|_<_po0M! z`Jl{-^XOARc(jnq0=f&ci$)x{SR*v_E~bwR zNa3xXke_4Se!d6+gV!F)EXSj~<`adGtgus7_nFx2BHbgw}^ zJA;&j;EvQ6@48@^6ek9Z`#T({t~%Yllfq(f=1fwM9?ItYt#A92lwnP;&*HM_>o+Ec z%PfBII@o?{;<}nuV*_NIa%QJ{rsze54=mB3n#28+b3y2|I50p#g9yu=LxiJC-(zzc z70Iu&42{n%?;~LJ7~FF44{A8M7MKvb4XbN2etP4a6K?_=avOOjZF(Fn9^F(lO=U27E>Hy6{9q5w|-gBc^ z-D;B>HYWC?yxFdpZHD}y$L3C1UtL;sGe&-kpDVy|rQYi=N^|ANXI<;oNl^lx!``P; z_5n!tFT?2r#RHrTtO+u1qa6>`d*gm|-X3oXyW{z37jU5gR{>q}HhVOV7Ok7fGy(bPK5U1N=xEr3oJM} zFX-r4w`Uk%rVnA-d!Z8gsKW&p!tq|C7d;QrYu<=Wf{#p)U< z2Umc|+@$<{8htNRY#fX^yIHcb-shF~&gO9qOlg(^P2qM1dxLLa^})(^wMDXHadnIe|BhDmqy%JTA%?W3G0kFZeSrq)iJ7#9r@J{9d(BMi!u`9At9hH{6fnmN1 zJcIkBMfry%Cg>SIAfjCd042=kbn z7)UFiO#hmu7t}?(#A)WFB{TB+{<-@Fyq477e8&jg_=}6nr&)Pn$W(B>6{%SPIyw?% zn2zPTwhOaw8Qt&9^Byxj)lfrX%Lu{k<-KSM!Edn{m(vt)3(t}^^Zt&My6aPH4`x@E zb&!Y+`fyM$v_+f7jL}_Tj)S<`S!OJR1I?)cEFkm0d0 zX+d>Zp0K2(T9a%=U7>nV`u2cTmL}M_q(>WPi-Gdbp3L&V#T~9mA=Y z>29Eu&x6$Gu+yKj{9ef*!Y}DP_hIC?C{k{H=W~O}#ElWC{`t$_zv~?`_;3n8`AL3; zO?{jc`LnHlD|INELPHYQfnr~;%y>?%i1uzSRK0JI1J(2L#TNp12cWRE|}73L?Ydf>5qKW*OJMv6g%U`(QuYI zhgg=}C<>IzGbegWwCOH^qaJ4rEq$1TL9|&Zw-K&v2&0BJ09YCx+?i|k#RQ27mD4)j zy@s6*n4}9w>7kb*AmBQ`z`J$wZNc~;>BwQcr~~(0w4fcSPF%ZWc4yy^>cf4KoTlf5 z^%!(q%-5f6)r*?}WEHe`AYF>1_^p=DpB1XVipu;t0b4zpHEbNjOq}(8Tb^^THnf;G z{H&?hH$q#13-M!Ac$s1xqC4kCxnL|gU(lhmMM7ppN59~e3USpmilz8y$gEpq0cC}-l#n`=ClhV;k|^Qj3MeGECOFP{ANZy)ZPKk4a-0#~UGxomc0m$HshaxMrqu86|W=j_}!8s1I4WIKfQYzD? z&OgU>6J;$<)rqb~v}!B$VwQ{iGOwpCw+6E*4$vW(KcXBu0VcL{f7^F^2JEYd=!RKy zqu-`{&Jlg=20yd)ihbs8JDk@5;OAnXHl#{~@j05) z=4TkRuT0eKK%w3xMd+h8vQBs6wJLe!1r7@S{o)Exaweh-AZ;^oIn57BSD|10E)X|+ zIb~Ccfrm4v7TwgzG1+D%OPBGy9H!bB*YIaFNXmGA+&QYv3D;!6i~Yd*lXflWo=UK3 z%0`UKqZ;Y^-ZOt?zPX0x^hFF=(E2(cuKf0MR-tq@rTFl5v(yVDya7zLo#mGSXHe9c z&3IGtgLTS>`dye7<(dJ(WY4)=lr+2`m}pRzUj6am+v}c9!upXF4RP&Jno>^reyyil z-&-JBv&j^E$mQVUAgVeJ`+f=kTHb(F3DN}v(xO(LY-H^UwSnbJ~PW)ps?`mlMM)9 zMrq)RAiA=4ZvXyL9~N4K+5v|+CV}%9msu#;$#}Wp1GKQgb*Bug6Q#SKVpG0yF$mpK zCQ^LmIj_it)craOKSm-fx*)rUde^3Uiau=^cXuaU(KfLhHI;6%fPTHB0MD7#L`Hz# zs*Pdh+DC@0DVwg3L;3X8{Ei zhM0O)pNi;GGmZ(1JG@eI&v&Q_N4)3AJZYzQNgkQf_5j*hV=`ND6y%K^zTc6YJ${q-yj zg}Ch~Y}`LqT9nYtN^yZ}M@8Hdmn-^C&mKurF=s9Us0`~AKndjMXFQI(^0VeW5ujvK zSL^)3AN35#5~j17_OgSy0Y^~%o_mwNK?OSSU5$KhX33{#Z^tk_+2; zoM&n*d#J}&42oza{|>b&bt^2Ga#}9|Da;}$igh(=&z3-5uKCAbBLn%BK8$a2pLTkv zb*G(bpXV@HA!Fo^!uWDeqW@tic?0AvX5l(9N+cOWxH*Rj$Az|fPWBAg!0A=DtJu&X z-R}6Y7ZbQX*1hc4VTBYBWu-MWkUAGIB{Mnw4{bV|hE_3AndL(#wJk#}0p73pcYAsY zJW_sD-=uSfgDm44&XOqvI09@1ss1Z}#M3#VG;A6jth0Z%?!Ygd!OmT%hswv+9Cn*R zpJVl=+wXyZ+Uqe3M|~ui^6#4#UJZTj%Wi`2 z=stE9d!UqI?qw4Gp-h_m%kBf)wIYmFUD$UQR4ZGrC6{n0iwFPyNkit zmux}*HJ=Z{Jw97zt`ZHf@WsnPOBRY<&kCG2&?Amz(8wwiEUHQH?R&^$fIM+M4xu`} zLbQ{OW^JL#S0yhfu1c;`&_Ly;+l;&EgDO7b)?2OaRgZm3{vZ4b9G4@@8AIAG=#~uH{t3lbT+qoPx?D1&951h zP~J~@th!xyZR35$l>$Q3AIDkCGi?HxmE(&+MVZ!X^l+5?s}1-s5!EgA%{F~begTV< z;x5dcT-AcJW=>L#k#L937Z-_dxr1YM5@`PFhG`E0#QTVAB_W)t2RQB3WE@f7{3{x z(K_))_u%-A#_zUZ0QZnl!HmEn$i&}*ys*&W0WAbYvqz}&H3S#6)l*9?{H7&gAMOBJ zlgm&uP+pPX46LC>wbh+61Xn4_eKR;ULzqAR1A4%}pKo*aB1GHorsjeF%o_i0|NP>c zv%fV?aqVwy4;9w*Vnis;n9lRFa{2^AIftIqtaJhGap9rBgg#W-fUQsHA)hG(%5BjUw`ooQy)ay)iPP1I}9#RHg27 zk7tFzto6^5we43QNZB=2n0kM|GzvyfB{bpVVW5F`kYNT#RTKwE;@s9i=Vo_M0*^d! z;__R-Sa?!Vj0ty}w{E9HtSzvQy^CP9iVGPiA?e)H0buC6X`S=dG~FcmEX{gTQ`#bg z{2yI}8Dg&qwlKSSiKA9iH(Dy?c9vpF8g#NpB#)~;fQI$-?lX-Du%k7~U8(e_<}T<4 zN+VjTzAjdwn^nv3$a|3QKyi8*JL$v@flxj;Qo{b#>f9%`IzZF;>>e!N0e>E(<9C8y zg4y0LKPCx{XS~1M-$BR0Kp|xTprN>J6m8%a$ks*yj)}g!4{^o|VqiHQ-f@l)^O`Xg z_nbPiSS!k{0U!>hh525yeKgcZk=Z#nQO>lQW!F`;`|HPl;-OVBQh)TNfDt@O*qm$q zl5P2+<}X|M$5$`jY~BjV`9h9;VY^L70^?@;@~YVp(gY`}WipG2B(bx$&9Pf#nFTX= z%E|a#zf&YNM)0hl*fYOnv1h(NP=k^;=Xdk#jMITGK5gpMlYRqgoD9a;k>%A+e19Mm z{=+p@m~ZBS4x(}|l}`M}H~u`|o3AN5ZRUayY`su{kk$aCpuDfg%caXsNFl%$n`LTA zlyY(YbVWgPBS6jvA(Dnr_nMI~Ioy>U&T5KBnN&#-JG&)h<84*oC%A+E>;L}qpZnRi zT*(!an`gIkC2m`;#2?rG2)4hlrr){GthCe6Kgt%++&DON*9bjZnziKe>{mhvy?A&^ z&U{F6Z?TRf$J9Iht$FzOpNQ|;Y9;17O5v@L zV8gtWUQcy6V?~T^s9sx~zUNp}0sZ7mj+TAKJ?3@kPIexT66U-Kr|5aP_6#vv2b`5{ z+>*<^OO#3d=9_<*!=JnHUSKn-n3z_NMgF;3e}4PVlzo27sjTFqOEbiR(52^KM&H_J zIioWBMbDQ!d7@c{oz|em5gYr+hTi7Kc+d0}eR47bjONeHdGP^%p zl8moxWjg-wp&Uc--{>7-aenm;s&Fjv=`-Eox>Mo34^)O{VCq$>eJ46Sq zIlV@r6$v$iH;OwPV48PubHZmWtB6pW?v`X5GKx*HDj zQ&h$pQVe?&QD#MIZ^|bl;_9&+we`R?X;gcb^krV}tT2);=_5lIAQa$3ezAMXf#CgU zwH6%wUh-c!pg*_lj~`Q}(8h@Mvq75EqDO1<=H9A4nA>L9)rAmqmEXGAOKznS)T4?o; z@ydVvwmaxnIW|pT9lPhvgI|7n@Epw~HB}fff!QCQ3&eU?0>bI6mNGz;V+EKTT*ckT zb@Tzr(ETxpoup0Okwq{88x54s@8eEU6A2dn^IuYQlP*^yLZ)W{QC1^Hs5jqD8=p1; zfKeXKUqY@INRhf{9f|oaE<_1uJ!_#7t7)!WE7J4JAG3Rx6!g(raPHlc!>HSM$5w1j z`xAy=TZT^LrjLeVnO3=fwVU9Bem15VH3Mg1l)O(4iwUS~o|wkEeLMc}Ew^*w$F?ks z{<6zFMhGgoA4qUGw!~hUY=_rrNic3BlcB33=s7+`eicqd9!r55* zYY+KIc++9L^b!~U$MOBkhXpx6Kv5#<93O(!f#3cP7_i2Mmf-vJ6!w5)kS+|0D zs=dB`TVgUf%X#r|igT{b*ESS~kE)udlXOYo>KDp#Zs+QvFXs}Zwa~eH~Ei zPrqK^Y?k&F(1yA#f<|-{5MnH>fTl%uaIzjf|JgKvgtxRXhnoZFd)HKm8tm5Cng^z) zZJ)_)ht#gXi7ZQ1(Abr-cOXjG-*k|6a3V@L**Qqt-EhF8Z5=rA;`t5)5tdt>gx4KA zpc9ywlv`v^{Tw*Dv&{O5prD9UNr-fGFSm4YRT)RKe2CMf0^cRvZ`>joR%7+sc#wBn z)mp8yAs*ZHXf%F$5S<{jx=7K}9vdtdKn^Le%eW@Xt!xkwy|L$JFHkNHKmz^X zV{0Uv2#8LnngPuRc)D~MtX}s1k`-8Q$DoKa?3Kk{H*{N$gV^EWov&U%-kP!(8a(x|E6CO7yx5H zdw#ksVgOD3kogqv&PR4jde1N?^y@=BzvaAEu%hk9{yGl-_=?sYqXp>-z$ad zY;GrWYT1WVzy4hOFSZJreoIG#(4W7m|L+(6-wOZFB(@IX{|?=j=lFlqOGMGJnc~lr zrwN@vZ=}xC`Kdp4v2En=>9?coA~9s>qM6!4{f>JGW*TF#1Ke)*h` zVMaDJQ$qcXuoS>0sCP^<@wmSz0#W-R-X}w%;GQfb7=cpUFXOVSTMoFTGfbXo8%I4z zJ8e<-SWS8Ed^>If${i^t1m(8)(GWBRS3O8224}>uI9<1p+POlCXOLxS0!lXuyZt zRXnx;BlWsnUQJC6v{J3=0Fg(EdyWiZox%2CtBn3=^8MQ$U4?Dlk1f5?@@(5}&*{yE-)%>z&vgqrn9n^M zv2A{l7hYQ{>6d#WXuIbGwrU^xR*$-G?l%1bfBvC-yXP@moN6V~KD@sUiFSY1+>Fi! z+ffU7<-0HoyXtTL+D4W6XSYfu%QheBwlfgz&F~{U_3QqEFZ&Bax_PYvwtL=ea~agU zTo&ZFGpOjzQrVYG=!kv59+2inefcxw`R8&d_id%&v-S5Fei_MvLG@T#5Un}@(SCN^ z`N?rtjsk_RYui0vytNE7eZxNgeA_?6vi;JVyB1;svhuZqg*AsHo~Zn-ApEzr4l3Qk zviC(Zu>8KwbMjjSs8}x5p2OhRcJ_Np`gM@GBglPg8G6gA7ytH-e>Y@)=gnQ?C@>69 zC7p5&7qC10%hC(T3w*X3_WL zRRy%L?CJpI9e37W^F{yl(`Wp5(!nC9t-xPC^G@42jOSoZjcy(eGovW?9qi!r1NkxAoh4O($*BS3uJ;pHKht1A(F8pA@-? zF^tUn3z=_ySJ~!6odFNic+VhrAACK%o%@U5^p*@Wvb-l4GgciNeiw-Vp@gb&;8C5J2t)TB{^1hepilfmBHIt5$$2Xhz{Ms`b_gbH}1dIHAs2Wj+lEq z}~B;p4;69Kamy9TJ#LNO&N0Lw)2?mcekuaS=H*$ zHv7o0vuQ_kUOXTuPGsHgs3mOOSqWH0?62`)J2!8v5Kpc%$^(!WNTzLKqWB%)VbDWB z?cm~y-fka*wr=ghN$(dG9Pq#0dH?n4n4w$7o=^H<_Ln96m&ZpW&Y1){_3p#tZM$xW&Y1){+pZo z|K~E(Z*R6;UB6#U(n9gbdG4Ai)Zoo9DZtqG7UxeiCq1OG4xARvY^SxnGQHS@{@|kf zH{W$&(_2F-_l+k1+xNF#)5)YoJNij>M1Cv>8eo z%t^-Na=DGh0K}q2c)QZm!r4t%zv|2(yj=}s;S{Yz#dWAKN-?0AHY@2?J`0FDOhM~+ z?wzOrfrZ~S+|hFMFEH6(uK$m(py0ot#U@a^tdYnzfyD52+7&H%8i>vJTmV3w4%1mT z@f#I8z>M+u|E;$o0bz!>0P=i-K<=TTiF!P{;W8Fl7*24d6DsTY{uaLcJyt`hZQj2q zlt=b$A6l;OzS6tiR5* z<8cCQL|3hz1yxr&T@0oimb?lW8z?8&DqIlLe|9|5x7fPV+@jmbxhE9lHy2 z&un4U?)L2uf`Wo#VAfiK#-=lth#twoI`=vN4J2n!@4N+OPGDyVFT;PC8lF4-v(IXm z{)^SEpxVwVBn_Wgklc9T_02DRgyG_0ANriT@&|)Cf^D*I-j%EC>lIz@VWR?Wzdi-B z<#Ox3y1l%N;(Nu7j87gHJ$dq$^1k7+`=!e>d@d55H7LvsrVfL`WCSi8OE-Ps_uKj3 zau=6JS$6JL=7;V1{ku8qJv94s#a%E##_JlMoo5P*{a15V0eO2pWrG}&zFHp_1^VQG z_FbeEz&*gQntDB$)1yssI?vqbhh~}gwq=?$_V`X_rU1~&Os=O68MxUI({|^Q%&-YO zIwBn)H8rjW7y+r+davjrz`6;_*Z1wgj8D2jx?aM@tBpZmKsM7|k~USLJfmQ4R?9V6 z7Ik)myetiDSVYg?W2!?876*n&OkNslx-Ivf&;XzTtB^N$9s5eN>H(q#t_bZ>tjWEI zWELay$a^=@>ifs!Jlo!M*1S=ukO1&Wa1AtMSm65JDIr8`5Y&eN@fQskS)v{AD4C$w zHQhJ_jy4I<>_VC(EYHq3ms00G$qEPq7Pt~qlQN!@vL^Ws;Q)!93jmdQL&pj7_)9+N z{RaEEck%B4E4hPi|J@z`{pBsTpff$6Rb9gshLBPJ{>UG%zPL`OTL=qtyN6yJYmC-b z+Gum?%B%h{)!C{MB~eWRV-5kgQncfETR+{2f2piC_$a;`47$C$Fbaz5V%H9sei^tr z`Ot~owEDYUSDwA0aGp>)R@$+>4xmA2nrd2+ z_k1F4QvZ6-_VDdy1Q^ak3@iwx0b8Su8eGg80!VMQ~bxxht(qIkPy`_I=K!hH?b$`bfh@_iDH>Sd|Hs~2Mpe0X;lc(ep@4)at1xSd} z-6e=3NS8<}g5(0}6p)fex*Haq()G=y>@&V|&ilH@8RPr)jq`822QD9;b>DMd^P1PZ zrYc=wu)VYg1FkQ9>cjqnJ;Dgs2v>A&YO)gsZJ9=cvdsIk&6;3=eDvsxws;}@!4LG( z!Efj5X!$R98FeNrf%BSB6su~g=Nvh%4;ahLdA=cLfeo51n0^;-8vXC>yCed-;u6n#nxHeoUE|5I52;UWf>kn@@Iln$%ypC_35tH zi2rh@FkcI^$niJ0>&kfcFFyx2GCM?^bg64HdUS5~OPuX({PW(ySP0ALposvcaU5=6 zdi@|AUC1b0^+f;U3NaY2z~=KANu{~~T03?Xu;D2o*{xol7eID_EXt<_E~xDB0_sjv36<08L5gX~=I>Z2`JbW2RPpW#Q?yZV;o9%z#~ z1$1lPM=d;`g8OKU@B&4zdQeB!C8hT9ns?2`He$CdLI(542Usrjr>o^eU#hnn3r;p} ziufvjf=r7r&tSHlVY>ILt~|3X%;0=DbDrW7ZaKZ}{_Gdpn8xsSnVCtu&ueSaZ(K@8 zrENmy9|H)8)(u~irZ4P=NfWhf$qk`7Nh@NP2h~$1Fnq&3;<6P3;mj9;bODU_l|!KR z-@2LkA0pX5*GKUU)+cik!b;W41Vlb>{?=`MgcKMKvM0Tb1Ja+GM=y@X_BUpno3wh%?1Y^_9g+7yh@L799 z;769cGhgrYm$Ufe`f)Dk%$VA%j#qr;h zs5ssF@tK>h!)Cbs9~13A=PvLvCW|UBVIzo@LBm=8RPuhQ<^HyX)y~?K$1*+91A11> zRRjoPSn2BcYLxYi)Dy8#rphju8E8UiHFKBPE%TXV>k(W)HV!8dtY${KbKW>*cM8|te%7TpayK|khwjISbMplhC3T|;d z{>0t#1d#@|ySECM1a#}K7-7PAlAKuagc(Hb7FAZI{+)HSx^{=7)l>r+A{P0T{_R{} z&il)p@#SPU$u1f?>|l{0>tD~!{Je(pvzhDU0*ebiVrd3TOeq!#aO52(iC-45)C=0! zn)}Z7m$dhP3`Ueu*a%P{^B?WG9hoV^&_zV7nA>6LPQcMN;WfJ$*q#>!_k?}gZn+B6 z*@q2+3oh1~I4B+S&l`78cqqtg&t6NOP7nO@wa9$TgWAg}`os+UWOwCUG2nqf7@05l z>3V3gI$qOqQpTWEPX3|G?k`?ANt@qTyV9^U@X6VE_O_PoY*x8Ls#L%?u8G=iP+QP? z=JAhugZb_o`t`vK@=eSqAH(%;+TECMhVhVSdue}-f+1V=+m+#-epb^>d}j%$R(z}$ zFALd5lQ@zw(c`lg1_#QWY6N4@OWwVc$pF_m5}YT~RTJ(tpR(uz7oeDq@O~GlZ;Lmz zimmGt*SFkRHFEUj00Jq)`jqIc*ZBpeCa=d!vFD?-FZmf zelLr(yir&Tra#TgAU5`_62HxgoBAa8g~3v}o6hYkZ#|jdg8M!Q_;XYzQ%9xcJ?v6@ zJ`IEIa@*<_T2~8M{pAha8lP3FPBnzdy~ZPJ_M_~HiJt}Mv?Q7LsC!o{;e?RmTGsfG z!B(v^}Dg6~B1(+8=gS9S5so9Fd`-$r$jW)OoPxUwERN~n#LZ@bl&=D$~D4J zb!R+vw&Tl(p%S|i=P7d_D{OLfY6|j2jG6!m$bu$4ids%M2_nVp+u^R!ym>+8 zl6sXdC4Wn%x{>FmWgCy`YSUJrBu^im!)Ll>1eNUX8oT|o_y5O$E(wW`nygs&65GEr zMz;+vaq08T)*X39h~Gno0xQ*Kac+l2YK7+7O+D}(^B=)ZEShxC5- zaevtf_erkJV*iaY>@aS-a?a<2g{v5MZG~I0KE%kBZ2%2X=PA3RfO1y**>2uZ=0wP* zpQ@RxUmvc@tWB)7(4W_cdoF-VU;&vdXfvm$5o3B2uCbL)7TmE9P?|@ApRhn3(}61h z9Q7@SX*k3B6)#VASEdGFDrg<)^?r@YeoeUu&Y!ScszvbWfsXssz)iKvE~pWF2lG*y zWrl!$b@|K=>%FU0Y&A7wbve*5>NR&uidDc2=1`g!hRX&p9>;=jhxFLCQUPH-uIwd1 zTTYQ9>njZ*nn0nMk>A`S2OdEfx>63%riRm$YodVU(qoK!_`z_W3JTfRb9MMHpif-w zpM1+J$V~qCd~5wrzLl;!0l=Cd)qDNAf(M)T33PLa`RsG3NN+;cx+VuH0N?$=7YNrM zA$EUQF4r=mf5>VWasrHZB`~9+-PDGOHZ@P4P3rN&z&lf0>f^6EvhBbIejsD}#>=D- z%X8<=Ig1uGUc=6}eNwc+WXPSELcC{djpT=xJ|swkEx9PZVq2MNconk+a7jMgeRom7 zJxsLDjMyL6JP#DRY*?Mj+#cCE_urT$NQlqw(Bbi~5+TEyd*fC9Qg}cS+^#@}w`E9# zOthzhTgcU>ll{(TRGL5r)3Jaem&4pO6+^^@H^&I|csos&@>%Mo$4l#c0ehL=5&p{p zY<@H%wZ$wpERzwT#%ize6xQ&I?wRyu*Q5g5kou4;x=*H+ z0WpOblt0CU`RbGeg}DjWaz}_cw?f`VX(LIpIn1 zKXBTA{0;(XFqHw4I!u1mPr*aj?$amxtpz^vl*1;~s zXu2gPYDttIC^at3-V-N*S@si^s>Qe=Vt+wc zfTLBhCg8?=b_EzlU|(dzKHBZ@3lzlC(ravuvT&goTpIp`+K4%>NCl-%INbRw>{1NJ zupmiD9F%_ZZiDkm<(|Q1e8|(brca>Q;UW}Xc?noY|4Bo=brKGWTP}L-FO@L-OFu}D zX@r!Y;sXCdBSd0ogi!oS)g&QN@&=%x@yqU0{{7?cOa6JO408hCUj29Aj-hwRasIRp zke3V$UYzzw;}K_&`TN(9?IBKTI)0_F!RO;`hJSgE(|@2?*c<=W*VivV1BRph%-=tq z_&5=GJNhsG{lkA?V@@U9UGjTRDEeQHvYuD0C;oftNT>T#sATITE8_nBIoidKgYCx& zt1B{Ch@!T4xhMbr>5|9C=~L{4(BD7Y()|xL)bKhe{0$!j^V2HXo`3(I*x-A@R0!#p zSXEB_{W*Au{!|DCGuy}?#FeV-zpk46?_G`mcVMJD=F-EG(c1)n|8OL{LML7vl%@9P z#E<78(3}Xn{`Wxh1Mg3uVP$)R7xpjDaUOHc&Qz*W2#S(tOa9-Zeq1vC-=qE?vo{pO z|Gzovs`+L12fH>_tK)YujKS72uwc{B)tLqp+NBXd9#B{FFO<(u0~4~Tb(r?8@yK~S z&shET?CC55RskY?_t)>yt|euW$OCA z{GMuh@_dBP(k}fWMdFjZ)Xm+`ktyIZuM#OMa^-|O&T;6zK%uBY_V*|vetgg4*>8vm zT`O#G)&j$z{%9e)mIEOmCrOYyHOjU3C7&JHonqUoH5s1gh;ydRqy5vR4HY}ZhZ;6r z66@LCZ>90tUnUz(z9H83vn;1_dl%(#-ZK4#VR!noqb?qd#SD-;wpXt&hBZ^pzu?;< zuz_EUTjJ%;QS_J~E6FuKZcLK#yf&)wirHqxC{%iBx4PsWrg)NtBLBOprwZovI{%66 zVVPC-n11_zhYI5I$Lx#%@8rXtOIU~$T{WaUlttW3^3j|?a9SQs{unEI_F|6iS;BGMi6AZwAxw0=DiZU*Ke< z4PnYO)!j+PPfVL|dU(si=mHU^p;F13K5IW>uFon^OK!jZ z^Yl7}|AKPUjt?cu|J%cSz*{UQFNPpZA4&OBebq@zkbj|CVr!xdjs*#bqQ_q){u}~$ z(VhqlHzDuqnC;w^+J&LMGyo0hkD+1x1qro(fri1yFkxDll_6G<~EprW%6N#IvzP!p{W;$4?4RrGhj7~u#0~G-T%O&hoMB1Yp3_BsX zf6f`5GS(!g4eUQ`3!CsfzRv$heLnh|VjYxqmqYJjamL+Achk`T{Z$RZd3lI$Gh%mfycj zB>~@*@vngMe|}ja)l`tQM|_E_fQOZe^u>Dy6On*-~W z(UU+dYAS!cjm?w`-nQCv+)PZzm+A6_Ldz*10ciON*vx(YsXV#9_T&R_JD*GW(i2#u zq~Bm(o-{mQxyttaKOBVt{b+^~lY(Opv%}I82EV((yzufYj$hvRE8n?)DU&c~7pPZN zy{)iiT3{-Yj-bn+1O0Impqg|d`AqbQ)Dz#Z75xsO;& zgAZ`sKc`#56W)1n5A%c%rRhl4k3b#dcM4tPFKy5hbQ$wKM>7R3@v@>%wu|G0-u&}~ zsnO@9BmWwpnWc{JxBx| z=gCNrc>YW`8OOLw4uK*l+{Q*2I<$RXb-hxMMZsk1dECIF{U{cEc;)zTvf{p23~4I_ zKT+r{Y$iEw%zeyxPJQ0b-xKqlbIa3dth+UaJ0wAu=du|g_U}t8zC?6?iXu!%Hbr;`QE>?rvB5BL1mYK+FL=oyY< z&K~ZMA;Z?#A!roiCjlRr1jOD))@DHpJW6lOD+#>}FO&O@LM7%==@d`7t7IrKkXE(A zS@1k=PIB%vDCHBvEOK`f&=TJ&=Df1N6DnfU&s1Sz>&t8%v9Q2 z;FXSP>tSX|!TA6Wr1szsIq+<%?c>AWzrk^pf%#?r=l}ft^3R)-mXJd0T*N_r-Dsu0A^(RlEjKjklO(8J6Lue3@(x7XmlCjST1gl#E3k=(n0 zBs-bpnW+#X_>9kNcmYcoqheJ}Rbjbux9`w-y6G~;FU)G8R|!MsQ)0b8uwg&{6=XV* zgreIOAP1@y2H)i*x1*EY-sw*avafS5!ir9eFLFzAQ^^vAF{6C+3%~>qClB`(MRAee zoa>$U7V)gMSFV6TPmBz;XR&tG8FW@pveGr^*YIy)EywGTaqdG~;j*`8E|?+r`DuH+ zc@=!U&BU4KZWS=P-0aK7v=+Oz`^)3e!i=y$(PZ1_;9^$ z{EXG^uat;}VM`ek_&HjB+S>iV1lor6{Uh*&j)X2pAD4N*^-No3tk^-VhWgYC1k+IZ z9WPftFgr&HIBljojC(T;-eG1{Ne;B$wO+P|NV}Cqni1fbS=^POUguo}t8Bt=*F3kR zma|h!DKurqV*ajGaqWA|d%Z51oO=vvSS4`YFEIRx2v-FQlllJFqx?VLLp1H)_&(V*+A_TGvDxzS~83)nF&wCO#e zo^fJU2}F3D2zi6Km}UcVcH~o7`egtzFukQBG!3OJg5RX;U~lATX?JpeXT5vO(DyR0 zVJ;=P0UM`yEwm-9C&YE7k1)Z3j<+N!_@##>_{6H_z!EGpJ+I{?vvQ_pS=-(H^|&KW z=x1kt&ro0FI(TaUw&bIwEpcMc=YK`2mAjVV3&JJ_7Wv$e#Z&DS=bOi{KxSdfPH8x9 z)q2q4vt!EfBBOQ?`ru&a>69M0#NJV2M_a%LC%9kGqLT;04=-dP>^(1sYadf2wfc+U zGQSXEWp7Q+NKlFryXoNEIHoiKzJl|%2Wih!AIX(fsGXX_NMfl3EPG3TwbRN1Ht?a; z4BEfZ$E#lV%W3(b%XsA5knqtyzUi=k|F*B**@K4$F}iNMvrPIJbzgH}?;)(Pv_TJX ziB-G&s9yba^%YX9T9qp$Kq>ktQ=>#*bZ_CN)52t?y5^nv&J^9d(aq4KF+m>HXsJ8w zIb?zqCAa7D&2)S8+Y)&vSTcAg#>-)6M@v;qK(Y&^F)(O1f`!rj9JR`G@)&hr7dqS& zSUt?ruDZ#d@1N4fLCZrk>~`eB<9J6(*efwaof9k>l9>K2vJDOMaSg#RCh!I@84q3 zNt{9YKfIgiCi${677=piDV9CkScs$oUXya5ra?Y59cr|u;8$jF{jSS8^(o&U6vYC}k=!F<%5?=yZ-OVGnBYE;+)foX;=#+ZO&MDkqo_mB&-qW@PnUt0QDrVp($!BuWV^y zna2L(SrNU)e5Wl_wudgQnC`Y{_2+P#+y*f%rMTI`Fe4qMrRon)q-t1Wo`s!tR|+i3 z6JBYHXqdhc)st*IeQyZRZ96nM<%DBMUNq_>o{Q|?QSU*elyBNyUZ?$gU=x7kj_DCj zO}4SQBoHC7pW8#>#FSO!dJtK(m@l7bdmfM2c$^#wV!r0m?eTZrQ)2{Z`GoNMx31JB zf;yq(O_)@r>IzNs5NZ7xGc>#Vf`M8-9xB_5h!+>WUJx+S%3!5GjfXJE)aA>JN>Cz2 zGIU*L>1DYeXw^Gj%1wm4jDF%(rP>=5x@!$6;U=g%tb0yR$-!czoe_@0_S0;F7(J&f zl&V~SY0U{c0`VWcI&;1`l%=)!EX!xtYSOp_Epu2aLv&O7yXPgYHcWqMs4<+fXh-ke zs5IeDvf{_vtLNFOwBCcd>8_#H6T2+k?(^0@a0kq~3(cP4$v6;QazNwOzg2@fC+nAy zHHEc9`M8(+d%BW#<5j3*iKvfj8o>$g$YXrvP&sne$3Y|)t@Oz^9RBRgPYBd zJUY3ewnU6#ayzwn4OI&KpW6fz?>>8CPL|}4*RJCB;N_KqTN~=!x=OltgeQM|UZvFU zc#J9W*|Z#HW;gFn!5$$2tHplRExmoc+E4w7yO?X8y5$SIAtBZ1`03X$so8S9<(KSh2S(+MC}|1l0e^TYGfWz#=hGz%1n}Y14LV zvlYSM=h9qGp>7z`(0HaYY`G@7PMx#Y;pS%i8TS9vSv2=tT)!ZaoS(S5(d`86qEac zu9uaVjaS2I9M*D*ofkJL5|j6R_C$Ydd+*FT3B~rG zUcCPJ>8rT{3TzZ}vXlueU=_@`5dN>#b}GSNIT#ly4b?0?bV{z&G8(9n)O5Qus*AZ|WS>MCM#*zp9f1pqI_{)YkR~#7^?s9~V%jFy3~EY1bt{lF4YsW|{8}7n_2w<5&RsrBTWZDwxyU&i zgsM+{lhLqFnF}QQ);h6JAJlFdFma?DEJa=@!OT#E7mc`d2f#d7?tx7~(LAcsl*$pe za~U9NeqXLZ$ey%I;_}*En=TW@?&hc0v8jf^8LQ^Z3x}PHTNJtenwoekQ6Mf;%U_^m zGB2{2D5iXmarsgbb3&aSJ{(T7$ILRV4eFCpv1u!%J<9m4H*1Y8Lq5$b$kY_uUpZZ; zD1Tyj6NVUzZ52RxBS^7ueROxws{AGlP;uZih2t0lEY=5EBnAsDT{3Emcb`xAs#{0l zmuc_r>o13`l?gfy{D-Osos864S}weee)AR+wSD5lO7|uN7p4iLRR+4yP>I;;$aKv@ zy}-XUa>RzdHHkf)lK!bSYtY+uZ-B|?{OyAs^egtKs#adTM#{s)eatV4K>hasd#A*c zVV^udec$1!_fPK+r_Pb-WePl>Y16i)nNfb>Y~R&eXpta7@H`?zy`Wh4-iT34U`ch^ z*6_T)fSK0v2B;xzov#C`O6MhZpLzTODm6;l1gQWEt1vfbXV|P{>;Gi(){p~Q!xZ%} z4h9D5~thhCpQ*yf3uK{F+X;;IvfKbEYgdx2}yFqL0=_Nr8ce z+k_u~^K`S=hrOk!(S9zsLt*~+X(o|oJbW@G4@R%JLdyGUCEXgalbKwaQ0VXI;m5gt zyVrqx#zHZ2q9pkn>zq?_4XnKU>VHLQanQb|I0I>orsg&3&en~$l*k4K3Kkq%ut;G#O$$HoimMhb*5HR72|#*E-D?t##~Vq7XI&X*Ze# zDQqExhNpc#;F#Hw=$${4SxRS>{hsj!b(ytr&0L-}=kEQ9wgi#8gcyxd<<_c-L! z*mAvSi&>(2{`0DaTe?Nhb>cVDbaUmXbC!Nr$HG0Mi#0ES7+vH!r52s!#@s?P$&*)% z3Wsu6qy{)AuH_i1sBYN>#1o!d>u&|=P@wvshK{PKpTLv9ldctVf4HtWeYe#XsS}l9 zg!h8Yww8t_Jf$%bPSWiNy^CBW*tmSFFpzZXA!nH+AxG(o$4`4V!yP-XFz zu!?uY_mV{ce)U5Nm!k%@%n0aFI;fHE?2fpl9I&6MHK%*5s zeYo+#!?sLLA`P>!mBeiO)m3!!UVjsi4E_hYrak-Cj!sqB3Zg3&ujK8g$a`FV{TxXj zHB6ie=MYsEAhtH?&;7ZO{r$nwG&%A?=Nf?YDr_Uxj8ht_u}u1*126r_ImDHBk~L_Z zSKNaX758=u_)PkHb;mqOdOkk{#kpUtrzGL(vsC}`!;OihTfgQWc3yf^k%DzA_MJyT z`Bo~O9z5S3&!d{hpX6OKdw}J*)${UGyVDN+Iz@i^wuAV3M8sh9S(>k>JS(|wpX-vk z%G_LqXWBDOi`c!cop36Z?AMG5p58uqS;u6_?9_dM;n-JXk42YG5pP80V@luq6CV?${|e7r<& zx(~2+8U|{Uz%vyL>v8@(`7pB!-7#S?*K<(aQtG0`>Uns zHZ9aNHTGQ@=V`Go_>EO@cHGNVvG}aZ@iw7!f=9weX)&*g1+IA5#g2BV3cIdHja(Ew zi+}TCnQ&Q;9>A!8_i%XXfU&Y<+cnYanfanCnJrl0x|oNc=J0;SBpX4LBadD5ZKa=h znpb+gyn7JV0QPwsj#Hyb^Eq;F&jDELT~EC>T|<6UM06`Wg!XsUUOk z4w1Dc)-IRlgHUMB`yV+eDLnYW8jG1WHdbR7%Q%vQ(gMmmoI}Ax2yH!AY5W}v{FQOtF zg(~m;FXhKSgsgb>Fl*3>*`4%yh%*{ zj5Z37R-6p}L??!;dI&pSpSX9JG7+sI^E-Lm0y9Km$g`(QL09e>OWV@Q*qzr6Yfuno z%-}X#5(TUKoSK?Ek*8hdNWO3gS3vOWb&fy<8)sm6k(?28NflM5qS6%SmUcM#||>V_)2@kswxq-K%F|c6^aB%!4gYy;2Tzpmrzo4d3@OiCS8=b&RR! zH{~dNbNlYHoF`N6B%ub#64B`V3jd-iQL)%9>3#aEtj!nm{qgi-gzQjOy20yhkYQu) z-!WBDxj@}R!IAUaZK^hPQ<>;!$SxqOGQlQ2!Z3qP zp)zb$;yI??MQJ#mDjLk^d7~QcuUtgQa$i(yB}~wZZ371S&YP&|rguo#v7H%2PoK;~ zOpF4jWpPzJGjpOY3kvsAhM=d;FJs({UzA_InI!ae;PZo!Xe%F&ZJ;Xj?~->QM>DBT zP3Eh@ER$P%#d1|BnJtZ?;yAqAMGqXZifzndXQp@==fq8EQs$uM_15yyX>Nu1ZCG(G zh~~i-gK%TAIdhKp2~nYLgJo2i-l!yVmti4Sr=dsR}UYTIcVd z2ScoaJ!dnn?V`mv@P#-$7jyIqYnDm$o1tzCjf=iKWe?g~)p_f}+9II`^c)}GOg}4% zH-sp~K(MXVYgGx2;&;?4a?NpD!$R%e4`ERK8EowyuRdD+bdaUXMROORQdZqNDo5)> zy0K=fRyi*CPVJ0d&Bd<=L3FMzLN)X?s`HobVj@(#r-NVnew^=U0|(8Dq8Fh zuY5(xWrw@-oBg^8Hc7GpqjTT(maNeEz?a+gkQeg>%p=Ac2`c=25St2)8(4!huX6t?1yqbZEu>33=hqSI#rST ztWlW+S`X8bG@yj`u~5QkR8YY0?id3AKY5CUK_~G3{mPqo%uC>3fKQ=%s97NsBWPoi zC1bWnKmP2|pkkHq_UN4@g9Y_`W7|)-B0tr~8L@xwhw1`fo)HU_^6Dqnsd;Sb2ai|w zM#?9#&RU+nWiuCwzo29u9*v;yRiX>v!=AeSII9i&Asgoxu&r2fatk!M+7k@};l0>p zEaDAX;acWow55f>(X9_VEej}xP<>*QFC95^na^fw=k+a1j+GLD?N^L(0DIBK@uSNs zrjTE5x*ZsOd!@>Xjj+7#2w^S5s!u_liXS$mu%#P}rm~~YET1Wj4%zpYKg>UX;F(?7 zlSWPAJ+)6Da(M9l8=}KXj#}x&sxbdPra0#Y z>_MkbthglB&a5YL3o8&^CY2u8@{>swML>w`NLW~D(4|%vr=mFj@dA*-o9szC41Fsn zPbtVaH9To&ZzY7i&mpU(jXt?C0aehLM_-K+f!i?ESC}?-GCsoa`OV%-_x!15r}y_? zj`d^^ZAdYtQVLkA`2M(aa)r2p_0|&yOz-%@3Kjx7A-SJInM~r&GZTq4@J{5kispE9 zotA%b%Xu4z|Bc(eMTiZ1lie~U*in;(0uZB5wm;b5N4Dinzp?jX!={u8WKjB4?V0N3 z{|XqWVm{y~IqrF0&Wh5p?YX4*G^hJyUdiVhKJ&@`K~VWcI6U0{PIY#5Fhu0rLE?Z znO|zP+)T@8OSYI`d}Phm^KJlX^L-7cBRmW3p*=T4E@ZttT!qUD{u{`=ynFQ@?%&P@ z)FD7lWF}7_baBFg{#xPM7jN3e8fuQi4Mxq$jI*@&?_Ul2=$5hCfM@A4mWaDfk+>sv zxiai%JGdl~#_;1j`w^pikUzq&XWQuFk*oHw69K|8-eb_ihK8fyVbRgtN3w#UB%6Gc z`bZS7k*4|n`#%w=;6}LAPXa_@MnZWL-LeSchK72zP)%5<0{8rjUIFHB3wjL?BRSD$ z4~-7!j$@54`ob@(z(2vJh6MTG{$lg;a^KmMnM#7)y+9iAYy7EVM>`xXCI}rnkr@f} zq2p7THY3u53@M|;UG<)y&@bdLw>-j(mjya`JH7Ng>>jtXBM=g;zNX%j9Pd(d2rctp z7!^_M)|Te-m`LA!fq|tiy=&Lzu>Q_^X&);P%*$8(7(n~I&3WG@-ae4R-h)lVd+(k{p-g91-%sJ9*tNdt#I^5#QaX_eT`yA3 zG^Q_^PxAVGko}SMAxz|0doW;GX8{_kY!WVJqMrk#CzwBeIORyM^46|=Ws|Mhs2B@@ z7l}c{CQ%3hr8meZ())?xW1l2%uP)x_vlkN8$d0S(R9aG)lfm|oiwLCsk@}L$tfQki z6InDaDlI;VyDuCRa_hciCumVPyq#2IiCG(Ft2lnF+pe7rHjI;Wu-}swrr#X?n)uYU z+{h<37{E=pO`st-tJX{NcsTQQxnu=xLn?j_? zr*A0=9)&NgE-H{rm(8WFx=jAiwv#1gqVsMQ`>>9excdIemW+V0w5)xP#;e6>F|KLh zDzIo`evV_0qGA$H6jS$?eA$Z~h z9Su`z79(;Mb#~wNX_v(oCLRSxbQ-qM{u*Q7*GqBiF&=DT3_mkGmTj7oHslC(+MIvA zFK52xT4uE#-1rQj;Y3<^P^(hpQOE`4&fWduH$m!=N5ZO#y4d$-EehN7{Aq~jwkim^ zf2zv!!*T;2j8R;A&Xj|lZ^4V7+2ZD8BN!$oaD8$+TgQR)Mxl=ad9MHJY{)_MgGyC{ z>3F@K1-RhanUvp~>gV2b+Q{aMz3Xpvi;Z7jA8)zK-JFmtNWM|VR0w_T6p>n5UdOh8 zE%CDlBI4`~j=kTH_S}wI52&S#UZI+;soeHgM`Es72O5!f-63>+Txjl25+PlYSS}C^ z)SY*s&EmE98Y0f$-3};hok_cvtet7C{iLO+e~^F}iT$|yQc`;^49SrvOB3RZl~2T}1b+xIeQ$)xy4*gqX5 z#CI!Y>|hu&;$T9I`PMA#O|w&Y?hkt>;yM@#AI6a0XS)*Zkw$haLvBf8aiGBNWIT*X zTFEOed0`zfP?pBf8MJF*XC#Pm3jTb2J@qL^ysZ3b-MWjm+&eP~<$W(F6ZvkX-;sD4 zDaPSOHw#p{K#-2ociy8*n`otN7wq-Squoq-`$_U(2205wg#L#)B)5~=$D~i%2Z%7f z&)~!ET0ct~KoQ1KxHk9`&vti8F1s=&wcIlp=Hu<$hc!iso$FH!s^5-1T503CXFs_} z@{9L(QdhuY*eclml25K`<}FvgJ#IzmX7}{(-UY<>g zoZWsnn%jL6w?Vr9Q=xx@(gSu|ODY!E5&;hTJ?t2!F!m;k(J*uwqm#4Ko|nsc;>mPw zk5~k=AEFk9vp2pz4PhHP*g9ez>!-2RRGik{O^<(gWrY5BdKRQ@-|<5?efb3PYeUfN z8NRM~uQPa2rs~>@kp1}=5muFSXzRmuAK2fGi`HjlqBQHMI!TZ0>c7NMhzE>@b6Jly z^owv&^Y36zViKD3-*xHC7*UrYFg>2lp8Y?VJVJE z1Rz_pJ?23B{0OE0Wl*l{_!2tSiR)QO!6lq0^}HJ7SB(vg8-iE~mWTEpX&B=t%t}Gg zjPlzOPs=4`fL8Vh+Ve$!|5(uk)3yTSI07Opio!uZYB)UB@KL|YqP1OjXQi074W7ou z{+8=HKCFnQ(j@JC5<1GNq=whK8jZwwP4NV+R9Z0?PKDc7cA@WmdNto;R`^A%Csp<4 z6>WhYuzD1mPHDomJGcEz5F3%&0KK!O>}Mkp;0RK(g;&@#!g`A(vbq_>yLS!KBxr za)KzSwKP{-6FR55*a!u6#5?zH+?*#8K@7MkkCqVZ%V+H;w4_KfHW*^?&!i+Am0o?@ zdj-0ub%CapVV?NV{xWor>H>vcbX9tb3n*shkXqn|L#~zK>*D{r2sW(oG0S*5hQDQg zUZDDcHIdu5OKhCd0ni-Cw&aWz+>qH4cgH7hpR{|z6PD^)MiNc4w^R;rFeVv!^4a@go9 ze_WTo+zh3kNv-eY`NP_)KeK5TxD49q_X@(hxtf_59UjT*8|)H6eo^NAaS`&%)#Lo~ z?#wyWf5|V2$46VbMA(iSL#uJvOjtoSNCHEG&HC{hubwOVkdC+%w2MC2wwkvL1*WuZ z0t)#8ooLl1?g@a27=(e{E>k24@m&B6ODd*7 z*nA5e3e(sT7%zwmq0#ih?mPCWB_c$A}|6Q`P|Lz ziIA8V_n$ccN!Q}IT0<^ZU^-Mr&z`mG$3M(z=mtA2jWt|#sk7Ez$%vf2B%md-S{)*9 zt{ljD+ROt7<+_pfUE;0d?J{J8@xJ{P^y}?8na=ep!jXZ|FWCNZu15#UT9yPdc;W#g z!RLql6%diF3|*_BahQe{k)6U%`AIBQl|JIxdbMOk=J2%pSsLa^{ZA9(6L&rd3VdL} z=_}tk{h%ft_Afumdi+>2k>^m5b<_r==nOvh_bZcr&&P^x2a+-6GbewCiQOjXMZ7@! z$81JiLR0w)|5T`yKRN7qKH8V#YC7E=2?t9zMe$MC*11S!QG4c~@$M4hb#LAK%fGC+ zpSf(P9s;hTS!pMmq6P zQBK7pA{GcDuQZq{DRg+G`|!4eUxsuTE1AmtD?(9DjHm~)$8}=}+D4_cr-1&7aKzO{G?}?GMzli1JeLFc~txQ>G|Necg;L$l? zZd>ZjYkb1wUu3S|Evm0IJG2rl!k39wEU~R$@(0AeyI&`E_!Ez&Td?2}E($^|6Ph#C zrbCD@u$NuaT(y6dYEoF>+wfOmJgs^Az4!V4nxYa~R!Zhm&jXt^D{qQ4hb!Yb1EBK-Du4^L*A!7W(*{juioJ zjiiKbA0&oHkO`^96xsm+prtyWkF*&(OEM(@Y=)e-=A9t@_nq-~tr_>HKa*XTvlu_C z5Eu^vIGUJS7J~x8-T_RP*k0Uc8QGo(616oFbhA$+2IVR%S10N;0>7PNWVraSBABVO z#Ca#!VQ;Y@#wqO7cZP_W!J?eBpmvsJaCLa%S`dk`JL*(9^$rX>)X>>?ru&|M>E%9K z9Xh+X4HT`~g?2mkR!Nk?u&cHfRE?GCnWbylPL8%HclC{OlJIlW z@&nr~j6FsSXNKhz><(|e=$uJ=;66kw$WkaIN_YJ}oq;R0mc_|Tu&(69OELi)NyOa* z+r}Ze%2$H^^xrx+fn5?%ia?G`@_iX~Gh6qNCCjC~TNyUE%Cp65+*{#4B8)cvlJ8v! zKAS#dr%*YIi^hBFTi(fx7XH)gh(W;kVnBOB7XjZ^Gvhhx_lv zdfr?>8qgeVPn1*QUccu@@$6mzjV_S%g}XcGi!O*q9&AOKFJil>7`)Q-@}Y@F{Nmf1 z^oqlkCSjI0+WxQXH$M;~4`40*bcn*?tmHteaDolzYUJl#2Q&e(4wIASM{Dm>DLt85 z%hi670SuqIcKbio$X#*nb+}?2mlB)U7p##}g@?j$K8#1jRFgSJD^g12EHS|ElLh6?1tWFvQCp_kN>4 zRJ_4ns95>6IjX>%{X*;|qq)wMd+whtGlOQpPlotA#5Z!Oi&u4^mk@GP-#gS$4@V5$I8|yJa;X;&!c{~$`Euq!WQ_qs*587d4ZNrR9 zsZ1xB-^IKzSf7rQ9mro?AQ_|mdSDr)bi{1_@T9j?01Yqj#f3H<6grbhVGSAdm0=!2 z>)0$}h1sfSxh_ay%Sx|UbPK+HkUk3S==hDTa<|D-vAdg#Mi?e}a%!rGPC=x|5gY+q zc4PgC!57T5UK*yv-dfW>Vp1g4TXL@XlF6!gP@^z9~;4l=$SEaWJ}yqurwa<=2~HW?qd z$P=it5y8J~WCe=9YhRnep?AVl70+3*Eyt5{)zrw+xx?a$QWwU7ufxx#@(9x>{1lt= z=yP7(h8ih0V)@%1iaM=vsL)~ItCqUmheOkIpeY+8uPZK-pSigF;{DU!&~4R->@~D| z0g}jZUpUKtmH4KU?YM*Z$$8=igX=OXOqH4->|PkO?F3_zD(@v8^n7oq`cn`tX&g*h z=UPrlGmS=bYJal9E^VY95sdu;r5S|Z$xBlu{||d_9Tw&G{*5Yv3K)chNJ&a70!oJ> z4T8=LF@%IjNq30|ib038(l9VI3^k-8ARsw3DBTUxXAQ8w-}ju~hW9$xIe)(U5B9#? zj}L3D=U#Vy?$4de?`TqU5y@AN-b$&{78l%<`b6V*hS}~(^wSHU+CaFN?yo6cm+ihY z_V9-)T&8RD*@REds^RBR`u&l{(2<$R_^W-RQ#3d9D!%zW=GO&%XU+I`3x{5abt8&E zp-DbM)+%|i!d`ij&BlOI$WGmBMBp&X^EAHQTt`b@^FJ3EKsnvx4--4SWN;sv56dF2 z36QU;d2}>{BHTdgE;i9Hj6E!?Y!1Sj;du*2$Js-Fcl+(}dXCAaz7(1&+f_UZ5+G$Dxn&N0^jD{SBPKxW8oRcVqcYjI8E z>PKgg6f=m4uGp*fzslqO|IahnTOdSQ3mx+#mZ9REr$)sO|!k zs?8wK|4LSpX~hlG=b_;AYgvmHz7uPaICJ$D0_q*_dw=1u1 zi<#4O729kC3;VsXCisr|+%9fGqHE%&a6dUWL8+2W&!#1&x5Y%xf~XPz7fbH2iIF6K zqP#O;lQG&pCGL0b+W}y0RZdD+nwX!dEx zX1}N%rpC^`+2KFhY_&14Ta^j8Fri8(Fa~v?98vgSHSo=~A!`ayDegDkcX;a@KNm#< z1#Iy?zll@0{_k$Ff@=((pw8~xd^`>Nxag;xWeI`PRuus6H) zSxbm0thmI?}(vK6&DSa>bLY*y|H=kf;J&*U(LsWhg(Ub zWjSU~g=VDUK*eJNuvTEnMSJh+q#gG;gQm>?*?tEg=;@%R$(3J_4HfKN2ROfDJ3hQd zcN98HZefYpk<8QVshleo0QAcNeM#F}%64BNdVnO)DCEbZv(z@srfm$mfq{Od?x1c8 zwOWrP`}oxMb?C#F3s_$UAWWtj ztb+u`)UntkP4yS+dfk14iL;;eu=2kK01-AdIDQ`IFHycYw|67@+Xo84vw^y|#;)eM z|NSi!b4HSzlU?Dg3;Qg9lv%&L)7aE6QjHyG@yVYbZOU9o}=alHxo2 z+;VcQe!bP*#y(7@$ZY^pQF+u0MG0ToyM0XK2-N~86mJE>B~=Iv+waWa@x70xwqK~Y zH=O*FgS8E@4H(-rCxb{?mG2WrPw;`PO3l+gE^``YWwkS7AbF%-{Ucqs4_f{HV*erL zQ|gvq!ftfmLG!&~lqcA|oj#o(J(k~f5aUZm^+bNQnfpqE_+U@qD>a5X(DFiInEdJi-gyop2f#%7a@P#m4zfqQla#6J`KT-qcvoIT zYLd^T7^orTZC))sBqKpL5Ub43f>44qpN#3&x9A)rwyGz86tZsEc(tc&Jy?Aev++La z0!cF+K)2e}_ok^P##Hg41*1Cb=8zis-G0+`6(Il7QmEpdDYpEOPJXA?IKJ1w+RK*2 zZPyxKrk~uTPD`*g60#ksXOnq{VW z29p8@fypBzdL~mtx7RE|#PJGZRSiJIY(KA#(TnJ~-O+uOvO1Y#Z-=k29M1|3)f-Ds z9YeaA1(o;+q7N}4E9|suyYzGR-Y}g&!CnPYfIly7FJ}=h4#x|ipVtHvI&2|b-j_hc zW}iVFOTno=71LP%@%re11wYU9?o@heoZZ!TOWo)%m|Od$)6@&|#lyS+ZDEZO$MUxU zG{(xJ+LZg}Wz}0D*F06D_}RZfZURax`lgHK1E}h*TW#ll<|SuD)feJ9e^E-Ajr+7| z%G>cE$s!#ZN{)2(|uApydDbv_zQyBvXDUl z5`Bg#dfKUBlxo%t-K$xWEz*A0iZ{BdVoXz!*Qn3wVl>MiIV!!wmbP4bRs4`y06V1x zOJjGr=A->&r$=NTXy1)z`~IwvZFV_EF*fmWyC>1*YH_U7!*fcB)D;^A6($tnP zUg9Q<|1*5BH$4Ajz3go(eUlon!^1aSW)?y7`5~1{NVs1TRMjmhNAE#rP07he|YbL{m*=o=CK9aQJx1CS~yt^^F1MV+3BEMI? z!QYGoMUU~&b3@JKD_GE$1m{`&GXVWEOT7troGBX{KH2kyv&GW~a$xs1A;0sa>xy6^ zdc8aPIbeBtv{=|MI0LJ6sS;hf2^q(2W-VOxE|^IZ7s)q$rvum^k`6VS&NxDXDB1RoIM65NOa06g@7jZG5CK#W@|w zVv0r4VWj~Z!R6~!zwX?4ey2q4@v`T^;z2W;D&A{^zL1Dtyg#*|K5&kn)jwnoiNG|1 zxdV)TPv?$b{*L=>mOIH)Fe{<;y+Qw5o8lGCR-u`o5iARr1g96^o=05}o`Nu7o5t%F z9-ohI=RYVmkBsO%N7eYH;Trzo5{YjHHuAGGD5XS!za(*7LD5Ui6F#jze+DNAkiQ># zsHK3*r8no9x9iL%;Ctv0&|`;Yj=-~AHWw@a4?}E`O(TN=E-X0_dFBVe=ayEj0xBBy zHb`7L=;oZ}Wd=+$SQr4k!hg6-rtnult^6Kv?6@IH8Zrt#0d-h;;(Y`tbqvzjE*`qf zI3%*`RAf0$4uJKFK}v7*`(Yyyp4C3`uf_Jyh1UZyJmNA5vlju=Rj_qiKvPp-(w>yQhhgHFl}kRxEhOLkH;R~c zLs%ea`aOeZiG9qF+3V-e1Eqn&r%;?PN30uxg}8q(X~4T%rBBM7=VCwam3K^F(CF~- zvC!$KKFxS|>Rc$0DhC%f&@6e$1#+haYS%4)esu?$YvS(A2kpdAVNr^hEQUY4{R9*cfhq#oe_6qv*Td zPzA?uo;-(;RKDu!rs;S4kr^}Hoha)2R`eO(3#{T>eq)o9GV7GNJ%V0{wkO$0WV^M~ zuRZ3$;9wFdSfWf*+~Is){abn=BW9+iV}F;=H#9YcfE2vk%a;pj#qT!TR9TJQg28VR z4{_iJjDHLau#@<_ZV})PCsI+pu1r+4uS7gt4xFPpi|fWc@;2HD7wIPU_;eD+YXJ^ApPV?2;eqhRMXWJA1ehLF}xnax<`WIy%f!VbDEf# z80deKJQ{>d$>jy0f(qK&u|03T@9v7Q@x)WFo5q(1_(KA;fd-OeHpe)s1xV-HZm z4zGMs73%J|GG?<-r4QLJ}=2RA#2)Ty}jxSIy3px|}UFSo=t*M7j1sM|*p6TG}tA zq{+>+Cwq0+@1Vy(P*>~P`Ot1MhL}cLZq)~4!d!f6#yRj|NUUNR9U+HOa zCEAR%J8PSY@JJe$nXLZQ;hUJ7+b!zG#?k~wMNPbhf}xDt_w9d1H||V*4zZQMCHnjY z2oURwdfPs*>sMECUoWbD`c$8sm{51HjkUgK9)b=Q_^ zmB5r!Qd@JIZt!akzx4n7p@@rJ|4l2h-?B_rWH^!*K$3fd+cm%atF+%_{>0zw)s`(WnEpc((*9UW=tUBaFGNZ|? zFD~F*tn-#win6r87n|5_T~uAZEnspEyjgEiVS6EIQKfqG*3K|GY0>i>;l96qWqi*f z`^JvklH)amo>670ot<6W?r?82?YRHey%7UDd_PiI*QE(T@kQ1k&rRGI()UeN%9}wDWU`vMa(zSng7V7SNsPrOW_IeEc!X94iB6mA;e2^yqtObZ&u>`#YzuS1No>84%;X_2s z3$knT@sKBqN=o*>*>`3peKu9aH)$Q2GFDjq&j37v*>p4`zdO20; zo3{uxFC#l&Rwnk)dFEhn!UlH^{7Ev;#D|9qI8BOp1L=Ht>u6sLbA|#kC*3)4JSeiI z+6pQh81WT4@B`;j&X&^^xO7!b$|=WTbsmU%9ix@Kukx7DDOY+a>lNKX7ZK{cl@l@Q zJ<;vg&G>NXSM{g7T2b%l&HP>$Zl(JF&r5cE`>O6!{IhDQqg4abeQ~Mh+6lS^>=U2! z=sZ}K&Wv{+ev5xqMU<0Rjrw4Oy+%@Ygk7rYq5!KE*;(4?lLh^@*Rh$wrTr2kguS@` zzUB=KA(Z~*V?4ArDSl95XlNMYEFGUEInroM z^T_t(!;sLcJGMi0gAMOb+!;`ycd@$fI>rkDkg>9~U_5r($$n|fTN zetK)}DZh$7>gZRoM=`!~KY6+^2w<>R@j3hgQd3iNto2~GH5rZe=&YBNl1dn`$J{dn z!-Esii%vZ^y%0`Qczq{)jl<2ffiuEt_O>bK4ZjnQ{0z=AJ=Q@O6|yq&{_^!}HKe33 zchns_bI#7*-d9wBgoGq1Elrl4oqa4^>tztgMZT@bb{Y<>f|PF(&7V918Qk$B(Se{U znjB6!UZTZAGrw>Swk#(5r_dc2`KQqM1=ez%w7ZAw$G3mpsOYrY?{s|omxWyP2e@%y zcNWfEIc?&%D(TUQsm^*hd_3jE?f@Hs)hc&rnU-CgaA3=QcMAwllUA?}?3W1I;O#%{ zEJ-}~L0N$0A{2)mA}ufxrggcoSJq~rIt>pXWo>7#+K`3`pMb7d#8exGNsA{)Ij zvUJ-1_>asBS>b|l{b|n`9KUx|k|g^rumIVj56VuE9js8%s~x}BgePD0lxtasI5vow zHqucCU=yt`SUH`xzo=JqFaLn&G&l1PgUS;m_+9Stdzb0`Ftwzp_n5e^+NbR={rJ5F z5xul0yc6rL{DEL&yNmE|vr~T7W#HeabN59~+22E@s;l>wfsM=B>AiExb9L&+?{x~S zoBfRs|7O5czXQaz9#e2)YCFhd)TP?kNsL5N*mamfwR=7?Jwcj`Ag{Do1;AC z9Q1+nfPJsNi0q&BrT?RT|53kfv#*ARbWC2p41eLz9%qP#8H$S zm6Vbq*otqr9m9T-Kvdm2)~2d+Rt~3WUF*X@9UQ;uk2)0tAZ9}p>+9=zMor|s`IF~N zEG)H>-_ zhZm$kvOviOOw;`V>fFAA8(<)`z9bu=khbf*W>$L_lV!zvIHBmET}Lzb?)czeFvo6X zz_zuNzC8mH(HP9E0GG~ANnvpYrM)r0#yHfqBU-dtvOQyF*ci&@-l|pAB=v%v#LUcW z)^%t{4|ECG^cqE!ScQms0+^ulOuD_AhQ_pZ*02GgnTFoaqRY@52qZH2@{P>-J#WoD zflkYCE@71xK!eoK+)S3;TDAUqSWEiuEDvFPa!Shi_=&^l{NJ1d39MNLiAc!D3;6$A zw*(s+r`cClIx3E^@9qnOfv<#=8dHrmQ1ZE4J&29XduUGI_-i3@mM9VD_vby4p>iQC zCEj=-)k8KDV@odU;ejTkq7iYDxI&ZB{^d!TR%?a~z)Lynf6aPKVJSORI*W9a{GvDY zVg!wCspg4+z+fBzHS6-j3v5?;3pi-{U8&~I01X0%+(PggargEL21iD+fzp;^SmNt> zCjdOs9%*Fv!RwBl#nB)i=_^@vrvTZQnP4&wXsJA`=&B|7-+s-XiPJ82_w_M=o_NQz z_ss%&LEQz4uv4;qyLuiuCy02%|5Tzet~f()BMJi`QYE|=eNQp<(B;N$bnY@r-G`gd zN!zx$P)$|!H~R;?)`092Em!Wb`5b#;u%&ypo zBBbPkqhz_kY&43cTv1JlsjbO-rp$=>_MsteP?h%qkWyJrL$XV74b+R~D1`PDYtMT| z8B;^R4S~JW8G>0F`6wr8t@8w_!H>Y7(1fZ7SoSwdpd>@7v$yo<^`gAPg zC77lsUG&m@P_(Ej&?mSCAAZ@q15{W!T{qlD*bTKEdQI8b*si1A@9cl0&+HT9tHh?;KgV3|Y`^w*ddsar1xlXwnDP@Io>Y$m&X1@5$P!;CF z+zLt@*U})v69ORK^x%7M0|B6q<+ zE@MG5@R5cLLk;={_6GnHXSrS?s_A1=nyFKv`9M3FoAP-*2S@Z+Tz{qK@aOYLTK6?o z7%?X!W38Yj9_ONdSBFd0sfDFh_BsBon3ZfmCF@7&cEE##ypdTeYAwRq1w zM=ZVj6@1K#LpXf!;&4v2KP2lc(#WP7FSSN@L+Cg!`ae%WV(!>kpZk76=Ct5q>Nseb z@;^Jg5L*Rt(#G`n_fx!x;x)>ETYn>?QfHqnzKgIi`kGqdD&Bd!JAFpcm;hd}R6~f= zSJT%|7_h4S#C!Wy=OTUT*7Ln><1xUa7XnJ24S;6-Tc7#OJA|(_{$ejYW(49Rvj2B9 z&kUoSg;OZOT{^`;;X&0z0BaR1lLXy1EHpGU+>}LbTQ)GSS-w<Eg#UZzqd19lMK^j9sh;;SgMad#H+QM& z=petQ8W-?(yQ)2YJQ5cz;%qbQproX<()na|z#}WK%P1ntp?@Qbs0Kh_oTZ1H3=qQp zcs2fXmZ8IY3(SHpYia!-Agxh?wkhg2K>sD;YZ6(W-E;|6d*1{*95iUuh#FgLa2FO9 zu1rK*mj3Ga$Ih&?EedUbj(9o;vZ6W4RN(+H@$d&AY)C?*hvpf0cvQfD^8li3YciCY zn%en=?T=mvP(dq|f5y+x&;1ar+X4;+QBqRY=m0b=rvOUR6fEtZUUM9@y%K6nx zmEuy1hn%BsE%^9oq_M>wumP`t4w4cF=YU9Hb^z64m~E@}1dauCy(t_JikIj`#fDsu z_1wn`j*gzy$)ADVxF^O+=kfQedRXpkcBSMw_$m_{Te|K@W0pvrCnsp!3>aVs&2$dg zF6UsNVa9%5PEIbYuaA-HR{towZ((tR4T8wHKH+K+q5VLV{g#lIE*u-P$FdrpkA4RB4Mox}; z99ltp32tv^_YU$sZzR|eJ4px;V|4FTA~9-(7Lnc{WiVU7fbpPECVcuk3g|qDy810< z=44PooaxRT=?BwFRG<~|8w<+iUWgAo=!Y$$oABJ3r>R=yUL1t}Tp*kQ+Qn#fLJ6yc zO(9uOer;xOi)nbB97^3+sZJ6!Q2#x0y6x)ExSo~^>;btztkd1|DF7wL3k*=%BtU`% z(+C$SXlh0wtoT50s)um?tB&pUR#^xn3{XZ%aE=(|HCe;L!WP^>0D=PokoA`W zW20@C;9Xr^Cc0u=pCnBF$29DyuIzRxeMHu0;!G? z5Nrshcp*S2m!-G<2AU%@!mfr51oqfnBS*h~YHa`x3pSv{>(5O1T+Hwp?}t7yiWdd! zlFrUw8c?q7Ab1v05*P!i)IWkg{EM!Bcl9_kM`z#zJuzJlYR6N@8Q`|XP3v44Y{+0h z&$*W5>$9OCCG{HWr%As$5u057`g_XmpZMyILsPsTQyKq+9sBk z5uly131G*VgU_@A%n(+dxxW}b%ee6prJ6|+ac{t=9zbxi&gZr`gyj^OJ1gmU?%7XI zO$B1D0Cu7XVvP&hhP4c2WoOGxyOODx2%r9$Sy%{v3vGzfXf;Mh^d8( z3ks^wrY9sYuyJzQ(SkuQc3*jfi<`K$vc6_KaaYsU=E8c6b7mSEk-lTyvd+$iH%r7` z(4KgL50A@h3=7X4PR{F|!Lj})Lua>CSE_-FWSI4u?;q}v=y*)Syh?RT(+-#_X>63I@XyQnRbbLFw$hYsRsE%< zMcElp#5RJ4@+o$iLAO;d_v#EQVA@O}wfsmFN*#&bj`DzHf&dm9&Dl&nPF9yjd?iOv z7rCsD>)%WV;eaZL(d=VJY@5PkQz7{+5d#BoK@d4~59d6qCqHfGQ0}(p%7VGUR4{=R8zD4-=tJAaN8_si%`AK$JhODR|<1; zRRKjkJ_S{t{8MmUf)IR0JD>&M`@Bz)oP&cu+%?PROG>G>mOTQaJDhMfK{?CHJ_O8U zsuiW%Rk61Zduc|7%-~mah=jUn{$Ypm-@DgDsv?3UtGt2>qgm@x4ZwD1Gp-r1r}G;FQ8e=dCRc+CZQ79wQI7^ zpQjM&e6vp+&9t7MpVz;c8y-$RY3vVzcI$5WC~TGeU+=>R#nFPsBibGcpSGZ<;5jT} z#57wua2+466zD&}ck=U}UmX=iOmVI#DxaMF@WKaaJ#4a?<%iy-bv}H!5BvA+e_!a~ zk^Z06f<)5)Ia?sh|3?!3UrWL$i&dffj)ODc(@f6DkiSBQ3_>DX0)2ad2Qb#8yPwzD z)ztt)uY?5_6@~$wBQ(e!N9^F|@Bwvt-m?n4u5m;85f?dSf^clo;M^ zkT!h+1vs^MgVXBGe8)aEpUjz^6GIrVP<3po>(k;n7#QUf>bkI{Fh4o;Zrg?L9IQJK zka_3?zBjxmB>FOIP;F9L8jPAmK6l3)Yz;R{GKV6SNc zncnNxbO8<{jZ|yKo*Tw_h7G~*`pG}gfXaoB(Em1~$L6v?M1TMM3ECa2H0z|W=j=v@ zDxELt2QfC+pZ!mdMrOX>unbjk`$I}x%tbB?%sHXG|7oxigPTVV`geUMt4pUHtFr#L zxc>Oh4so;D-!Wbsv%dg~|K_@xqhs;hu%`sphj$=t#L-~XXl!aS0)$33<6$s)Gc&}1 z=fNH}YV$|gKtU`8DEt*BT4FhTe0<#B#t2wMfe4^-(N$cO-fBE`C?V?M7^TARGphW0&EXP8sKxELrSrJc5gj#uG*#uME?TJ+%5|d%3)Kx_-#e_1>~p; zF`X5ciX+ClQnzWZ+pOR}Qb(z9$y=D|B8I7|e^wxpeSBnD#OOo#U zsh-=ZHotu+N^ghzcMyRpx!*a>KfHyM^1;Hu0HxfR(}PUR=(Y=I3Zl)MMkmA0|74Sd+(P)m)19n}WuEipVK8Uot1HKNw$?rFOic^x%wF5MfWY^g^lIispRLC6Ns= zQj~9h=|<+hEsthecN_t(Sx7q$#=0z=)o5&{P_$|O)4_k8;=j5_61e3VV}1UVTYtL% ztKmM*R(0`sEGuLQb%|Srg@iDQ1JcN3nFpM@yMHK>zkZc;<&hNIY7h?u$zL7p&5ma3`u)L3M(XMtJAp1a zm_mh}0Nv#`2xTZzUS0{qetiShRVeQZ`Dt|!To~-TKW>jGdPaI?5QeBCPD6dY`c&j^ z#qYA~-l}tW4xbM1QI!+fuikAcxC4Yy#W(f>B)s!|$VLo8tT&77Rw0#<3heEgL!p^f zX|uZ}S-E{rR*(M>zxhHe;3MYFPv@JjB$fgoF{R;JVIx)RgF1w8 z%(^D>VCU7Q<`4q2LR%KD_3fGaT*mcMGiP5W<6ir6Sv4E^GygTgOC?A8a%GD?aqF}b z&cvRuBC4tjv|^7VboVl#h(06)fgTmI1k-s}e0bcxW;25N28-_gN-qXpQ8YYPwDRquHqMv=28yz%eC#!<&R1WGQyM=6cpvI?tZgFy!q-W4Kk_! zcrx(>QxEqS9I`ZfhZ4v*Zxp^Z3OSE*;p2(rOm_}pVlL(*Du4fbdfA!D_b)YQjoH2V z1v9^}0nL&auv^j1_bn(rhglimm22qmBu_B<=cTwrOUcJu9{-ilcG{M4u;Eptl@~$} zg$=5a?P2SQK3Q|li!1Y%o?5_~ae=lI8&KsgYlIaKIz&5?ZGNumq7S~~T9fU?fiUc9 zd(0L4iC=RoK_NJArQnbBS0>|$GIprJ`5#{Y*vg-{E__a1y*57~g#{UGer(r+p|_>g zR$1$r44Wr|?##Med2hTtC)O+RPB!ML(pS_u|B(PVVI=hX? z;RCdkGq~Unfm}lok;63#v4Drf5!#Hesvcgm!mRk#why)mIbc@&E;bAP#|u^kRuSt9 zs?NAMoMt`mV4>)TK3d}W z;LO&7VG1}NGmw2iTe|x?@BMGto8DSNsBQk3^ z-gJvPzLil`!YBfKs#mfHX3kzo6s;eJ3aPFB<3@O?9z$^x`^M)ko#GVzkv)txj6k_Y zm5hvR1$d&0I!?cRBp)PXX8y!W1D?Vd;E4#+-J5{{L_@iU7Xn+d1^{&DND=3}axgbz z#hY$d@0Z7%ADG`J1L!fh00miPe}p45=&ktF<~bKp1u26T30WHkoRj7FoY|Gt_=wJ1 z^f=-DiU%)q#b_s2e%f3tqf3>5xx%oB$(ZcpcFB^nVW(X0O&|upSa1K;6jR6^_i@i& z{coT_FLoTxxcSp)o(4Dz!X|~W;mpB?tn4+b6l0RHUuEWg2QaZm_I?J7F@2e@cksHtem_s=&3gYXOZYy*5`p6U4jsdU8JV9WJxZmcUlV#77POKsR|k!#l6t)HEThZ#t1PyNdIV z&UqyKo{7 z!p@GyLJn$uv&^G2GdW8D#*Il_+;fE6ZBNt-@uMsoQ7Eb0Id?@duDcOxg7<`Bn9cQ{ z0MDB3S4S_4h5b%aS(bGBhg1b$&#}S_@S>3uyz8( zZ3uwL+*$+7L+p$O%YVMv0GcIvfKeO(BPtW~S`o-nd9j_|R{uuycNbQWfhS#jk=9++ zbwy5AF?_8(GB`AxruRxOFvy2Cj^)iOci$J;*`c8^`j@qvBkDST=Cnq)GCu3b#ojQY zAc^5Z5v}a;5XQ1_nNA{s|GFmkLH7?9yewovvBK~l0sNnF$lpUSup133FL$}5b&zF# z-h%jQ$O~K~sER$>s$&%+w(i%@JqJoMh)oB3S%of#X>$<<6X^~neoM8#!UhV*C-wO; z4)p7K-S5Hn!6DA;$+pZDPA=+`t&>4HJv|q}ZYasThT>ids;)}bVOCU4E(!nFr2uo^ z4)IQx``ybAlcFd55Ibx;0s$T%G7`hmbTZPiw_Sw0k8|h-*|v(_`&0By{{kp4gBT@=YMNh<$fq@WlmWiV`BQ zavQNItFNzLXYt|Nm5Xp6#1IG9h2b#&(YMT5C@D4DrkX+G{v+`s%BxzA<&jkw7hqF& zDul{JF$M<`t%&u|i{UC$53vnea0TBniAy3=zMQM-MvG7Uv5WX!$ty^)@XAVd(tdM2 zGjsM+7Tqn@U=1;q{%`i>srgF&6~&S+LMpN?YpZaw-*1vaKX3NRQvK4bc;eDmTM-^G zb}{q6`E(+`BguK6^tPA$-?Y>5pZ(D|PQ&D#T>=5=51^+Qs0b6UqZ)ty49)i3o8<-A zoOgZKuo*6&)Zs2Qp5_Zf!EfrAV(A5SNrIo$_7iK}Br*bG!98s*ltI=L%p}ODQn_u= zKJy}1ovd_pv63F@Tvf(oJSN{(a&PA0(DYF1=z{g=1s;Wtw^{|-6>0@@&*gaHh#f6H zzCF)B*E5A|kTcOxL;WqiEyb~HMb2pHjhB_tec+uG(HxYgAO`Myhzxq!q`N?F0i1q# z=W8}Ks|~W?U@e!Z!o9s4v_VCsd%;onLw@Oy09rSe2M(?3k;?jC-LATp6wOU)dwb7eZL*VrrTSm zjf10^1@Bs}U7g4m?M82yrT1@Zu~jUMQr*%ag#t?LSQ~JQE8%%5-0vZG?{oi0z^ZN^ z*Bm~#jGFvMBmK`$vQ%*xzA`lyKzy6vaKkpmLgfg{ z0km?d)h6M2@wIrz56S}Nk6864%6uIPX(KX>!A#$b1}Zj9mk=}WO-@sRJ*jgnJTnis zNFwc~ErL}AFgv^fqwp{Lv8hS>^Yz+=Q4KIR9bVS>yXGH+{ULJetKuCEW5UU6e^li5 zdm}#JDVv-0?UeRBTn+bLly#IrM4QKb4xeWE9HFx-2P3Y>@g8+I>DkYu_L$a9uGrVB ze4^CA9sE8TeY3YCV%=422%X-$`)XsfR{wY4bn&jw*iUs@OC{>UjkOIsh4Ckztj#;a zcB4*>Q3w3D-1ITuqK5aRvMXH&44>cFbhwOk*+^A8XbD-+6r3*=zfmxl#?O1jp>wdC z=|cSOjjVT_Ob(xZe75UOE1dat*OO;`Q7j7+yH&c#Gqv*;+Cn9xV77i`&w2Zkf9|~` z#Q1066Wtdl6f%Ty2GxbGNgDUJJ*Gjmm^$UZn7+*Y3wE&Zq&;U;P)@!%bfw7>mYsjW zf})YMVlZ|ay&u=l2Vs}o{1z`<{5!whmlEGvrnx>TT&7-|7Q%E# z(4y+P&w+(XJ-%SU{v!X#j{m~g(|4_6si|bjwwRyg`OuQ3vFVH}nvZP`5;x^n(f0-> zE7CC@8U*BU{xSYro!zv<>%lt%dJreB9KNwdf^D(BFA$P>w?>`=gNA5ZIr#4K#hsrn zFKPqU^LtCwY|wjdyDbd9S*^?^WqXG7As7ftN0rB#iasZOM#_Ks0QR9?>T ztQ+YtPJK}p1!1#2U-yrXT8m)=y%bma^=`a{-0=7VSc{OAPgYt>q*%#Q8-rl`+MGY` zbfF8sk_$roHN#K^mM0omk2y_>(Z z+fkDc3_T$!8Fz_twx6K;<;=kqUHvW|p&MrQQX6WQ)A#)d!?wAIemP3r6q}kB`OO}u z@ui)mU5nn9&(qg?k#6*kl@Y|{N~K+80o^K7H`Pb?c8E?oYI&BbThkQrsGz{)T~2{f5l}b6y>dv6Jnd_L@muBI60dD<1eQ&h{v#c`qtG!$OAgT(A z*TwXDpvA53amByl@x&???Q7>sk!oL;DgYrsOMfw&pwM)7xg0pwA4yXKl*1WD*w6)T9$ZrPSV! zwN@%->c98V@HZK!LiidP+%xXR0G559^yLkEA;H_D=4lYdR02>ZbqVRgpj;}h4S_Z&J^P-#;M}EB=2m+NPyHUU# ztSY9GN#c*d=^0{}X1@FO5?eqQ)1LC>-l8rVt7nKH=+F1#lf(!Cj9Q6OX@B(2_e4D3 z{s3AlNh?A^*7!>w`Uy7TLR5JbhFjIPy934~?_+FSvoF2r9tN#{IAUIiC+b60VG!8Q z?u-z>^l5!E87+hZs?}g)-|%M3`y1#5K<9G(y=YhPZ#w65Fnm8hHS1CB;CqW|d%X${ zH#9CTFMSYqe5U5gpo0V3{=SgmKJDo%UUE^#Z_>;eH}%{9(zkvSL`T^EPa>gE$SJ9t zD%cU^pb_@KbdE}4gx$^z!P}*_W7E^7m}b&7o~_x^ZOya~c(2Uq09>*( zfDh)LkXrTtcya|6*O4?9_O62u6){5{PcP+EvRj7ChN$H;F{jG*3qDkr6us>!-`0MkfU5-g9`Y7SBG? zf}-*b{Y7H2WP{9#uZ^F+c9zQ_bFu+{GsPXXdH2FA1F2&NL_75jhB6kIXaCAJ zaMLdL?=@OjTctY-5^YEPTBnazlrXuM|<>tGi z?m|#`1eV%dGKH=3%o?6?7xv4q*oQMx!S;}J+qTHFBxbH}xBF4W@895Sn!Fs*H>i*~ z=oNB^?YPi~cF8L3m@2XsPd$fZ^WOM6`bB%E3EAqvWk;sklG9w}9<#6m;D*{+LXZ4m zv-S_O(;bv({|uDxTvDfY5Z`gQd?f~!;7A6uxaD+NfTLJteTmy^HcMM&-u>CsCi#s3 z=+=+!%T7Io$OHS{jo!822(`jxI#8iOrYBQ)Hu}7t+qN57uC%!+Ha#6guy?&l*eq-| zQBUi;X)qd3P?NtZG)Ala-h{UW<$@Wfc)+Eul!~h!%@Fd&NPBdsu1A^SNBUpF?PAnU z<&U$+i`+q3H*sB%1s>of27urX#Sx{6VDZ1QuIBl*V#ZxVR5({<>#JjsBA%5SI0e0H$f3VQGzNs>ZxSV_KK0ZlD^)cWfdHX7b&` zKF{rq=J<}>;JaiwOU8+k=P=(>)%_+U%vuKRHTLuP;HpBoO@*WG z3B|u+7S)R10>?0cY`c5ihxsib{F9yAnl_?qh|APGevp(TMBBd2A&caNyCudNF=8A~ zI=^>+>X~kZ!icDiAuXdt;=HF~_PC~8msr5%&B$g~^#20grTixxa~SnvJjG9_>N)QG z$fY4g3sQL@ew8({IQG|hM$6J>mXmDjC|leK_d;|7iZtbOLZ4i9Z9^pOpJzm0i@Y<< z8CkG$m#Rl&tVV`BMsTT4SK))N2aEQ$Ae+!8OYTzbzRZF(X@~73d;sP=@uR7-UE;@s z(s)Jdukj`yRAL7%(sfzved%J=l*6*Q(zz=;D7JaxWx*CE2N0Ch0M2kJd#7)aM8EsAaTb$@Yi#bjcKh zMGGrZsph(jGpJGcu3T)Wc(29tu*dB2+gc`Va-q(v(DVX*nt`CnPCqp&N>5kk@YAZx#}9kAmtL0 zw9x?Z!+xymAar8S5=HdRXQEyHIcnynLniR$O;Nu?gnn-(dT;A78MO6>Ki=srvskje z6|$!Ff3f$TVNGpK*s#)65aEad(rutfmEKWQRO&$?2mu6?DiEc2QHn}cM5G23h!6-J zLhm3VozPoAdI>#1Nb+t(&Uqevcz=E0pZChYi2K@m?O8MT%-l134ev-qv>Fk3Iew=1 z#};d@Q;5Ir=Pl@^7`x5Hn(3%dPzfntM{WdCA=cb!3Qq|X0WUaGb_dGJhRk_g&sd-4 z?HuQ?exj%?RL!Iy!KCVwHCR{hBJ9!E$=$5b%TRqfpO60Isj`%aX=KmB+LWB6@IcAa zJh^#~4LOHM(M8vMOjfufm`R|hg)-0z_4T@cTyXy4I+_eLX*S+|J&^HP&N1AE$kmw~ zBKrDk@u-0kUui^ojs}oTOuaA??;Gas;{?KCLxqrHuD5>Y7NYOv-N=;LmPFo{!+Nhx zt-mfOWZ!-56zq7GFQfPoLwkVrXEhy#m6eL7Wvs+q^Cn?uHX7c?ADU6t?Kba{dxjpa zzZ+ey-kPNaPqdbNU%$CZ$Y42{rI~@Wj%T;~l0D+(P(dh_P3TE&mVR4t5#qug+Sl27 znnv!C+Jn*UYQwCjUZYPvL!~xDel#1L4c8%t5->29_^i7(XfYL|r6~s9Fqwu*bumd1 z-vGaYLHDR~^T%onn0CD~B^GD9?&kx-67loJ%xp)huvsmW+h^g_A*c(U__L8Io^}== zC2l?wJ?ftFFy=w+%IfVb!BQh7Ai?hs7#{B(*F;QI*#H#4n>BmYB#tV3w#FV!FC822 z;Y#i4o}RX0SShr%w1+tAin8(4#Ss+Nq8+ZMjO_4ZrP}2M7rlSjX2|2*Ao<1>>Luvb zST1l)Rnt>!d_H$+x9#TlAhcq;<7@s!-Euw^i_?rTi;p5KDmqPk=X8a9c{7 zIO=1bjU9j}h`2d*Vj&Mlc}+XOSXV*&6{$rQB(c4stM#?rT84rUR_|%2fk4}1=qlfBTWE$&l-mOFgvVl6t9n5*I&zV&>3o-Xe|7^wFFvhjB~aOc zzi=b_-%9I^UzOII-T;^Xe@WC|1@8ruZ<>2w;XVVwWLY4Pb}RN8V=P{LpYWJ-Akj{gw+p$u)W;sO1#7-R!u$|XIsfeGte zw;u^=yr@HpTDL+}dm58=6K)$*h7me>S11iLZMs`qVaHKU-H+qF1?CR#7X1WNjT;bP ztY=1gL9<^6uWg%9q(AeC>7)nNp?)df1h(?vv6@8!^wd}M+&yX;una(QJLxi6PZ(};B+#LO_j{9^0bI=qNv+(S%)v;OFQl%A7G=j^i!05esn{39^vzcyyw9Csk*201 zHP_9TlHqJMnbRoSK2fNl&w~VD3B{)(iIyi zJ9Yeaf9o5(Y6*R~*Sdg{P5xX~oO4#NnNdDL`5E}7s(_-IPj>AM(6w(Hk5T$57A_rR z@m2J1ouP@cCk$J|J8TB?p~ojT>`bF|dSjf1K;$;EMfM=iCuN5B7VwW>0Y#e>_tq?~ zFYzDsKmSY);j9A^p7(OhV|xl8>t|4bH4K~hWT(@*EN%+wx6BKx)ll}go?puHd?3Te z_BK{qXu7N}M8Yh5ZC#g9G54u8rUu~_B{nLm@-uu%e@lh9^_foDjUQVeQtSg)q`wr~ zD*PFZmTT>lJ27Q0HaKT3iMco2YOX|u5PjtFLz@yX*rGu=G_cA)y#L9#wQ{QX?1?ig_o}d) z6!<|~?Nj_=X3&^bz8kozre~XV&^hK z+czGYzdlu47S(U-rl!ew1OGW83a8+fiQg4N5IY3yV!n>NmB5 zDLuUPN;9tDZkoC}w0NUQPy10K&AoYI^N>lzvvjLl0LjzIRT+%njnD=^HKxm0d4!8C z-F9Mn^u=w12jQmGop)2Kd^i5FS2Ow&AOt&TB|; zcQc%M=FzY!F#m`lA%mszJ)C$SKK|W#fZcOWIOFOn5zGpFL8o1Hw@WdIA0X8(D(A6i z;j)$f0)^yI-`6R+lmU68S~Tl@2WWkezO3DvY+E7Iy%s~PUXRdbv)*13J4RK*m-LX~ zbH;VunTybO?^fk`8~glhV=Q)fm_KGcyfwVjG>E+0`Q~A;yWvxH#_PFttjL^3WMat8 zfdI<7>kH-swxd@&?rc}BKVf@sJ=(y__yCoAJMlyf# z2c_3*Bpa>nZLQG_Q8>x8cBiqke25jj1bG~e=70adZ5cM$n(x;RaIRX>c~&1Nd+z3$ zfB}LB)1589vK_j%y?ZD5^f9C575$51nS*L(nFHHlteiU9t!W;*k{us_uk`vY&bGXx zQAim;v^6dTBQi6_UTL$k_STQO`>I6?W(&n?2X;aHci#s5pe+N^sE3dG>J$U8#Tr_fJyVMtW;WxT$XTmy=!Vy$!y4AO zA6F{4`~oxd9z2XO#biWAk37I#dAy=cgqEA(Xuv=|>HQH zOUL`hYv0OgWoS1<=f8-fTu*f3hj{wz9cJCZmC?ZUSH#i`jyqM zn!zlVqgJBZLN01KPWJ~Not?jTcsjA)tTp(~C~wd%3JDKN(Rs+nLQz1F(6tXl=K*m^ z^}FjPoP_GIqLxYwH2CujKP8&tWak;1-TL!;2+tLfO}EKFIun`OThJLtdnj(_;b9kd zx*odmZQ_upw{E4pyS|?;P1~*WkjFjrG~Z(deCrYk$my2N zqk4Le8%NDGOFm$yr#{YGs$9@ldb&|Q*r&@QCDMW#5jLAsrlIZB-`sqp*tGFCoUuiT zydAcBv@jTeB083p)BBZx>gPN|`)2_ta_xR-0i0gSTWtEg?4N#$KWkP$zhd4!RdK#v z8O#|41ZYE@pBO&Lh~5wXTYNyf=$I!RzR;o{TbwtWq^w3~`Fxi8&h7TLP(rc`P2UfT zIy(4Klfyjv>0~WF4dv$nPJO;2{A{`X>6_hDWS|9Q>>Nc`#nbRBfvuen->bjUXucv- zq-~cV{e3{AcuBJ^cpJ2lfAwp-gcqD)m^h>sQdn_&#L)ZpOB$cX<$^@D7ln7wRj)J1 z$!{x(TK2+T_`rRW9;LS7&1NW?$wR$CEKagKQqr&cubWC1N^>W!kdVV2tRQ8N(g_120nu-zq{o5y(P9m8si-xJL@jcb@VmMa5Fiaej!fM zI{b}_z@{hdHE_b=5aJx~CknD-pjk<`9zSWI;yy!T-1lS5f{*cQFE+-m=$jDZx7>%i z^+~zgCnhqMMrpx*B8)aL^qReqsVvIoOMa-!Ce=Z##APW*m z_>4ZI&$n|j{nFoFbqiWaXTu*}jJrkqsQ-qU#2v8rWO}i|QhxRl09bsnozIqREW5rb z=_DdxpPSWA7G_0gm*p;f(LTebi~h!4LwB6DUkqqZ%6?EW(QJU`HA`k{g>ayQuGo$8 zUUY^$K1t)xKCqDo_jru{TDlck+&BTyfLQZtmX1#fB?4_}4C7@sd3SYj-k*EU)8?l{ zTKEaT`MzA!EbO%o^->-YGz@dd*cMxlRzy`*2BPs2%*fdVtIn($cCD<3!7*8O?lK$0 zRJ6D8@RAcJj{Ei1;zRs-nRv4vT0grLZ~fdLh7PE;(S9wq=^9(q&SnQW+~qT4Cy#@H^q}cfMyyFyoD!=SU&HVNn6V#9&+$j6?aEepKt(Dl+>rgg z!9^EInkOIMs-?|a+C62!@CQ9asiZ*DzdoLG<5@cqEBho9WK9{dEy0O$-7G_Ngwo{p z(iGp9Uw1~3={z$tG-8I2y9Bd&fNLHe8RjUsd-vhoTYS$8ZYKicv)sET;+MP0m?-rQ zr#vR=ze_Rx3ohWa7Cd5sf_t{en|J#ma-#gC>(4luy0jVXU2pLz2fkxTp1Xn_f6iz=<&br)F-^ovdGEVTtc$F&fNJ>hF?1mp zgOx8DC`mdsTPnC!YRAr5S<=JBBXuMlH35hrFPa7GIesI1R?zE(C2nxw&vb<8yrl|P zr}`VGzVqYd+mKx-@K#*vaGJ=EcIfkVMp5uTKLvDTC-axIOj>PTVLp+cV4e^hvp!W) zt@gZd)>lWkwO%pMUmznhV+CYoE5vsN(GhM?k+C3RTc+Pr1R1sTTk{lxM8rmnFnQ4~ zR_>5j4LKXg@O?MeE~64)q+aOYdQxcklE2OA$AnQ4_SL7y5+zp7Kx6B+_%SM}llQLH z`gw}g&e0a=O$foa8IN1K8s&b|XVj8C%^@DzVDM$hfkU8n^18mDrOZh%SNrvJCCYQ# zEYi2=OxOYLLR1;(TMm}ba|&70Ta<%k1N|D?QuPS)DlTUvV9FthvK%w5R!dW&Npsd8 ze>j%HY0pH!XUADPufop%s0{JLB$&d$N!wX8#o#ib~ zR3jF~ojK5V-)=`)0zJr$r+P`bj*(409nR6#h{>0}Of+na8}iojTJjYU*-+$lHW9D(AhMh&nqJQnR9)8od5= z@fVA*Ipa84Jg2~*Fc>(mzNF3XcC`Od@B?U9`9^|uq&6or@^>v+J4a>T)an zndGOfY`1h0+}axB#4VD;YXpZd^@^3VR!l!6pP*w+Bep?XMDUe(3k&YcJ88-~L-Pqb zn>mMi-ivw9^7iV!N`F$vS(J9mDTEPewev97zuFCanh(CyS!xIOmnMYLNW8bq|1h>H zf0b9em&&al%g<72f7;dIdbXcwDJpE<5$j{sQznHrpcH-{x38bm$g2K?KMY z7;mR}5zO@-+k6gr*(;M7$0k=BK-FEOSPluZ!NW@1pmYi09nc0mQQ*tbwMW61hng^s@e0 z=It}HQ?(^8fr|VaKff2(GP0Ml!oHUWEIv!T3%7cFnvk~UW@da|e?Hnw!HCf<|JV

+B%F=p{5y4;tw&1ZWj4+8M}{DFj@@ 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%0D4h-^0b8DOatM`4z7E!qF`L# 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�y|xP(0Tt}Zr34uuKz`WWb}Sm@o)i*?)v@Ar)A5ww_G(j{)Lys)~aHs9<~@bdf4Ung`m+(Sv;P}Eb2Tesa#V2o^2wL8vagnMD4Z0_B3%>%k($zny-gOOvx z=$8KFX6+V9+-Y(4f{!*1K?#|(-DpoM3^Gf7en5m(yIz}#(K^dJGiF! zz57(PG_{67BFPR5IFv|%3ROO|;F+CEw3b`@KyEz`zV*E~%m1XM?-7yNHOk=XR(qDScZ~ZYuWe zz6(*VazSnoVA)=Hh2Hu=<;K+)$MbllKZT23IX?o}L}brm5KqLD!{*o$c}!=pbUCYn zf`b)iE1~FaBNfeL8c)}05qeYVDWO)s>mWMNH^{pV&+jD*Jy=O$t=gm2HDRr4p4Z<| zb6;r1nU$sF>3Ogq&*6|&!bkJ@fy0hYEl2bSs9rtiu#yY)IIF1s=%hP~xjNns=SGvz zVQ?52__0@cc@RjlFyl!<55GPp>I60~^X9lVgF6fuTm}3Ir+ z@_s)6s|7QeYx0xs4|)6AH8gwz)qDIg?|$!r`26!V^mpNoe8w+Ym zpyOWp-aC-t?hmt}DfRC_OhLOeH zsn^L%C{Y_Y?n#eqp3%NHs30h&9BY;&(||9kfKWZG^#LG{ta1?I!g+cAI-!86xkJ2% zW@Fq^0|~1dIim`;Ac*X#%y6j!t9FKpPP|hzTa{b5bAyS8fV_MRqH%-lQB!gxKMmd9rf)O$_m=WAbN!^_c>whgWt zDfWjl6D|$My`>MJeo5M}PXboekgwzbmPq{0BS#9B+bl6$ag8X@;C0yWvjI@!W9TuP z=?GXa1yqg$qa68U_e)31Db{On(o>(~6M(w>#CDx~v_7is9t~2AkkWCc6kC-f8rT@f za@p%-ey2;9#d-z zl&V>E-z5YBdg*j*fZ7S}LwX%c?` zRbv_T!gZ(#EH^|4C1e1P7){5VE1g%oPK>e_JI%xUP6uy?MQR_rf$WgA0#k-*r3KS)( z(}I-gtcX{)HQ>>&NZ)N8gY9_*)l^&<=*aGYF|wi^_o#(tZPQs501t;<_CR693bg7P zW((%4^FdBV<$?_7Dk*5S0};3t1;YJZWY&>xp_u_9%0(umIXe`!BT5KoK=lpv&c% zX$>XOosf#euJ~h~ZWFkY-U5p0bx7OLqU6ciaNgsiOMPGSO6-E}CLuy{S=}983`>O^ zT~KA=o!Wfwv#aA2CXs0MdFqaBm)N86#5Wr&xH6T(M~r_8>dp49k|BRmz+vYz1mA#+ zLU&i0>xRCIM4gdwCVw#$9WpOWB)io5MFgKYQc{M@yruaVB$iZJvZs^8C=0Y0q~@w; zoo;PnW>`<3&JB@p7ID{nHrKy8=qJ1B$~a>|Qght3t01Vy{&BR=E#uSiR1- z@-ZOFx@qMaEXXD$XE%(A_Bd6TtNS<2rT8;O;!WSZ=T+$lM+0Hz*2iEtLUi(Bemci; zwn3shD|!xh-(CPaS2~()4>-h~<*WaY?N1h&T#xVEk}m*FS$0c1a)z;^On5zP7+ zRRjGPMQaWW$jF)6V%*0T&*wWUH~OZu)o@@vC(77`40rKHcieW9b&1>IXz@v_#{n%P z(7BHvTV3}0v%x|Ig=!x#f& z?Hm?z1I8~N^XM|JY#Gu5SDqz1T4)29PsmJ1@~sXw^hbi9jor|Imkt1psC4Ljv)il3 z0YhMMB$}@0V|aA{RhT%=)Xw=>z%?Qx_ko(4_=K$hUWqJ@9eyWQgv21~s$ZhfD;cc@Q~}WjaF+IW^P&h!WUDJ&iVc$#31H_$hs1Sz ze@_E5J7j@@;U5hAbT%i48AUrv`})7!Te)i`$oWKscvgVYM;VKdCLqV3J`l_gtelRH(-=T3k=FnrFx63O#D=;T??y1$e7XdI9J5^z;h3@-t)bBL3- zt~;s#p4}KPMObZiC3Z`R0kwPT(7?Zt-+vJY{v1-_gW(yNC_s^{wobMfUh0w+)y4OR z1%~-nrLMGu86o$&|7(!IkDB?lGiQ5*7ryY8Ig0nxZKT8(@8)aO11Om*JlcrvM~z+^ zuF1FT4{Um5=;OodLs{W6@w`tBLurMSw;He9YV~+t0Cc!Y0u&a@!0zQ()uT<46J35H zkIYAacu620d35G*H+2V;oK;JNHmv~+*VWPw+{lJE=LxWHahhjx<7XijYsUJ z$BBVbmwx+2F^NWM_|7{F&ztD7NHy6gHl?n~o9JNjc~=1Ah8MdqR_mLQHcRXe4B}q8 ziBkYwW6KvSl0fld4_KDJi8n>u9}jY5W6l{v0djl>mao_?RgB_+1)?-a;fjMh^DP)! zqh6}g=#aP6x6(nNQaZ%grdz~FVBO&unKd=i2Cb|a-ypXvts59LDB79nAXU9wPQ$h- z+8KNdxf3td%ik%HwIe_&@)U2g$O=t=#O1xq6~mNz6*M)Mv}+|S$_1;Qb{~Ckutn+q zj8%SneP@8~Z*KgKAHRkP*U=%P8aAPG9`SEg)UaVak2rcX0hg!e=ruP4C-p|pS{vQI z$W9mrQs72>YS93^ooPMaIm}z zX5w}JZ{q(oW&h8Y{`~3}z#H-<4KSt9aFRFn-b7{!y&LuGTa5m*UEpOyvH4hcNV$pp z(PX8mw^yElVDSz#qZ+HmkEv>+#xCz0OjF&_&Wi#IuqKx}u4kWQuc%@`-qJM3(up`_ zKefU3Vqh4rb1bdll4Z~YsAZE)tci-xGu5#&lOcoip9YqC*?2q=6~K`2CBW5fzis1w zAR}KWR>9jPCU;OTdz(uBp0Szok##zx3e{>1X|gYzxQX4p3y0L>WAGm7>prv^RvIpV(WaiRDcyc05LE?Jbo? z&c!LA9?P8{r8uRvfzAEe#b*LDY?UG%&n|zg2g2dQJC%;hUD3;+j5vxxI@=FR3JJdj z?S?(C)xs0FL(}$+0Oxy+=hi7k$iaia@VEO8!%iE;2t|@phZX|=L0|n(*(_XuJGraj+1ZzlI88b&0OW4 zVQ-H#As(GSrf$F*d#g(|IJeyYj@1=0Kyf@G$|L)msyjZksm9K<-oGt^+@^s$tc4YbCR?qHakMmRLMA8JI;^F6HE-GRP4o-Zptqd9X9 z%$gZdwz0N5`#`H#_XRFQ75e*z^*O`hAGFzA6bwi_1u_&zQ_ueGj$k;*ueP+|5)Z@@J~50iv!;0LPJc^%20?{RRLK-!@r?2(M!% zq2Tav2(xRm>BnItfwNrR^i^g1ye3X^GAgA5(mZvBly|f1{g1B_IIkHJOQ?L9L0P28 z9I3WX?7x%ke7wbL&_Nt+&Ri8VvM;WJv8_Y=45I{4`Z~dslbtwSmEcwhz*g9b;~w;f zEGnvE7bc>c6L(33_=#fhLMef)qV{#@+F(Yow$o>HAuhv_JuqY<#SSi$Xw482UAN*_vI#<89vFe* zfE5gXtk#0~X=fEen1#HH@KHPE3qTqR3N3d5VNDuQUoQ7M81)ww3(3xPk+3H*{D>PG(*TUw1JXTC`}rt6o^S;h5S8QD+om{rWI+qd zNfU>jr&V9WhL?Jikh(j8zfjN&+aDcX8#|Pkm}_?O+!P+YML5FBO&?foLW61tqDaym zpkeYEX{kF?MJNn(X!n3WST@Vp+_fSdze7~)>W!Wo8o&_@h|QbmK|+4lP5&Y`t|od= zuYB-k#AmA-BtR#9@@QEo!+!#H5Aj$2G`Nc@>&4RB#5&6=q9T$c2amq{;UNV3Ss5ft z{0q7Rb*@@@?p~QTo1loLVDV}pw(7DLO!k-*@d zj3GEQ#p1LwE+K8;Gb z&jC?m2`qxYUIoma##}vch*tKS)JFk}bQlxWjP0x6)3?~c04mEu*AblF0_?7IbR*!( zmOJ_}?p`cAxoaz4u&e3K?05**17Zq6|(03350TnKeu#T5}Mf^@@u;n%L&YiJ6k&$YN!OD zpToy+5>)0M;4}9%JCB1%v%Hp9NM47R_tdnfd2t5R`uV+QZH&C8fP|(kNHXWyd(dU5 z-tjyio{4(`#qm@rl~YoXBmOegAy7j><%%#sYy z4I|aNtHCqs>!`{MYRxDbLE8>x=ple+u~&w4iQVBgkx3E)J|}{4N>JYueHsnl>MT?Y z-0TzXbzK#QmB>3UafK(dq~Ot=O9!h%($9UXtteKaNJ&V}ecr5SY=VBUb!+EA>9me6 z;N+sjYVqSJhyN8${`P8DgMXc>>v(|Pml0NWg+%V9s>3CYnFczOWdwIbfQzymV8$@vK&Q)vLISZe?} zf;&B5XWw%O=Zma)ilCje)pV(G_zeyf`6St31@)oQr{3oGlj-S@^s~FfqtW*?)k0N; zTD?V6Z7C`fqIrK3qe~#xHgl_f0p!r6!yplQAQj|jJu(6 zLReNtqH(xAtF7gJVK+?a5at8`DOaJDKmtnMR(35aF}FG-swrwXH}AU88pu`vMkHPP zQI2sp2>U^~6HQ{68j&=IyP6q$1THLl`1#ck2Pl#dy$|rR{LRzXK zeBL1>nmP=c6r7bPUBGAk2yzz0@rBoDItCtj2guNQdvn#UfWR{2s2cs_#A7rYs9|aW zK1NO?gTdNNeJyex>)7rDY>_aw)e}C>tra8aNU>{l0Lb^+rXlX8sO^sk7ci$lO(m*( zyV{@z>JvzT+Jo_G8)mP;KTEiD@X3|vwqQOmt^=)Mv_BCuDDaJA9*=`*A=^ApA6qNC@(Rx<0r~Ren0EytHgfY|Z_L~;PmCWh zhuNb8uY&cZ{eCfs?m7Z^Qs3dK+wqe2!zuwnVQ+BC!|28Cy~R347UEs>B2Hya&q_nn z=(yC04dEbgueizq7n8_$QicwqpmYR?XjmC>K(wg$#cPH%XZT zz`0?QQ+n@odLF$(2nM>1aCyhG*f(e(m~F+kGgtDoX_no|Z8!qo3jnSbVSC|a8+&-1Wk z80ISr`b!JIyNaNhow=CQM~QeyLW8VhE)XA82s=yW3(i z3IdXXBA|$rgn)!}NEj$0-Elxb0qGEskQTwFTM!hGI&_G%C{iMw;z7EkyWaYt-uvCp z81FyEdt==D4N&BqvwwT9z1CcF&Xw0>%J_%2By=Xd0)V{VmX0CBj)dD&nDAl75Ql_> z{?5*(jYaM?nz-EZt%a*~!ORb(oRLJPf;UI5aucR!dBG@!rxMj1_?Zwc7=ay4;`*Tj zX)KSLdcpu95vS?MNiH0zIXnUTVVMyEwm_&jou<1JN;!bHF4JUlQhwDCW?akS<0vX+ z1IDd)zf`Se&1>8oQ|S$NGo_6=P)tKFr-FYio1#)f1a|~*OLay+KAYlvv0rAYJLkod zdk)V8EW-J12KsdcsjbG}12-=8HX4fTjwxf=F(~1#x{$wp<4eyOX!zvB;?$gQA+QW= zlpno*K*1qf;jyizJ3xGLpYj0Uo5nA@4=_X$u}tP>)v5ivYW^A8i@w((EXw4liQ~#V zNmu^UuT8y7pLCw%vnnB)pFp3F59@S$Gw?S#OIcZ1WE0N&;Sf!)RaJ}qslb74K+l6n zol-Qb)D3bcB&iZ(q0iX>2znBTC{&W=qO$2GA&JQ~X`*J+&VBh5{}njEV2PumgsRWZ z0Vj$XxJW7xd6+NqEnXm)g?Iwsq~!_iU?QaFb6DzT68Mr1!;$%HFluAU$`_V zj8j+RK88M$u*>#lA5a2Qi#32hW#TzqtxScQh*5I>#|q?}1khHL z5N))I?&kf&zu)`4Hz={KwN9mA*z+D0?#A)aRCRb39A*5^ZTZU=GDLg9XQlrPIZE3` z4l6tif9PjdQo{QtQAURNb4(92ndqo?fw*}l%yU|aidY) zeUv6Y4_mR9R0gg_=jE6GzrDRE47*ls;}*gS2SWNVu!WZhlN~%jq@4r=@K&^*7#k$c z3M=|RIbjDyUO3R(dpa{gX8=gdC4!>Tu%kbg$onXnjMcmv(^IJ`b*6SL|KDd%KlOG$ zG@Ok>!6MZ#=r9znGFgNn32m^bp@j9&AJ6BPESf1$;d{Oy+C_v$C{9uQX2CRKPNy+> zl@02!lq1P8)(hbmKG%h?5?$2vCU!*T2`-brqFI!YBKJzkr}J1lCk-GTvxxohC+)op zOR9tg-gAkE`}EnrZ98bP?}?P`-zgce{#NYu^TUNBnZA{n2~&xVZ2=&u$Aqk7kt=1~ z9)kfFTLy?#WtIb_+LwU-Y1$k|f~xvZ2CVob2!WSmr+tu$kmjuOr&+u?50(6z%1FW7 zo}sOZsd_jnfj!lk83JBDX-~?4bFETrYq;tdERO7cZ+v_uTM8_G4TfJ%z<+l!*5NsZ z@ABC@`UEHcxXQ5Z820bvyqXT5bU-^BK>gw)?yKmLBpY^PZEkR(>HysbC=J~ge5C1} zsQFAD9pTnLtJQL3jFd)L31a`O*9@}Jp$YKPtSuR<;SAq0fs$?5Mx)DRc(3gYu;i1r zqk4Z^Na)mlmmD5*xjWzUm!E7E+q(d-kDFI@%oKg0&Dix=2NYE;E|c*PDj|n8&iOph zIwrfU^U3ouY0wFW?lgtXA~1LY#oczoYijln@Z&e5OD5TEV!iWO;jQ&n>|a5Gsvyp( z;s+#}g+FOEzg@AY`^e4!FHlCRYp9cahGThu%7gZZJS7a-9^0a+N(nyco6uz+S$@@6Z}d1Z4$l*ExK2{hN|6M^M`OPjzuL z$2%bt8-cNzD&jEmF`)g`;2rGac>T}=8G-R1Dyb^WbzvM4BXzMaAb$>l2KF-WsgJP% z(Gn3sA-z*nU2sV7=8IGaBlSSA$wVV}3qq~1Kk#K7&MU6F04M0O=k|+1OVYBhuxW_x zv~m(e1_gi%EhtwBAO}@*njOeoL)5MiEWcSbq+r$qAgcyAG}m!TgAMRnqeyW#r#F+| zOX{w}5ZMc|?w$CJ+~_~2#M=RawGT%|k9ww#JV+>x$k0+ojx^n!Iq$}2VnWj!)`wA0G+c#_;>)-Mi!N*XwWY#~yoW^tRjD@B)7 zTz3J#YJegnrN(G(G>K$;wmmfji4CmlC_1<4Gf+3ADC&TFUJ}F=gp9A9ZQ%Wsp6DT) z;@SCPMVE{8^{&8FZSQDo1U_cId4~@4^es3_a|zL%S=YGXi7f{dIuX>E@&r`Cw4hS} zRSws=u%M8ZHcH;hheNZ1*6GRLLVGJNmJmKV`=Hiqdx|&@B>BWq+5=Bwa5MoI4a3@x_lnl(TfcU1zS&TluJc{jjfs>I*g5JGbIEtf+=t69 z1-yL%Z=XtRyaIhegPh9X;9LI&7;vq2bO3EYhN|N0gb1Dab=3bE#vHO=UXLy3_{|F$ zcm*#Dp-);5u){QKBrmQeOr8vca-lCJ4*hiMXJC)2;Xw{$ari!5O|-kf^wGZ^PlN$Y zhBD;LIq&zte4FpH*Y(SPO7f9YOHWQF461s|o`nd=q&qtl_rgc<729QStz?_MI&K6x z=`e(n)fGy{7vB5nf_x9`2Ay?Tz`rO72Gdmd_u%+&g422QLhoJjJ^=DqKz}peDZMW- z5iDk1C+R{Vq!XRJqz+0yf``x;If+z+OiWC#a0B3kaxjGSNXgEU+Gx0MEWsu8PWs4dW_HH)ETO~mcTE-7#);qfrUaT!dC67U~~%n+g3#>!m$Uv zh?5KD6nAiOv2fR-(Sg4%Ki?s*QKQ-?Gb$wxW}1>9p9=39qO9sbl$o!`;zD55DEqk% zj;zwJCtY>&OddZ17mMWq_V?!*OZ5@Z1~RIov)9il-ROl4mjneUdn)jeftf?ar%MnC z#b;)#sN*CP+^`FEiWA%5zjGRnvZ_@f05DuIFf@LJK}iR?VY0r?ry(#%teadULUR>k zunP>Z8MGnNG%Ik$ke2esM@MOm%?IJ^0jTs2T7f4 znbo;Ujoceo_+ku^MAnuW2>YmYoo=>2q_uk?Q$`b~pT4-7Ap|POP}FPtBo3$P(|_CK za0ekbEsTF0a(#>oixw2w>%-xEsbn%Oy|m1$k}zZ!(bB>sYftvFA5pT*m~0K0YlxOl z<&_e{F#xs{Ss)j*STQ32>bo1Mr4sk%knE<^ZnQ|x!9r%*MCl~~m z#0O}qt9?YezU~gZoW{}1T67#k4JFU4% z+@7koj$o2-6=XJB)~`LbU0ncYQy0b2t-5I7LGqm#+3E!++-%>oqThNY{LG4pFCm)@ zu0uAZ=g%P_GUX|`L-W_={epv$LI`=t8PSx)M>bgqtXIQ~d*WPd`-{t@sQ`K@iZa4( z3kO}Wi-Iu+!|l(GV4`}MzR)M)RKNp$Pxsu){h?-XK#$=2BUn=qI6lfiZk+^loH)_) zf#^n8{L4c-B~9Qy!eK~W&JU{Pg{{~?I1F`A2dD)B03@5HmYVT!Q?CHS&c*fdWL)(4 z5J6+s+&Ydksqd>ygaBz&gP&sbWCF-WMuGvo8F<{<2!T}gTU$yN%1(N}#i2a{SfwK* zE%u)|4E_I_czix&>x-GhRQU#ryTu-1Q(^i%f8GDDr|~4Yur07X*Hvtd zUBpv4i>vROlWpI8TeA!2Qtb%sD@5P-Y~+?-R|;Ge8!vGmAY2A$I}fVj_&R`SHurk% z!FUJ!yfpQ6E@;dIK{dQNJR!sXtpbXDq?eGPU#0^NHR&-cZ|<=dv+I>Sf+o|ciVY_M zq%{lTZD~laxVJYYZ)h?ZL<19zDjn8&JxozfE)>FQ8h9pb%^{nnG6`9ViHC+oe_e_b zdrJXOJ^)l#*ueH)l(825*Gu$0>%IfxfOe=o@$KKrhm>tV!5l&ZbeJc)vf_)Vptzq8 zaM-w_(#nR^bC;!-O5;u0k97L5I#;EsBt0l9SABkab|4smXQmMqICsVA2t>(D=V=)T z8*L*r6-qv&r{>`7^|I4YVUw^)jeT z$J;zp0w_@kSg+5mreHkN%2u5Fq8e1U-jAfbe9|AyQLYpJHPb5Gi#4J*&!6`>jC%KO zomMWY(82lk-wx1+Qk>^u-k3D49HT;NDxshRO#OmjtB$STHzZOlAR?u>bJJ=S9`0AU zrS+W+A7!9kp9eUQ3+|@HhNnz}FxWYsx)}0|GGvU1kLni#vb*Pwn&`;RN<#O3eZH1X zJp|!?@>_O)8f(Cw)gyDPg3p}r7!eP45UiX5{-Sn)c^G095C?-U4c=`p0N49MH4c1k z;`8vihpAjX-<6QCS=wVe|4yd&4**4&91aFy*(T(hh^GToglEP+^8UTPrtiR?{t{0Q zg!=IFeuPQA;wQ@v;c8OaL$YxKk$LKg0uJ$lejH+H1Pl#R`8qT-0=&I2`s-4vLI)~5cXuW)ia5{vtks#5#h!DYo=zlris;_fi`9DSkrg*=*38ftHi=}PDz+3}hAoGt$ zEIfWEJpXT%?wxp&?sFWjY-=E!paB0 zy@waKY?Xz8y5K!da=Z&r6~p*D|9;5VIg63$VC@xoWV+{)vPh~Q)rWC#oDn!HgvT2Y zg48R_#kt`ezz{Hh0n+Hs)3s~BX)g0rgv$3apxz@|g3-rdd**Hkb)n_)>j5xJy(kVt zfU2?_YHW;o*c6pK#0ym-IC`Mm;){% zJK2${3*^(Fhzg6bSy}#s(=6X@OZ4`hasb+v&QfKd*zU!ho%JznaC9>vd4}-d)9OJ5|hU#sh+2px_|ELGU_T@y5_o z$(N8E=iZ*xuT9v`EjYK-oh*O6j~8a{9STUqK30l(bX-UQ2FV?I6)8meH3k?nslq!m zd5cmLoHXw$uX2~|rGu&O{Apcf5Gq_>F6e|GBE7cBSw_xNxs-Q5=6T zhsMRiJLT14?-rx)RZz{Zs`B_AK!`W>kPgv2tXA!S!U(Bc3XSQXOoCw+0?@@gt*FXK zOoBF`uKt~QX}UAzMLx`d8rLa3FMpjKQzD700kT%>CefXfpHHuE^h#8!@W^`m%vGz-3sax^OGg2bV{#au#djt zHIoa_?c+!6e4uF#u$D&*&_7QA#N!fn7V^3hWe`l@FeX0aDv@#VsHxB;(>Zq+yM<>b zlT)uGznQELj0*V8+hw*lNtHYHlb)rY>s5nNrl;Kf%>vDR!Tf|fAWL;@pO4n~N&)nY zoX37 zLl=N}F)RrHfO-XFjj~I438H5O&eh;0P!JCt^}IGXd!?p8NH zI2+_qmv;Iw2IqA)OwU7zQl8r-I*O|q<<391{%anr^3bafN7MP+4Mojb@syO&6&j;s z+>u2Ie{8+%WfV0}_T_UyGN|EpG-S-At;<_$0uC=XPB%X>m62D4X*2Eei)&{}DGXF6 zKu?1CymkLjSGQci70mgnZ2;6W z7~)N*Vz{{fc;Oe9u@eQamm!u9WIz(a)~wvEH9b5+5c4{xWd#@-YH_)xVd7ZrHeKjv zwHBQMPnMM>m{_3l8v=ot$6wHzYTfnplpzM8gIw>Yd0k$)~X~c1UG1vE(5sbnL z75hQyR%gQqaufV#eML4|*4VSbWXH9ejudqhC}Mi-V6J%@b*cC{uNwt0l)M2hF?6sU zX+K9~Qke6*BPe&M23r%Qi7L<^qXn+s*P(at9<*UfC*y<`rRObBI3^J7aGiHsJI;FY zc#SzC1UsBDF?LrgMJ-hYLFK}ZfRTi!&Co2*mY#1#1r-J!Nb>Gev>xKfI}i7dQL5}*=G(8JJbD#4c`vwjRb>{ zUTEzy$#23OW&EPJQN)1 zcv8bB9WX;zX$`U(%omCD!CC4p@%>1b_%L3KG5wrZE$fyp>AYYmN*f&0^js4nbKQd&6xEGAh3Qs?**{n%?_J@q^kG)z|`3Jc(XS@6=t;2rLDn;l;QHt>9X6= zGfAs+kB;%ZgcCJ+hMtK|z&vz;+HVT1Y%*If974H+9~*Y_b)EpMLB|gBxvf;c5v$(( zL+xjp?%akcB9D>MqjBZl;A^XQ4=7~2{c>g;ZhE2N>JfZFgch{!e|6V&M@AtIShk1G@cpJ*r8mKeg@^gY4>xA>zIN?Lp*y3E+RZ+@SC}iS6CMRzKe?}y zHOD%#^vXWJ5Fz545=qOy*l&8_w32(@czobsmTadR0PxZi61LgupwDK8f=AXM?Brzy z3dP5!58rL&rQ>Q|xJRrU(mz+P1nKYdM}sr_j$_3L*`NhSw?WL)3Tym)nSRBa3g2>o z78u|&qhrq>XaB6HKv51oIqT2VPxlpQMRU9A27P^+u)RrsHfHuI$e-1rcVP_T3>8rE zd0(azdut?t!|U7$ke&+6meY+lLMR;=n^;KL*qYBvM2(%C+o$u|KDT=dsHSRhk~8&D zX2?cR2L=ePb0rLM)^`E!Pt&)Dz`BZI1axnB{((qsPMqS&W2X{vHRmXCgQ6%)Ktv-C>w5j~niiX< zuiY5(nib-;E}>jEI~=4}$Nm4|mwX(OnnY+ux3CQ9pR_G9Hozu>>)zGBRX;V08yCs- zW|~+1NSq(czoC;Ai06ePx#(&~4RB|ruPM(}j(OQv5Zs5MfJvv_Pn(YU+|JKQ?DJ|r zt)$`HFpl>jh-@Z^zFqgJL7Eia<{Bi*#_;g5tDcz+5~5+SEjMu0HEADX)<2j-g%S#7 z oWkG>IUfHaQ3l8cwnb6uHE{Yut?QNm3>myg?=KX>Eq6mUi}kYFHS!j}ky7#13- z!5c*buIU&(=t_WWe-c!SLCD3FdMxbV;4swm-%dsTP<68z9M9A#2!@hP*x(pnhz~~y z-rL_44}qePEj^GJYb;4%&|#|MHfE}Ox}|c7-nc+y=L5Gfj*3Ri(Es5N`s<$hq=%MK zb^h>G^d^>;B0?WNyz=_vn=rh`lI(+FxtAVabx>)~0zy8*X{!`FM67QN?V+Qci=5ZW zQJ4<=0b{69k>))h;}g%VUWPd{gJ%u2#Q=BYS8i@8vbiRy><_1cR0QCAa_84RMcikv zK^5R@A0X|$y}3%Xv436#JZ+5Z9tQRiYuc&J{P8CLW{7UF7CSSbkEL6wkCk^m0H{zgdFkL<1I>k8>CD(PkB)KE9>84M5 zm%f`kt;_HszhnCEXkEt{mfcbST9{m|g-QdB-VhgdDfSUw0(ze6JIo+)bvh-djtmH} zFq@m;!pA;OOIS%X55%CPm?eE7%Wir|byV&0&p_>`PFb-E<_|>6Vuxtk4amX=?kqO3 z(@cZv#o%tF;?Mp24<|f+~vbk{#U-n=-8JOEk<2f9`i_Mna zH2;78gJ;KT>2NjKj`L;w8g8IcZwwl>+)!)cf_@MYjNu0PT-0{E^H$TTdR zu8Fha&~(4Tnw3H1OAF!PD|nE3I8`erQE|QfLFFw~Km2a!tUEoq3i;~R?{_K;bFA{ zpOGS8fu9fp2H3yv%DP#82MYbXlAu_t@qq*_=Xt&0k366L8T75$*WV@i`E%e?&^LNH6Z+ud ztHQL``sXJJ62tZ%xPxm?RwoxLtPH(Ta<%Lvn|;dfAgNNz2hBZvw-sEt}t}P z0wJwQ^N{i?1WVA09WzqRQ;5s+2rh|XD4=c4Bj98t&EG-tH3-}sooD;N#!wr?Y(jCp z-XH>=lYy?dK!>#ROCae5OYyg*YjS6;rGYR38;j z_YpKnPXk0z*syZ-`?J~-H4fRQs7Mx!o0m_98mtLA%q)A#&IrOmSv7~nHTkMwxFTtn zF;_^jOT}hORWSk$A2Hh*(9>aWQ0O<-td+a4i4X=RXC1rrQp)>G%2m6kcY)EzKF1{U zo9hbeZ~!M<8Ac5enSU#jVe#XT#W!sfL#k%@pHvCLO<72nwF0rVQQ~1;v#Pf5iQ6|K zv;NAy2B-+a$e>#%o~T!t$Xj~03}9twQY8fT%04^~*|>gae(mu99r_G_3&N(M|L;ih zmCZSz1b%G01e}vIqR0Xft~A2!vCwE7BGZf-DE@TYnfWRQIC$WGgQkwU9-PqhM@P?` zcR}lv-+3+TdlbnH)v<-}agchYH52<}zzu{~a8VflEqy!twenJ_S9w5zsM@?&bsZQ1 zd8I>A%q7z&QB@sa`}Dlj4cF}vtb3;38x4BwyHyWq-upj0w-#{wo@o&|${nn`^s7FD zfSnm)aIVEAm#@ACgq_f9T6QnwycrT8L9^_<;LCHGf#DprkoD;~bE*fBClE4+|AuSi zJ&tVNlCwQOrOQ9o^&k6vZO z81}=y^n;MwMHs%lhj0qi$mgO3fDt1TeKkxp8N>dGgrU&KG#bdv4TT`(SO$|pHf}>e zaFs?Fg2w*5cWX#~@nSc0{^d~j7w7VyZtDSv{_|IMd zbw&F&v_dk`b6osTs?|ks$3KAhw|CoD!;Mx5EhA;W`7=(_S}vfLR4WB85jGa$g;Tl? zoDEeYG}2s53S(2f1kMGB3;t5LooeL~)VcOG5FK1has#Ex1_0zZ=Pw@}XoI|CcI`A$ z{T)8nO8~x5lZc+jk?OP-y(Y@e@46UtVJHIRfFQv>=WHwxaLKeWl3{VInd*+`U=`{4 z^p`K0;uAp`fHAoHn_f5SGSUbyJM0wjo4@>TR!=VnOYcYU=-towa}s$r>oduqaj1R_ zsSkeX+e&&upW5fJu~=?1RX0OxQ3m=YBLMlRa8?o#*AQ5PCN2yr47wnauVlBSO0n$l zaOf0F2+`JWW(2|R_<`#Vl19^;`#uJ1R?sAkwO>q@0nZj(dL5eU)!wH}5s$~ABl>UX z?R|f!v=XbK-V29>3;#V+jjrVOQV4Pxus3hCKop7+bxe~jbgjz`mv3;s1lA*NG^Gk6 z$8db17${t}H6}zu>6}>Or!Z4#L0y{C1B;tUN;{Zu(4I>25)6z24le$81^xrF($63) zwUt>f@&Cf{du{K3eJgVef{V)grv*Qk?7|^r$sCjKK>+Z@G)=;T)fCD^WK0)vgOvHF zL5L8HGy{|SPwSt7%wNjbRf5ppml9&(w`hZU*CV*`E}wPo_QfSn_$ZH5!6LMBu7avet^3;x zD8v>(!72;fq#MAxmyosw{p>p6mg+iiJ0?M|ST?{FJQrob(ge4H4#WT|9i-3$_;dyu zJ^#pezJHBADOD9VrB5Js@i%|@-ybJqfpx9MdH?mt9|Z;>&tuC;^@8m((8U`d61S72 ztEVSl#GBi9D>ma<26f(0-l z2|=3L!Ik?J^Y2=Xy0=~sMpdappDK)uta$|t`|6>oV!jzUCvk5+3Rq-4Wo|_gvp{q$ z#m+SFp~a6PJaUSj>?A1RRH4yn?v|CW&?w`>QOY+X@(m6&r89dTpYwf)JCXH1_%K3N zTH>9Y;fWeecyfz%UBJa5m4(_;eF>eRaK_UVZ=Wb5Wpy%@rDq)b^gWGW4)h}BeY2)EH7c@;P|{5OmX z;4SDlL>DFwD$1w&sKMFKpCKva+&=%fi1^2h5glqHp@~ zT7ARTr2f!KAKH6UJq;#i#u)4E3Two=f!nyW?+XnWKYJ|+q}3)4Ks-Twwk^W9JM4~O zYdTTlkxA{t!uiL4@UOyh7`kW+pZe#Y{?8B5;ozgzz1}7MSU;z|^($uDuSsq28v1PV zN#WE2=8@UzP{5XXSS-)WiLDK@k;?Y?tqxCj!ra$+_!6! z7fG&|Y1Nz8)zu;MFj{8D-GFuXx)tn~EDE;;PM&;=q9f5Wa|5O6Fu+(v&7>*bt(3(j zqtO;OAe+CZ_12Nvp;gvcqYpYqOVd57OFHJasES)BkaP`_AlU;5C_d_Lcxh)N4><7T zui9o=t#qnnFX(7MG82!;FCLjkP68&3*u`k)NngN7i* zS!|;IGS}qn`fvy@WDtBhMb>&Qlc_0k#iLO72Z9|z?|vSTxA1r$uMK>Je%aBVpB7Wt z-L3U{=!w`cbW_uBcbh|u*nb3}_18%ZS`3r{&;DiSri^-8zqB~}vO9~*%ZIDA$ z=qPYQV9725wc2{K=gxI@TkQrnLX;V^RA&1~H$VOg)Y8#cAaMwRhuv>iC^80@yRiIq zoc}pK$TQm_r?(x6r?WWu^NIfZQQy_~s#G7(!n*wZ2c){;iL>`yP3X{;0B8Gnr^F6p zew?9hq&wgOE-=!*bbbYh{)Yu-l+4f1`*BjXx>OOP%*b9sc9)1nZbj|XHhJwy$DQ*J z4plz$1k}zRhSG18N@qSQyxGE-vdkZF3p_!h)1(#nXfDCwWGYd-jV0&^Ql*p;FrISK zdb|A`&st)An7pXZuHw>MiYOksw8sqq+L?|7LR|?pZw_&m%PpZcO(*im40M5c$Ty*|}Xs)rV zw={zqB9^r&e_1s`LRf^G)kppmcDz3vrnjZg?t1t_dM{!EwUYj2pfn4>>g}MrH9ls0;rTC&~&f0LTu4Kim#$XfY7ZCM=kD9CZk5Lj&c=+;@A{hO>jua z^;pC-;flO`K^A&8EAOM|RSB38(86xvR{+AjdZdjDsqf*>ao6F_4^LfN0r|KrRAoaM z*~dGtXMxZ@b$Ga`$}H&>s30j{ztS))foU5}_8U>o0J%Rzu?7;2kC{UDk{GtObSqIE z1Dt@fsxz`2n%W&HA4SG!+-|mf-f=w6UA~q$emmrP+XLg06Pdgz9qVTW+-J?7I{+xM zB8}+Nz$q*g#@WQI)&V1d5t+_Ku--$pVewqp@WQq};!LO~^iKGD^!dkLU1N~K)RUgo z_`cr%drj=cCVV2~uCO~MjQ{_4P(4t&pu+@`# zg=keO)v>XZ@n2_Ai4xg8@6tbt{OOb?U4;)bQ4$wR@_k`E2p}v!d>RH}**k#zQ<|y{ z1sddeh$~7_?Jn3KMNX=T-h#gAieV8E-=SajH(56Pg0EKpdLRG&mTUq7J>xc^{nqzK zfTIMjzwb=X5qNnrENqxP@S+inzGx<%-5y~3$>H)ChQ8YCet;ENLX*hB`SZ3}XGWB} z#QuLg#vfOVml!;(Z)%bEeq1xZ`~=w*@#Wc&mmiU} zi~aucIOpK=lLhwRBA?#`8|bXTP)A?e+5ECwBAyFP>L}<2EJ1QHbBE>MPZw4d4ZjT~ zef08gw(Z{D4d93O6Xf(xSpWOpl|`1D;A^fKd`sVm3u-`4P)5W|50v%Mm_bBI0yGEd zo3;>Y^8Xs5Ds{bWNm0h8V=|X6mE15fk=4)$A9q$zC>$OcxngaNb}1m~)rmW{vQnyj z@YkL3{h}wr2GM5TGZT>(suP`GA|@=<)bcN0zI;Va?orMA_p&Hd>9MD3vgC;Y#6i>z`(*=vWV zazpby*NK#ee|R>|%+F6~iR`p}%*elWMqBmHfuvaO z@5}9ne^GYNcpcJW3pSvJGnl?T{fE!A&)a}#cyzQLNJ>d&ZJ!RHdHMK8z(ramU4xTd z7kBe<<<36}g#URrR9Kk~j+ja;5Gvn;OMcwoy&`fK*VNQ>V`~=pmYO>G|6zmDV-!F* zeWR|vJ{aiCZ(>epwBe)tIz})C-`_ZXrqoLuG!m=;X^$8mAOGZ&bNf%LfyL?#d%UM) zdG{s6cZD`z@xP;96A`fLJfZEv@Dk0W>9TZRBN)03wOWDU#RoG`NUoKBDbxTfrZ z;o&TZn#pxJ7-fp2)4i9K5+;Cs$}S?(vvpa+$Y{j&>yXwT_L?^@x9!&2nU-u-z?UzWC#(j+ zmB13laf?pmC6&*!->>36Y%Xj7NkT$HKYh9EB$9#s0tZbP$b+>PgS~S(U~_V~vT(kc zRsKlx`?y@KOOJA8L5yXXm^(llcy|tOX#9_Fk>$sd1wozbw;V-YOgPo>wu)izmM23Y zs}DVFl_kkS==L5((XagRGFEz32^o&uhg4|S`*CTu@&T^P35}`n?(Xj30gApqZh*OS z^n84(u+m=Ms{8w;-H(_jQ`fw!}nV4s1H*Yvq=l%U1{x=!<`IYe%`jaO= zcXCYVr)uXV!)@fh)DA!oa*RmV?d~4&{^PnEo_b!fe*g}V|2SmT=l*fN{kLop?2J=4j!{`znL(2B z;2**(nH0w69}#7E_P(L;MGQMJH=+OC@7wPc4kMdwSX7iDkzSGvEH8x8Gio=cseZo~ z$fPP+U=P}ffb$8brMkM&^`Z0DxmJCGW*un-$Q*;=+G?y{E}Ng{Yl|~5CWZq_f>5Yf zcf`*S`$LQxlpYNH5u?JSm~heUGIW@fU}w53 ze?S|6qMvt8{Zhf;@b}y3mlgH4CI8US5CY0|nLHD~B4&DR&;Gb3G3V%8;h|7NiWj!D zM68>Y+VOVuT=@ZgmOq`YBn2t4_sDD#kOy4}V^^;p-9lKpDRHhk-87^Je13lRe=o{h zQ6;45mfqe10y0>pX}P-x+Oi^WMXQ1<ucM#^|CZp>=>{$ zC46#zEzW*K^o!n72hg%#clf;1>B||qDUj182dNELISFv+`(C+zDHD8Hd z{-qbY{A4dl6ZI}!@E*v@>dV8{oa)@>f+FkSo1wNT2aHs%2&ZCgN*4m0;bbjsn3#@5 zTEs>~aBRHr+M3FU`LJ8%m38U#_t^dGl7^aiZ*BJUx`ag@%vcc1W4HN6b@_V&`?}%; z6_x2XM>mVXrfof&qLC(h9CWF&(XoG=@qaEDJwLWLF)FNm+Z0^%hu4m_+|0EgVbP+#9_E|Q*$$KD9GjVYZbRIW-l$r8zA-PB) zom!o~DnBi_FgDgw_g#{uZa2pT6;;J(_sKIi=h$hYDT-wk2I!nRGEdWOxA+y>rXPGi zuZ_J^X74`#kN4wgvAFYp{6JNAb`KRV%<52>&cJqn^oYOtJnXx7u7WDDR=7qd+y`Dz z^uh+W3hObFcPx~$jIjFmN&S8kc2YYX);Sh}PM#Tx+Rd2k}{F!s4TF&$nz^y-bb^g=0Uf ziC-0*lVevnc7ftTwyD$oUrzwCdjC^-($`=^?G*v5p9+qUHMRZ{n9#U57Nj>A8F^GU zEWL(oDgXk{Ix}Y9?>`%SN^E*54Ew$S3CpkDIY;W6nwAY8W4NKW?vjdno%Thn^Wzc> z@G>lfEQd))ydekha#?%(+$goz_Qrh@95I8y45>#jU|TrpFOA;$405|aafGTTPY&*J ztLEIVP1!^7kn^^zt^zdE$d?R&nJipXFP&z3pFDhhVgQhCr2Gd5BL)C?13{el;9Ck) z^tY=|1pslL?97~6=AwDF+G4vN)u{LGcxuU)(?)W1lOxFXC$ZbqTy>;E_^PrWe5g2oYP1)V`v~3bwLy zsX}yMi+E(tD(~E0XqY4a3D)QT->>j^%gNw~ zh_ScSRoC)CAzWyBrekYh9(;q0;f^p7liXQ*k#EuU(JTfL?Stz@lo@b3gFqG#H3$<~ z8csevYjiIjG#jsh<@~I(EeIx_YO%;g8YCm*GyrA91M}DOfz>;o#3DmYH%AncWKU-%bzA^s7BnUCR zgc*&5y8UMQb{}s6n}&8ZA)y$gJq?hkCqcrfu-O^}ZGVlurc24xUARjlXNnc#p`(3v zrThBIzIcIa7ff6^VK-XKf2H^}={e;HMLf2{6%Z7<1F^=?t5Cz14>%rSFf}_>OZ+57 zKeg(Elg|xH>O#H*BTZGX+Ib05yLUarQ^-+}CcK&D+pCIFQ4w!BV3A*< zFZ5PP2qJqq_B7qEulhY@p(n$xI*3AuIr*Z>L+>BUzoRGdK*0LDTKU*P7HuB~!7iO% zha~mRx_xW8`++WLM)R}GBeoZ5Y&z09wk19);i3^H9eFGJ>29Y1m$CbJ?!Y5*D2 zMpg;2;3;Gms2zF0;d&Jg?l9O!2YvC-WkX1rFp*Yt5GruR@-2IBMEfJLU3K8{J?YDK zEBhDhD!VGf@S5^NN+BGnV%43YA09%x>zq~DueqUb)>oJbjOxbNS+EG;*xeeFlopHV z7@M9gTaEjCPAsNu3jJn!2+<}1FQx6#)Pj!m)h`i%!Bb|^8*ft%L1Q@_aOb|R#oP4V z-sxZCQm$hrffdO^QNiC{2!?>`KybMMJtwCJz_*fx#^1~k)SChgTI95M=FaiG3d@P} z*f6umC8p;8P}-bHuu+-|C3$j)%(LXM4B)VuNsuDrT2t-ApFOjpyas-ECLhPMZ}jwAaOg?o_h+{Emq9XqW?PEfA}p~>|GlgJ_bdG8Qat-Lk-^(t*WzzH+3D2vk9@)mn`M6w zl$!9wfge6`!YV#4 zER4A=xy<4{A{GSSjJ)Q}`P%r4@i`WzalkB~Bw2NCV-&DmhTo;jFOxI_B)THpm2&<; znyJ`=!>yorX&RTN(qjU@5&pM2((+<)9jh_DJMd#HWH&QY)H4ABHoSEG`gQq^0=O%5 z^0r+`OfdEFiw@9_Ix5ehC?ZI59+d}E0n(O_zq4>3i5^S%j_@)Y zb`BZHYdBNR3E3u*$``P{fqCdxbaYBwio1YC2o4i#r1AJDmva5a?|A0_KDO^6>bWpB zwBcanjylrXr`CGCI&di2ys6kO>%PXT*U)25f&epm1h_n>fmy-xmVkiZFr>k0XD9CF zk`=d3$^kuvk|gf6h0d`I)s%{Oatn%#+h3Zp`d=nQ;E^ndwY6EixlyN*M?gXjh8Q0| zkM=7(Y_IHqX<^2s%4P*=NF#D$i(jTAQ&)&D6D;porc+KL7Ctw}@_HSPKMBijyx14t z!1YEBX$12@w=ce4a%Y~@BK%qwyz%v0aniVGn3!yscAxFN$XM*js}Z9WtNnw{$BUs! z7?aHfKr?2BXRYSGUYq9CoVAa@x7gvcbjvCNltG|s#Txw*F0xnLIuCm>(Csl zZNaUvgSyh?B8lScC53z+Z<^A|yjEB>iLDG1l0E&$a?Z3|SA-~PJ^?;yVy}E^eqST@NgB@VYGvQVd1M+rzSvv8MWKU*ZkojclphGwJ_^YN2IPm z{AX8P`D_01;g2yDzJ!+-i%l z&=HkD9rsSRE#sx3!p1+stkho_rh$nOm?B@?r?{$I=IW@c7-nY=MPeE2d&mr_(z_(F zHKp|gM*ou4$4K#DYr-fa3X+N=9Z=gc0mCpNv!o-dP(g?zW~{B`qYv)2(A3I~_S81H zqnV&=C^VPTo3VsTEF8p~F?P?;iv_Ro(C`_ph~6{`s8{7bP=#!giG}6;>8Y7`INkS% zk1+zN>sIgfXj9AxP~rvK9Cmp#4+y&#ndj3caF@@Zavz_i zUxdR&4nMP3^)bkV?%t=;=~Cc$Q&DM-Oi@M1+$I}fE{eG1aAeEbv1rv!YuPo#%)IJC z7*~|bM-Jcm{6rE-9N2|~y3~p`km;$Sv^H>o_EC|voDi|E@j!-Hhe5Jf2P{fU4~|5N z#ou01NbwS#WxcOiK3#hov{{9;r8<$c50~&V22jUA4^&$QI6Y z7v3IpyJbR`K}bW(d)}Md}8IeK@zhIm&uoZOUD}8Uo16 zRTvBPInz8D0RrQE-;6rbej6Pd9*%S$F9pAsr$QlRdJ07$fK$NCH=ePqu5(3KFF;0}2s$kK)UiG>7soVU9o4_xrp* z5#XG(Eda6w`3^F})rvKm6@IbzM7GuTh9iQhwM=U0G|6%ZK6C0d!{w=0!Ayd&+(OIc zw#VlpxFRA=hbRLi#Pkcy3yxW}ze;e?&pe6t<{&9DyPQd#3mO=kgyt8SR&UDjM1gPS z-ZdYLk4jAvbicF=?BzG#Q~*+9RTN(i1xT|2ECFszDcOc=n?SSOzQ;I%LTjgNbs!HH zdzQa#wq%M6v9TjOtr|=4J!n4hPKQw+kxJ1!E9b;Mc8vJ~`)G7&S>(CKD`Z;4<%96- zOT1w!O+9$_7-2i0kGIbflk}O5aHW5Znc{u)o8uD11r?r`rjiY%1Q?ZI^&9OZBU3`* zI&-Nknwr5|9?cmjm6Mkj5Ncc+O<8eD5|S)nWmBx8o9U5F&lD~M8s5W!?2fopPzy{S z`2ZB*0^sS8KY18qNFq}PQ#@EsjR^CB7mh~mjy({>iuy2N*D>aEm~#uDrGF?P{An>e zS_4p^Ct`BW4bdiLlaH?ePt_uNxi?jnb(2KTB6?^FguRB=WK;Q&^(nZnewz{Qlh}gP zsQ1YfCm(wD8H9wMG41_tZqJ5;*fkt@usu)pY(mYYGJ&_#S}^rRJY9Qg4sP8bPGlRw zXvn73yLc)##eV*`vxZT0bXV z5yNWdTT*ZRzgWf1>V##9I+lE(tQP$;R2807*#TrztBzC&KFW<~|c zHb#>YZf_2~bDoO{70?UT={<+GXj|O|0@O{PSoGrW`pt}b02J-Zdahv!3~pzneoeJN zzkVNTOuBZjtRDjnD`Q~BnM?qYx@Aew7`FlOHlsq>diQaPL+H=FHKxGVoOUG1I~^wA zuEWhmm@&j1dVlKNT3@s}m$F6MI8C%GU<=96gO%8kR5Jl~ah91YvcAgA;;XTJ(jDsV zP+&9ZNS|hBuQz)Q6qS0QfpGvdEYMcK%D+8!l=?VK@IXk-3R7nQ=!K^mTd59x?@};E zD!t?b)_}W$6*4!+-d!*;8;RfDN{OO;MX1@! zfPpf;Nw6SK#~q#7{HDNHB|Q`Mx^*Yx3nA*W$L7oeWH!;#{5%ez+tGd4ca2p(`o`?m z3Jl>5fzqUBY@Ls+u`*0@Y(i^L){{HoS)2LQt5@^lcOV(M==oGxZBf8>q*#3W^v#r9 z#FKU_&1L=8vJlZm3=#FOJv60W1cI7-;7W*6PgQxRCfxc!$*%yCmcIHoyBY>TN(azj zkId-$R^3Lhd}A_wbd6swAF=8M<$y7ipSVwY9IJso2eZwLALiS9Ip?wK{`mF%w1gz6 zd17WJNi<1}fg0CTp7sQU<}%0jxTuL5>U)b~&+TwzXnU2fq7gV2AaXm{OOPD$WKW%K<6wMj$ zA$s`$)Y1AuASH!g(+ugE+|8?W4k*`&BzsVC=;k%153NthH-na=!+C1mqFI^xQ?GUU zP7*^VnC123oQ@T&#K*?Jm?32cU5eb!x61CPL~nesTJh%;MJUTFyH9~0S%HYASlvED z@-F|*=g*tWnHe@&I+Ty`r@>TVLd)p-qAxWxZxz}y>opa~txg&X**d=Fv<+jD+}+BX zSzpm%rF6eEQ0^|q*Cb$@)NH-Ho+Z&X)0LIg{!00+nV!uh>=TgFUzq6~q01`pbhmEL zy5=$Fj<6bUELH9&jeNJX3`J#*Moz_mUF`|Pgf?;>&g(UhM#=JJFyui;CUOu;wyOYk z%uH$RhcBtNt-J&|Y?q<@>J#JnPklsLR3QQQji=+;Q@p_D?YouDu;Q{qjKgO;((D4% zJzB7|K?EL+W~4`XDz~i9UtSU-Uw_6&$@NtcjzR-6TwDA`l6s>Dc$L@o5dY>vN;;1O zE$$a7m0>H4FUu$>_GSqpbWg(5l=T1^Jjs910pqG)f?20MWbiRVZO30BwRk4GTC7~$ zmWlVI5}MTz7tOzR)=A0YtB#gT|+c&Xw2ULTrrZ{zyy|l(3nJjPPurkqB zYZlYH*an-%ICvy3eT}Ym~JPb?Hwm^)Jzw;nORL;ygHB z+&Vi_VBsl*?>N~m&@l^xNO(w#@{OK%!2I5WEj-!Wk1NBtbx!|@69a9Q7HsAd#TzgN z=mw-L(zF3i!+=QH7Bz$=LE>z>u{Lze*5vTi{Bn2cli3_Af*_K>3m`?d_GMluC8T!=*2%wzQn_`v&s2$<+*Nz^Zc*1ZC7W@LS4zqQ&O?r> zBlV6hGs>1-XuaUb$WvfXU>j|Pi-tntM%pKbHZQRi2qJx^OBm!krlOdTo@*} zqS%}*F19Aq+S+P)qCoF7*tditF5W;5ItAV4;BTL~1-zewd0&b6{oEtPt@NMTQ)eTy z)nWuQr7uWmwAt1{brjulm21M1#<3=+It(wAn*WuJ8(!(9oz;rnD6lLN|Lm}1cByoW zyuPvnlJV&Zf=|zz;7WVuL6i+sP!>zCDN4Up=_N>|sA(DdvT+9$vx7DOpD?6|>b%uWbZ8`Bq3W?-+5Kf`@P>&egF0Lyma5!^&97ToX2oXvR4J+$)}9S4&lS6$61#~ zABpY{8%BqXqV)#-=t)IjPAxv=4xB$eD#X6A1{%}QKFwjdZeP&t(8LcmB!}^qTV1W( z)4^%UYJ3R=W0!p2FajV(l~Vix3zH26s^Kwx86_A2xf8=TLBh@v5;2ZQEks9dzkliM z>}>j}N9Y{S)-#R4lswpAFA+^FklE_4k=4%Rh+MXsyO4iu&IV?h0D4wT9(Xq`e?|ly zo@p?3@EyO`!eJlpl>7A zj>viw^ed0)I4JP)rRl{R0Y8L6DXkKi(5i=i-xjlJuh2$N3*2Xb+c*{)Afcv)z+hXV zeaexRT58~b=bvi-8>s?@T~EZXV-;*Naif4l$v>`~GT||+Fz-1Bwi*D3Qac}gBj*pj zbL$%nQAShPsd^>)>voOnM#G|j@7R5_y4NWGj@r$0)OweawPo987>E{t9bPf|g?quX z_sSFbxZIB)O~J^@;EF*xkd}IAIGsV#Fb##DK`Y3(I@Y1BsOn^Xhwr^{;URpVI{4|a zkd#~eAdy5cgE#C96^WxHzy6HvI zrwR)U9_mAK1FB^!j_gH5M}a^^LncF`&QrdO$@89E#ux>gmAb~wc9=%enMhsGr=-(wj6e&QK@fcQr|&8h0W z$&X6yot-=)Ony6heuZubi~D_C_RlosD-(1_gTQV7I2)av6veYz z>mK6y`1^_CY-rH0g$(p&Gdai?U8BZQ~^-Dt8qj=aQ_T5LoYx8+a zvx2NFXLlO7Qm&NURe$kxilS`m?CRpE<(i+HyQ9zU z8)3Gen!lJ!@wJ9y{?8NoV`ygb;zB&9E?O*2^lT4rUkyG3bYecEj8C7KfDpqmL$;iE zIXN{I15g*3yl9nuvQb@=VbQe;k1ebheOF@=Mp)bb!a7<}_tmZ22e50*{fzuKM;8K) z50h408|mCQ@0f{|-);4X{ktL|6~CbvR{rKd&frC4!Zn_~81Q~Jm3LW>OF@e5$JAk} z(&>Q@goc_QfSExY$haFs3yT89(F@APdLSpq+-(EoI7w})QTqdida0tm9navM>LFNU z%V?HhyqmS4`-*P%!YLqlWf}KF=JJ(PlWH5pYZ(Og{pbNysZN%atB9xw2HUT66mF=h zb~@mc&1w*!Ybyu^48}YX6&vn$qtgM9N`b%Nxt;aZ;wZJJFo~rDBM3*8+=Q>Au$rGd zV(Ickl&f!V@;!?y2iXxvw%zCQ3TF8i!)`iiEG&<+RwW2ZNe8)$=Ju*X%F4J&vM7bz z@@k*z+X(GZJHi!28Gf*8YD4%ZFnkdK!y9b0#?UkXJ1It-31yzcNFeKe9Ao@@?13|` zV=#(jfB`Z`^U4vde0WaE5NmbGJ@V9J^U(W;Vu8dyb z)4N_{Yi=Hv%2ZG}`7>H2?1#H9UV`WEyn!vpENf zxwkZhO8XWZMn|zh0Dd#rLovsW=*8U&{2nFc{ zvwTa7XC|9trdsCq>J&RL!x9(Iy`ye{b;u4%8HhqGfJukKy2sN}{y>)H%tg2rImKjB zAr5Z*z;n&s zzDJ09*MJeKy>wR1qJ|M*X!IVSrY4=`5g_#fDxzT!{D(h&KUyUUc7e&`Xi%}I;4+_!uw~-$5=~J_5b}%b?c>{?b zfL?W~!yBYY3OwiC@yK9Ab8GPiqK+R;#*9Nm@nwr}hfRr z{rRaYGa$T(Rs=ZIra%;;G7IIy`VTZN%FtgAegYz;QK?>$mP3CudLbfL_dgJzO9E*&vnKfIRb8HWshftThkvOV9s~PyJj-0elD(HKUuC1$yZ2@fxk{XYuroYJE*z z<4Ou57Xef0B5Af|<>l?#rpZ5Te)Y}Ff0o>TKVD_t9~bc}T5!-M`Y_lE#>cO87VL^>aVd1OyW_O0Ut z77%*bXfo0<)(VT;49wOma+nr}o}m@K>ITi@fZJ@XWT2-!&=Olu!Q5uoHCN?nmew@5 z--oiF#&p?gT%KvZ2xaNLBF_L?OjfENgt_1L9GulBk1x|LK_OeQkf>(&MEGs!$J12q zveRuUPd|p2mX@AnV;g*LW%+Kk_oayC)y$tN4JC2wG`&_E0sP~+<8!u*#W26SBQmi%&3+GCLKGD23l zH-YcHrwZ;l3H(kO*`wxr0Hc2d@PU|s*38UoG=8w?5sd*f<&&84+{ch9j=)l0shwJ- z%*e0{)nhmlUYr_ClaTUUyRu-IpuXEDYw*4TT7E@PBYtpN1F}aO(mfm?fv2ENUv<)I zp+IB;VA*{;tedLa;DkLKw!Crq!fH4!6NJt1lmyWBMDo6;-hX(ro5q-6u6L>U%Vc#6 zRivLo_^T^7rojXbsM{5?vE@>oZ;$>$eLjwEi-tvbHp#+%FOO{iO0KVk0iq6_ZEabEI-m+X7PV>yVye*IoV8uA9WTlPk1-f%7M2{I@rl4sV~-(3fDqvgo{W zK2(jI<{hW)^Tx!t!rXy{XW8un_0~z)R+(9WSR(%U&mI9y52(`2a@pNg49Z#PH*VbM zaHk1m*@+hcO8n^PXhyo$VOLaSq`N<-{NJ^gIpQES%YRT@d!y7`LFZihr?i!ESBw8w z^wxA0mPSA!Wcbc^r?SJ9#wAwL_3qu8C(&4>8i;-8U^m2rdGvL_CVbvwvi#Vl(gh8$ z-RwkI<|D%FpFTB_^kaZa|NPe%gPU-joLry1{jgyW0#?qku_=_@VIcVPs)WPE2OSbz z&H)EvKEakL`c8uy)7B{8U(OWeN@&NLd>{Wr-^6<`%I+J$XyGQrwS1T*399oSrq0UF zeg|133gvG=3phL~K^qO91ByXg^Wv=dfi%WqslS~6$BsuMnv}B1@a~5IUwi7FKg|Ul zfK-C-ACDzCB<(eN8T0+4T(JJk&$y}9+ZLW~3$)VviC%r1+b=}? z!d_kZDQOYTQ3JfsZ5U3lO8lZ0kDmc~K#@AnS8a&vF#sm%eg^RF|n$mEoLYxkb1B zb?D6`%IQdoh5q(%0wvMQ`b%NlBU|frJ(N{#y%cn^H5}f*f101a;SP&9@aCNJeoC{% zad2Tooy4s13NN3Tl$@NsxR|5DT4PS(P44~YUUBj97F|piF6fk$mYx$4X}(#}2NY3hXR;Jt^Kv>~ho0)6Z;Cf7t`rk6~2@sFcwEd~|5+ zX+*xIB_;BonBhg1;l^#T_js4)n8!i*!e%OFXqliY2#gm%6RH>u;Y*5*99LTeJMHMTgCYD51a=NC8NzjOuem zjxHZP{(@x$mM|lF2?%wIG4F(>IJk3c;ct?)Q|DkUGSUCTM-kV=kyf0x&PCLqMrJLI zf7{;J9}zWZ7f3M4ZV-YL*S|t7k0h;MG^anfF*5|UF-buyLjoWgkU--)@F~d5&DC+DKU3GRvEFNZw zoh&QIi~m{Y4=;gA1w3I_5dl@2@aFav5AR29Dg>kk(!UZQX4#!WTcOd6k z*rWJ*wzP^oJX;~4qS`Bx`AUB8-n}?nQf3VQmM_GCH_oQbw1N5DV=h@pA=0n)ipwaS zz4_buK==69XSiI*zyI@U{{2k!A;AvcZ@ogz0kC4o<6ojv3UCrp3%gW7lAELZFW(`c6!WgQ*UZdyZj_kgk!d?x#jV$FMFN=jcoSSQh3Q*oWk+ zIB^#%9oS3*xaAC@LN2fz5CNrj%@PB`HhXEEJarb(K6E0H@cQkXt29(R3J%|2r0@y zcPD$FEvHJK%fG-vMkb63LGtzP z-|po1*dfinA2XsJG^nXacKqDcY4|umN~6{0hgqj)Di2Xxu(v1JwHixaZk)_@@a{)} zW-uj~wa#`K`n?B8Y*DKkGLsenE>4FtGN!&uEi{CWv~4AhGfikqFCk8@!gka+D;m7y zU?^#BFb{L&2VnK~UUbEN8ah1$rl@bogSNFDic*DE8!)@XnD9fp1=Ub%3x?LtWKN$Vy(HCZPf8n zFpf>^Ntj)~LXevomQdykA#M6pCm{f(3+HhuBB?>ZD*6RDQrkY~Osh&p6c3 z6N&Do`PLK#daqPn)d$P-CbB=&IuFyt`GuJlM4fT;4SD}|N$y_!xhpaLy(`-e-@u@x z6ek#FQX}Zp+<8R+7m%#<1cU&z%?=4I+@uyIC7fXG_bMy#uE`aOmN}l7VvyyGR=Y=2 ziFkFW$7bHQgXHBhE3UPhGc8VshWOdfJTz3!pKiG^A_^w?`Xjc53*TV!o}&TgS>*Y~ zW<0(`RwHk%GZ9Mrg%-!rpLAn|62<<-L5{TkA|oj+aCLwE=FMn)?`Mq^G>y-r5ILA_ zt-Ve9ozfCK*$|9baiyT$Lulo6C3DwS*>)-9lJp)+G3nn4%3eJI6UCOTa_0vr7SQ8% zesly@nU@HTu7JKu*uRSvrYFD7lSLl~C-vVp!H+!w%z+<=>wWZsJ130+(MPt5*|mU% zxc$g{H8m*4FKOuZ>L6te;&p$pJuVB{;5eYw57$8$>bU93L^n)<+C@7l`C-Tec#n|I z(|H~q9yK`sFG6oBq%a%{2jOEon;80m&fx|%D081Zdv*;>KwiAMS?BXDEm`t9py+)! z%B@#eEG9i>?;)cv7yGE=)K4yZuA5fD#A|sWf3WZtMK17WxdRY00%!_Wf2A%9s;#7QoP8T77Ts^9N|ROUg9w2Xs&^sk$fKAylRWMq_`^lag;ZVhVDN&- zJig_9@`AZW9Eh4me2%!wG9T?}^|`?-xVXSD^N$xmI~-`8MPmL3wJAe&<+Aah`an#M z=U{5%o@`3%hOest<5#HtQ42tMqlY%M)c@tD9f%c|>+t%_3uevxytfR2&y(dGM`#nr zL_n;qkZWe8R`ThSC6^VTWb43VPc$M3K&X=Dn)SgyG$K3{!X8E6gmp*`s#0KVM8II} z*sZ5ZB;uC~q~f!52T7eRB6fAD}2kBs#) zHPse`Ist3xRG>v8{U69O08b>K%{bClF$w&8Q{_y*8B%_?RJfq=rD|)4KFg~Mo*f-n z<`iQ*zx2qZyOW6X3-Ic}Im#D=eLQD+=@jMV^T2#+xULs0lH{P3Tb>0b$bI0dC9aK( z@LTny1?C5J`{`6Jg(PGJX3jLPR$wuHVZrol82{P-(nrr#92-5pPi*})9e%1}V`cgl z4JGLLmi0M4nr1PswoUd&fE57D>?Lv$MWT$Mbm&|3#m|sAftsiO8JE5^nQ4xqhIVt`}o?KQFl}?BuZ#*i$TUZ$QDur^lcgGnZQRx#B0Fa#LhQur3m*F2zSKc6M znNFPb{M_b$uoiyy+_|brMW=#n`)l{|m(qtV;OW`FEF_8a7ID=B)~AtL?=3BdM4Fd= z(X1d*VfBM@YfMb)eO@=`Z`&Q^fh+}mpopzJSaA#5Hy=UIc9Ll_n1<2hBZQ&mmxiQ% zB9O_;Xs&-6Kler&PlJZ$^mRd0PYYj>`5+>b}d?4;) zzH|+VR0jy$rfUtz-0?8s8^RYlaw7QjsiuX-TOMK7ls*P7nZ3^NU{-4Q&ii)%smD0} zhgDxn+CPG=6CV(f7HPllhR@ojhUWu+a#;0*Ix?ae-GPeq+;^c5S7$R|GC33|CfJQsENM+N;j)@{n{NWOV2r8y$qhdl^gAdVr}4SisQK z>|SvEP}ntB#+bjmyK8JGpL*_-n4OpZWbp%L_cH^Eg_~Tn3L6WRHKTq|U|BA>yyvZ@ z)dO1q2XYI6-+K$X4;Vjgl!$-dD1%evI<)#rV!m`9A6t#Mo*FgFREVooys*zCf#TB6 zyCL3C@+Rb6BEhG(MNwx2Hx;wP{UBqEW4z~BfO=k^8?d{PF)vr%U;ver8e%ORdQp^X z19Wqw>oh#IIJ#{5HPRLKorOc05--Tu65GK`>>`WCk$K?=&o7yai$2W#uSPvTihPL>|$^KYVeM4BFC=3m@{wFTlb;@Tr^rv<3wxK@c>Z*KxgaA}j0TGVIc zrdR(`7U>u=qa_jr4(&@cjaJ~FEr_2`p*-DZEemlK?WFvKceF41oq_@Xjxdz4zVG8{c_5Xg;#0qylWq3@<`?eq0 zl$eiG-s;^?RA10KSJKQ`qT;LW43z4}-mYG4USgU;ZOn?*z?ZUnGI?kjbPdFkm(~wg zMglcd_WLckoJFp3V$g(F%`^k~uccAw}obWDUhIt?>Ya zD=rH^dESys&rOhObq0LfMUpMff5rL-H2Dv-0Pa|XL~U|=qRu%tWBr^8y>v$0{4=lsY`RF^a0sFx6 zUR8i~poQe!{_wu5m(s!Q3n@kJud^2V!9cqIczof)HcW(Mp#tcz9;-?);o(#o_X0w8 z$B{^nT}(M!v89)4@>LBXR6~UZ7BtQ_uAsNmPPn50r~B9x%PV{~{eye? zZT+%b<#O=_&M*nDVx`Ywju92_?&yeN(>W^A7_jcoy2mEpQ{AxMn4)}hT9&09Zk^5g zuCL5eGRf8@O)MZShMlu$E6(u6vxUpwJdj@GjaK zINC`4{y4?iwQl=ko>=J0;T;6PoK6TR`sPpyi z4Tw`W@&fW;r|)^aG{9a;jNjn8bYF~!uhgu@g&L|@F(eKb8_5LA*fB3JWgAupnPAv7 z=pTei1(rn1mMZjGkVw^p%SJ(-Z@N2gKoE>_Umi0Xa>@%*`zWJJh7Ahm@&!4Tw5MWzJ=QX?C|=>rPr~Fq>wYgH z3q+WzBG-|M3-u;k$-cM3BVnu$3~-_zEQE2jO3GnWCUH6afZ}=XW;U${uuT>Ug8mzdcz=s7i_2 z7(oRN&!inD&z)~UgrB0AkNE8pj2VZqKFs zcg|p3vN*WpYz5JDE!NCuc=Pzwtk&1pZHanMnth#ar13s2;`Ze+tKO>t^>0l5UsPG> ztooUi4)+Z%!ocrc2MoKbqf3eQ>0hua>-u zcwcK5%O)LJn!_;6d}MDHEH&TX;c3lME6H0$Cny2CmR9+fLry!CcYul$&Nr+Y?*e_j z`_r(#2_Axl7lGA7)$R@(DZQTBlk(oKS-%Y|#CHML3tqnlEUqWii-XC04k=(P+_@Zj z2#aTVa9YUqv#Fqub9I_s#`}#S$04wec?S8%i0GlW>){>iS2gc<`n?C#vBb3-^;qsL ziR9v4s!Z$I9|q5ZGK~*?zKgznpb2jIqJDy>V5e?NUm1?=NWnbg)NZ64^^#vne7|Zp zQCVEArP$9(vXu*w?+MxC1CG&dvIB@8tIhK#0&#I!)HW|7dGlp?An(+LdTUe`Ojj3g zUKi3>&s;3U^tI1WfV+msA<+#NhGU!?RlVIxOiA^DEQb@HcOKj1f|Ypf250S5-p&v} zjF(=#crl;i1B{so(cz+s2lwwYKz=hvD#qcZo}JqF(Ut3JbrjYz3qSs++Er-2Z;QJ0bZ5DBW$(1=lv~dg-JA*DJKO|*SmFZlUY>%G zYk#)^Nqmg;j1EqR?xFpFOK;aA>je?ATK&4R54x!!JxGdL*%Z1-P`+s40Nwh0s$ze4 z3{Ct?g~DY}x+sL--qRa?uEMxsdo4A%_umjX_Cs<0iK~}B>%#Qy+-sko%|}}d3?UC9 z58K(la}j-{V)wPR^{YG&Vtl6(&A39U3!j6pLf$~}~egY?t z@=eaOH4OLDZ-g_h z_3w6>y|+T>x=>s^Mx^BE>J33U^@0-+UiOLa8T{XP8`D)K+973v-*Z|xgb_)wxRG5y z)ky#4wWMRHjg|C`z%WB}LCX^hf+b0lfarQ*Q|UUEG#U}b(y*SxD?o}XSZ4j6=zFJu z&3UIo{tRE^AfU*XAhJfy9PwIK5;wW}(HDfj=x7WhfPJt+o5iEIR|kUYC6Z+%-U!;{ z)m*tYnX|(r#tQslwfYm6XC;z=pqQk0Sb?Dd*hBxq@eHw=O0-}`7tnM`7zkD=2jxOd zK5v9q08wPQ8A1=ktvxPg!vQ`<)ja^3-3Olab38$FhX`07}y~Q9E5NSpZ#>(>2v;h9MxK9HzfQugI{ak zPar@23w$!rcLqS$5XDVKFCcQKxVi z7)`E|>dsKkXg9)yo(Xg`e0rFNVYDBREF@UD?NFbSmie-tk!G$88p#CTu-joCAiqa= zK^QhOnqm-KTxoE|lu9a#J)8d8>7hP2`!wovpt_QMX+MeH*ikd2RctN>@(GylJrzfV zxJ(~_^muy-&t`PCC0auz+aT0r0Xnx>xIxbf(sWMi1hO~St+?@_5@%lGWU!5Ytq#ev z#-28pj&<`bd%31_d#VAx7oW`W$m%*rng3J7_ zc!)VZYXinyU`c)>R&TZvEn;KSkzVI;z$*sUBM4c1udPzz4_Ps>sEBaakA}0^)6A#o zhkj*yiBmF&Hx7P_JcLu^0{=%|jM{ZaNw9eO7JsBL3z9mmCk!YeiDww$iAgS}jqkvj zuxJFag6l4?B%kv@lHom>$80)ou5F1&?62J+IBkBt5lhw85|T!q3ii=aHTyf()bFo& zYcHIu3^GKEDg}>)7uN`4#m?~63FTe$=9du0DY%>hY*%gS_{TeaArXm=&NCR;nzCfN z^mwEUGEI*8Us%;0kDZY^+Y1D(1ifK=jpwiN$UWAYcy%1N0QuQXc7Gdd`|=Gh!!FX@ zYvXf7JG~Ve4}GF64#Ws8<>^TuKq#CW18hQ3yxXc6!$R50h>RQPjT8WGysG?UV8 zh|RoGl!6`n7z-_29JBF6kPLkc>Cjz3D5q_r;^&JC%AlPzNN_o^OwOkLQ7Bu_0k5E_ zs}}SF(oLBCGz|C=#>kZH&gPkn+Yo@!SjajO6+g|~_iehSm2Cc;F`kCw)@u?aCZWHfN)e7#TDatwl2H(3f*XVq7#IPH>RdCC#q%B}leh9PHB#-C z=Uy7}y?`=rn5JSeI5Nnl;GDfnE2hXLYS!&nEWF;zIDd-#qtN4NT*Y!6lJhyGb2+(f z&v)P8pHfj<=u9fC1}(En)JQRxE{|o8I4&709T2EcFs1^J^V6q8tIR4T1wyz`Tr-*` z6+axcnPr0lh|rS0Z7l4Ugr|!zcz&28Ii11DU~`HpAog+6H1ojH?TEzl&dmCpfg}UG z<7>B>Vk4NWJLDWg<8kSDgUz~IWEIRjG(v4|XD zm{QvI{UPKl0R6*Vabf;8Rmf;dc=&;jF@SCX6 zHG_<7yLc|;eK)#`iV5eH zItpo5@L7fpjj;X9EyN`srNV>39ttQ9qn3-j=@?r4M8HL6c(#~e4be7o%ON_{frWs5 z!sHk$!kv%cZt@XAF*Z3~J0bRJn8i)JLp_a{TF)BrY|3F~ziE~z`RKe*+Ucmk(IC1! zmDw?dT{2GXnW|9!&oDz8+VU&g!4<@kASzih(&r~kD0dX03u|@>p2FHVpbMA;+HX1a z9(P!klrW9~<=Y@9&`e1ditM#$#zQ(==XXdVu+Cy}u`R2QU3_fVycK6Q_n#|ObPL#QE!Gl}00o9nSqA%X-pD^PRPku~$(J_N~T z?lBw4E~2D6xkGRu`t|$kJqqWj=>6X};EQN+;XFpHr?QP|mnHLlB!i!%3*?rD$Si+$ z-emU(Lgw|C6aM~ZkN`mWCxSeUfnRe$q~5P|Gvp~9Yoe%cqTuZ!gJR=M^mGLY+dZwd z59iQ{kIi69lCea@O+OYNxPe^-tAPo6D~)Ul!aU{l41{Oy=X-WX5iXdwrG|}?t_2Om ze$52KHs`Z__qWeUiyX>)C9oMS32j&;bRp3Vd^1r+izh8|xdz?w4e2*mp@-3$*ag}Z zwu_%D-*})J2Wn8$=X;!@1R!=Ejk+f7nA8v>qj0dvsPt+G7pV&B31+s)$_44U5Y^sx zsMhinl~q$8x-|ay4*}aqx}dm$kDr(h}Tk=G?R%pae?~}LH2ZkcvAnA zc7^_QJ@Pk(`G6*o6BvtnjlC3!y3Bt?Ow%813tzma)10aZj!f^lSSguCA935Z`4tuV zRn3hc`gXFRdo}n=?%-_FZ*4jss;*_PJMzM0u=>`E&H)G34m}@q+0u>-OSmNDWl0z z-aHj4bOG;eTec%mMLYvawj0To++&U=F+=H`EaDUi>^8cd=HwZdpdQvS^Qi}hfg1v$ z0ZhT&==E{fb=WeBk#Dz(F*Ht}@N@r~WPZknxU$O-UxEx>RWW#))R+VPq_m?@cH@pA zT9<@n*p%R(51c*xgYTsxdB~do4@yHdqf>@s_4^2F?VZ3-%} z(GxdViu`UerV|y_6Aw&7$2Lh@9K5rYO%q>Bj^nE^I#KCUI+ntwfUZLBVQ724QU?LU zd6QUOB^^hzJ(vBr?Uzu?6gJ=iQ-^M}eZp7jb?8RVAFs7b_<B26(2(*}e9Vl8Zy)^_cs=8yYU#)bZ z@$vJOHo@xV<-F2}Nl5hxPkrIb8Hq13p7=XyzDh#lp3C9RzOW;GxGVMT!`2{QR+#-t zB-xft*gkIk7K-7+PQG{`n%~yMpAv5^Nq)2>E*ZbKB=zKHqH2}I^qwo8H?0hMYSr<$ zcP!1M??OKTjCS|-|a;gdpF6UYB6woB+A52C#Sd4h2k5a?p0A_Sdm@4A)T8{czu@c zmQdG23ELA3h5a#R?MumSI{Y7&BOc78kPPE51o7h<^P4(2M;=vy;LJdsw=8_)6eboc z)r`l*W>b;UmL1@y;AL1eO)xYw7+)x{Zls9dI33(i73&vk*KQ}ArN=)7JHj!C5VA&< zNLydr_NM7_907);kK!m?-k_q6SW61ne|I`L$3yFwqM|0E=K{kQjzPbvZT>Guhm?n< zCtA2yLJh;>iKiQQ$=+=pfG(co3N_E+*c3ou+42dTZ!{3Am{!Q`^w|&Otigb ze7U+=qzK(t4lVzhwO7Yhap~hlb3qNGAA$fEjwap0DQ57q0+PmtR*#HDeNnb z2dGF=7VH(5daX-dgbX#F%Y9aIc#T*3(6ZY zpNm%ffz?=BSY*FSdaVO`Nk%g1NA_Vnw%DE%oNs4zQPlJs`oIz~eS4R}UJsqMxfmt% zfe+s&cBZW}1_!^!Fz~gqeM^{j7{1>5C0ex4^ht(gYy(Rscm-&a{S~yBj1TA1{bb9(6WPzg8RWhn&D9lrBEQ zx$z*J0>lZMQRZ$D(b{<3+#?j~h0Mj-D)W@z0WpoXIMaZyY4O<6h&jloi`o2Oq zq~oyfTgu0(~Cw+tytA00&S!E;>XQt9EXd z!*GC9yD`;7hbbr*KFBTxSy^;Tc`#kOf@3J1J+>ew-sZu`p}4L3Ky$dIpUzICZC*a72&7R=E$^3q;5E{}w@Tw555^s$NaJ+0`DE?65d01Kq zm{PwjpyZd5$6I3vdWKk>S~sqC2<$5ShO5N5;k<4ZbiTazdp{~GMJ{yr1&x3+Q|t-R zyUhAwyoWQwmk&3}QF}lJxtbh= z`_d#BrvMmXXTeayP3UI3yv&X!ZUMuS=;7%H%$2yW&#DKpm~Me(cKYy5$xH0O>QyQ` zxh`?t^0Z&%MiKu+lC52XP`$BEwwhjRrE@LM* zNajijZ!P|74`YMsV#`q z&}N!JKggY{2xkZScO*c%#H>B5DH<$$+o1R?2uCN;g-cZtc7fR|rA=R$$>MZTur#W1 z&p)v2`F`rz*~YkGst@JDHycSq_)#SE8`@yd`w<41a@^-87HEApV;?d0D;68Sxm69M z?v#YQldi_357~6oVasP7hA>E%5E6KD!3$~MLnFr`^zbG1x7aC4MOd!57hi1{#DZ7vBf%|FKVi~kg)BzylZZ&6c z3%n<z3xbrom;1zMlvsZ*AL=^(?EkihBp3t#;2@OtqZ*vM8Xa)J=?yQrmq0>BB70B{1m zFPF3ST4-CO?gUZF#H%>mX$=JbH!^C@&%wsw|JfV={zHt+Kbr+m=Zh#TagQ5W@)W-5 zhhpEqMK9>x1e3neSFX8qbc2n-Sm(g&V2n(X*_1AjJ`%s=9lsqo^sa+Ngq73fMm4~r z5dT&;x0!Kv?Xu@c1ZRu@4*P=lXupye8`9Z)Mvh)m4c(c+fkI)*jkTqovGnP-AmX`B zWeg3V5h*!WBm*@YH-xVUkXmfc-3A~_V~~=6j+#9o`MSn)12^R*kW`*Oe%*VPxw`nI z?qIHl(tOvGGkvG&m4o;RTx8Ulh1~%m-4Y_J=kp+=FS?yMjcX!qUJM9!JHk$e!R+># zt4uq&r0=Wo^ARjaXxZKiNa}#L?$gQ0=Y$D5xBNPz7XXq zx)x_+a+UrlAAr<*2zOa~1H9evLOlM|7Dj~p==0BrVQ4gB7pMH%hJ7eV8Sm?PLuis? z(Ulylnhn)imEf7TD({9t|BQcMz=aG^ysSTYXumRXj_UQyM9xI6d2YgM}0wdb3+>#8TU9>>pE6??hPHs=xr-pOX z|nx!+WM(vC*RyN%RN=Z(=8aSp8uTE6CT%hcRew7_y-9E(XNUQX4^d9gp z1UoB2?%n|B+JQVvH<1eZl_rN!V$X#AH=~#C`(7+Sj@98ZuZb|u#q;Fwu>ZsF{rOHEQ4v^IJ!MG|ezh8%ZV){efwYFAQ6Csu z&cXLzH+z7@9OF~*_qdZ5i5WGaPqwsg$v7HO0@KU@pqY!P6Ae&@^khNvunyh)(ks?& zBUB?@``vfeq4BG0C+p&YRVoLRnan|;`^AEfkr&SvOY~cx1Hm#krpgjSX-}@3jcQEU z&^9^D!EYGOLLd-ew4N3G0-VeT2+T^v=zny8W~3H~hH)?k>_AQXnl%|@f?7`1eP$(4 zQ&SkbU>k}D2*Ma%l#ma#nCeOlx2W{om`4)X4bB|U@Dn851v9$rHvs-Plg_4XPX|$qKPDhAf>_Y2bKu+oL8E>l zq5enzPwC+|LmYdrkiYwpyL~nK5fllQhj50b8{d`;#r;-r9{nN|as!7DSbXz}Vk=rm zgEkoU4$czmwres4v6Njop9`J{%Iou;xe3a2k4E4ycMHDDgwm$lkBJ}sfEFPNP4guv z93Fr;YLULR$QjNxn>4oSXv+?)Ltx~&qe+C@wLU8an*eZ|imw5?9k;kg63RwjrW=Ee z`Q1McTt`C7a}MencVXcSmjGe84XT}0jnpx>ETz6tP+QSU2lZ1XEpjzdLyVqd>$cp;zjw_a=M? zJn3u2MHVTZGKjU&G9_9wcyY*qaL5d5Hm`eRteR;-tOxI*H$u1i1z7Qu&qsRK!=q#t zN7unNSGas7LXTdyl)x1jBby?$yL>0mMqvc5UfMq6PEc<#9pxhaEZj!=4|B1=YdQ!?i=hUZjoPvJbI~vBE-Y+HBtJyKtA#7q|0h*Ux!Dr z&cY{z!ldKsfa!4=6U=6sh)szk-;(gP$1;ZdK<2;=;6A^!uII$okBNO-v%9L1P;^3t z?5%|k_k8dX9bv$y^EZPX0phFs%9B0a7T)A=0!=~(oSY~O7oZq;1Ry`A<(h-q^PpT{ z16z^N@}+mx*WR80Lt2E>g(rQtxWp2>pe>%gkfGhsM!v`541Ewe)q= z*|*w`p)L%$r_m!(nqCy>$sXHuOs-rJ2Q;1^iBnH^<|_c!G6$FYL+GAfsa?&)r)WY# z(jlM-e}pzf6J=4Q#f|KENg4Kte6WvPauX!2Ot3ZU!bEj`5Je!*WHrD28B?ZBp%|e* z?9ypEq*{)mKR1>+%}jif?B}r`BR+Ocyiskeb~{<%*G=&2Km2#ab__>4^2fZVWEyw) zxR%}58$u<}D#x81Ksp5Vka2aN;SgHC4P5raTT&3BEKeSk6P z6u$Ar2y(5N@0ARs z`GUJJH;ED$+>lVyEc)~qRW{L?x=E;$n;70m6F*KG>AKi=1t2L)*t_(n0@JXzfwG8= z&h}yy=(}vdnZfbC10*(bsxx=!T~y$VEwiF?BBrE!a3+P?R1O&T@di7sXrW7i`xHAm ztod;71bI`B27K-CFiXSb4ui_14fsT8JiUSuk7Fj=+vz?pj+SPpdgMac+y^lowbArF z;A~xvJ53kjLdn@!3)a(u@lZ|UAyC6U&5qa};aPiWbKwZl`lCG?u^CcyM_}cUnqHMU zUnm|nwF^G(txzH?UZ@G`!QB}IF5H$U!N67S&tR;TZ3{fb#dbooz1q(?xk#*0-Cg&r ziEq@42(FC!9K>?u8xTR*lzVHj4`=0^>8TUr;#!k2YYu?;CC0WNj2pd;yz9?TqxHt} z4{HKN@N{Yd5;U)5Je+dUD+ax#0M3{@>=v8|A)cE2Ta{&hVJ6^FU0> zy58VGb%Lx2G##>lu=p=LY%$k;&ZYOm5+xNGIS7_Rt0^<^OZO_ zDO-{Ltm{HYda)-n{V^w0iOGy;d#YId9mNTB-xsE@B(jgskV{*l24voUeeW6!YjV?+78taDnxcL1cL$9ulR64%I#lk?^fg=j-r5 zde8s(iu0$2gIJyseXsw%uSG~T!VZHk0$y?hUjV_+UX7vxa;_|FSS16`w0p=Z>@#4@ zcL#ke8jl(EKgFdsQe2M7wcq}0`;B~*5@baQ0Lr9i51(?j8b!Ci_?APN%Pwi z4g3c;zN6DP$T#J~h}eJvH3ch4Dq|1ovFjk`%Y@z}D0JG9)#UA6XW;f+FE!u6mDc>H z)ww1IgaKJOjU<=_f*6?&ykCNI9jEXel%7|s=BxZ@U$49GO9@ya=$dPtGC2RteZdxg_=FW zFCD#Cy$VG^8{7-JEo#sdLEiTr8*03N`evjRL+dsA=UM;p_>K{0LjTaHq6l@d#vQx= zT~Gf2g#Y_D(@j6=L0r*tjmS}C2CY=%+Z8QZf=0D0dGdGQS9limJt+&fpBaO?WgYIF zSGU$^FKQMAJiMf*edp9g28ecWw_@b9=%PvhrnrqB9J$YcT~^@AdiLje0v3!+mAKO3 zuD>t2|NfiwUk^Q9_hQ8#rUw5xn|=%~VMNv`eCa1H39ks_OtpnCH@e2B8aOgi@S%*Q6V4s0Ch_+0xLuNr9B%s%evnXxL$^?f%v>as5ZyDS?pVB#JY_M z%9*mH2K`{Q)|MhtJqH|M?MECYGK(+_&i&Np-XnGf7Gc=|eC1QR0*#KTKWZ&HQ#2XJ za;tt!(7n~X`>;vq>4-zH*3z?Dzbc11{avC_jemON(f?PL-H#1OdODG}YJB=#@sWI^ z8mGQv%ANo32b#`KS42^nlh@4`Yx_sR!UDC6FUfZ>nNXAF1_!j!djI;u3A?9|b?A&3 z@B!|RF`6EOVGRZSI*f$dp|zPH>@9(Ux|P~}B9_iN=YL3h??9^i_kTPxj@hx3bx^iQ z*^(J4E3-P;tBj1SWE?9gQc_k#NOty~Wsjt6p@@tqtIXf^O85J7zpMNHeZQaYe+?Yx zb)Mt89@k^=z~YNS%$(0BNV_}CH!ano_->E!0UCi=U)3bQ-N_9F$Xx)|XG@P-ma8I8 z-gOdt0S3TL=Y{V+30gRof)sB4>xS?nz^8I_x!=?}J}*j1np4@F7yoZ>^{@Olm*<~Px%Bbi%-lqu_`lSqP4V)L_ zL_?6(W&NP9x#Qq&hC{w~1bCPTCUHoNX|JPsT1W+E5t}CWzj6mIR1Rhc@v((jBve;KU!09}Mq@6;)BPQR!a)mw{ z>MK>a%(n(rY`FoohN;EX&l1+qN?m2ebtb~UKx~9)WG`sXW*!n|Ayr+arwf>1Tu;_< zfN89e&v#3~eaCXZIAtT>{Wxf!fG8TJcJZ4pJ&I5 z2Yyu8fgRSy)!V0LABBHSar&VB_w()7KSwYVB+v6`wnmqQ$J1Vx3I4Zbb`LnSK);E* zG)$HwjAL>rm6vjx;{of?d%(*4*6|FiCB7oyEtI#Sx9IZuzz_u#Nl1ym{p z2s6md%_w>~W%LW+Xm`Q3tQ9WNCrv|94A85TAz4+iPMIJ8{|W+{fritCEIDJBVc7H) z`eR%DOr=L#I*X7qr3Q7tW=7KHEZ{o%g8Es}DOSAz>VF?N% zzFMSmw&;u>kc}VOT|h@T{6@X^AB7%SxZ+=nm}7D#0QdsW?hBce4r$I|9-oANJ<9N@ zk%^_>-ZSZEzQ82O2H4_pRz>v|iJl)Bd3DlmcW%rL6!6W+Kgg8+Y;#cX{4vC~uLWA= zLRPkuTC{iIdwdn>dHNx@HdQN0p?rRYDtzoRup#lgX|n)jbq40?H&|{6;5|pAD&Ppszv^*IoiP++e2;wXyeY0-{7#H#_Xm2f+72iRe%u zyU7PgefbcP(Q#cA_}?8^OYv`Td8UFK;44_o*p8yFz}&9Iq2B&Sjf^9cgZE9g=h4$Y z?v363fWhgW+@0R1=EsHh{7ZqQs<*pyUeOAc)=xwzBP7hPz#5pv#);Z;A*2C^D-dXl zQ2?;DCIy(Tufa0q2)=-Q#G+FYke`}hm0JaKB3gv+(f)A9LvNRh_4z)T*1RPB%s&(K zB$RUFuyHju$gyAkK^DYlNmsnt0>dS;9I`;CV)jUb7!iY0 zkEDtwAtxj+vvhY*jW$P4)&0U1|9Yw(`|DK2F@@>;%gRxGzPlbO;UqHl2-r4#4~tr^B56*| zP_|maltlyv{W@8r5U&yeB9x6NWm{{IlYNCBr3Q`1DWG*+A4xm?Py_he0x*J&1Xqyt zR>c97ienMD%OJoL;Xt|xREqj{b;6k$X2tR^W*a_Nn5`r*NGCX&#}C82N>FzXvT|g= z@|aLyu+F6>SY$2i=h) zg;?A`I8`c8z3=fG95(x>&7-RPv+Lq3Pm-Yft$+Q`m4(v zB)HWX#6KAkmx0&@1*0}ZPj~{BJ^?jgKKNeK8L;!e0R!(8xb3gaAsKGac*cgcFyFX> z@-*_A7i|Ib6HZk{O#eCzql#J}z$iPJy~4Y&IP6EMTy3XycatwEON_tEasD=$;WTJ6&jRjgIAbEYDr z(V!jNeiI#WeYq`gdRrm~3J^QL!$4o$*dq3aw&C3BIdP7jzP$aRYVjEu)@ zw306gVN10j1Byj(-@#IR0kXQst;tFkk*b;aj@#n&8&4D=%=OMRV^{NwD?fyv ze4VVkgbp{O*?khKKc0k%GYsD^Q71cE+!D~sxR3RkFY=#@YcWNOG2Ja&x{j{AVfIaW zkH0&rzreEXqh~Xa3??Af@721A{c&ki1RB5we+YB_#x?)kJ|`ZPlUZ=$k{Nw_ajP~D9;y-I9R|dnrXYGO zGB?Qw>rmX7E!>Je1KE(}tm*w_3HSoNm!PXjs)MN12{8KL-rP{_rdzHJFO3EYSch%RlYFu$COES#@=fSaRYhTPsGCIBqyW|Zd92LfUrvRoz zob__-wfbSeYfSV6j;}WOuw{nwIqcEt;I$`bvabTBN0#qj+`MG|ey5!p|LEpCxfkRr zq(Ws<{^-0c6apORs5(H7AH08xSefD+X?JoXvB~|k`@(2`Ucdj@{CL!=OFxf^*cu9w z-#(B3`KU1AyZ4O@G?of!8PLcPAutEb{g*8*EsW~hd`=aCTE0cJ4;%TWVJ|DgGvL+o zMDo_hqZpIGyoVPY_YY>##t-SnT=Pf9*_8sizIfK9|p=-BKDwd&w^oHuPi4{S7IF>~_F?DE2P-R{g8aPXEV2 zo4fBXganSvPV=zTvCD9BJA)#t4W>@Vb4|gOK(uE9y7=({uGgWE3oXz+O6}mSaD5wC z!m7|-(CCfAl=J+J_6P7d)phUSqbfRTzE7LOXOA4VeZ>N2qzM+qr2^ec`;cJNEe+`c zhK}i|SV98??I33oJ0tW7nmInSQ<^Re)Q@h18{W5%QD>(boc_c{asIh4T3n0%fHD5< zV?rhFQXyOcmqEmNNaN=pHc}va-aiv)B~A9hnZWmG24D7xmfCY)>dAyuVa(_Ka_rW_ zM9oCmdHw=%hpH9*a}WtbPe_B6H+frRYaj_WkHua04&9Q|BKo3>i92@b-U71?@pJn8 z`_Nw+S2sA6Cb=mPMcnY-82N9YxMW3(EsWXBA4YR1GPA zscy*XeB>tryc zJOHKuo_M*J*E$g$gmA$yvHnO%6kmGr5Fs^oeBn0q=41reZzaqFw-?2U5QZCL&e_+; zYsn3GKV5dp`u#He@}F_&WfsYV9L}bD&ZycoBXHiNNDtO-=!2G8&>7!?Nm6n3?+wo1 z{_KEUj|28tw{x(D!?`VdJ)mrgjGyEKC7{UB<6mCT#Nz6Mqt2JqZ9vzC+;1%aEMAE< zln7*B(iQfC>^}>z*BvD9%YmA-j`B<939vZ`$D4xc=^-5L4Y>(FXOAt47|n#!D@w$a z@m;m|WvnT71bE+Szbm<7oY;(T1=p|Sx~w)UoC7pd5Xrtlj?+#q?SXw4 zhoq^25fL=Yk4DR?2n@arfi6KR-*d^zeh1pcR*2A^bGH+4N4&?Or_|AwY&;8SZW*LW zh(;PpOuek^%QY67-q%ME(+pVj+yG(z)%WiL$FIb|6*^oXxIPS%zuu{~hnf+1?QM=M zy;dsHz_#aUzep3vU^+$#q5Cz$G&Hm5k1or8G@>?aZ%nGHTxJYUe!(>4MyT}fh@41b^8f$ zEXolXrYGD|G_E&i!_({jnt=S*b%gUJfgVa5dXnucb%gzD&t{tqZ6)15V+~*AIiT3Y z1?Q>1K|!7ZO`Pl=sDR#z`WVX}=&vnDtP)+*_7agV5=Mtzov~ozt@|d;y0ABl?SxUj zMa#X3wR`Wc=rdFO;p9k>`LXkFpNAzWY*V=@2347N87-Ol$Dk4u8U=5V@OiNB6QTt% z=gB9>$6qR(w;@=}=g4;&J7iw@2DQEWMsW8}VKiAua~vnl=wb?Ch>Li}(7l&C_}09Ghbl&DO(e zlo1EFDQP&QN6QvVj6feT0f~Lu^0$ps&8HxHojT-0JO{f(`dz$2kZ|VUvxnF$Qj;{| zC6T`nG76r1f^?<&cUYwLkA_GNDIDu5bFoI)&rq~C<{s$7OQz4GwCFaYo@TC_i8w^j zty|S@yY1$M)kJlee7issGm0qmyCOS?I<+mV=izErmESw(5?E0MhB;8g-Vq{;_m+8~ zfrN<5d>adJdwykzw-lV&qO9&WEbPsxI5OQQH6=4I7r}qNU#2_uL{W^nyq1HkPkecE+YOW05+HWmElypF%3^e$jV722~J?#z? z`ULz+q#^?2v($Pa)JMAj55D+^v8*0rc&F5Q%{JnPx&C%z{#;wQH$UokUOh*`MA6=r z`XgD^X4#<+ib;?tg**q6Tb6Pq6OYM#33{jD*v*!W)av|%b)N@TDbJ0dH(a96DK6Ew zyqX3Rz5_C3PepL3$nnB!p@^&wKz#~|=E-I5Lw)-_ejgAbzsg;N?B>SuUf+?N8M z>D}Uh;aTi~Hy~j9He*uyA<&hR$wGuo5Z)2&hEu`hjMtl9I5$W%w@aeC>G0zr4=9#H zp8g=pFP_o;%-&7Gqo8~$m|Y(MgoIAMOz)j*-$mKG!$3>p2Ta-7HqBRP3y_tW_JCI} zW5!82eq8Io7~KrNG2Ljv9u)mCV4p1dc2iq&-HXfxtu_WBqpW1M+|_Z?9JD93g3{uO zh>W<0kC`QUdThIxP^0-ZDe-f`H@Mn;$&yb8!hH!2*A^gAtJX(Hx8ZRfe|bTua?!sM zCPdZ64ov7P9MM4rTt`C4fVrmM@p{rtrq!{AJu^FQnslm3q8@~ZdMQiKeGBe^UxGx3 zjCE4`P4JT7c~0@$ww623`GeaDJal(^{5AR)`sj<@uf_1PG|kjm8N2fI!xrw_0E)Am zJ${4cO^1=Ya@x8LY0g=)A&+u4#7ot$|<#5vvc>Wl$g?(`O@!93FdE2i_Hk4#|Ikg;HM9)yfH44m+9%_`sQxiLo}KK!`bVh0ja zNpgrqyy_9hK!foX*wfw$iCUd|tAVB1D?7i>;-r5xsoRKa-?JX7a|JMM*cSuMkKEO( zz*c=U3bs#tbo}~-`}*c>gipP>L`@p;jGocf{sIgzF&~%&KvWiZB4lw0gzO!gf$fDb z@-gV9GOPvS96ws9{@ejFF9bkNHm^kU;Kg1 zUrD&W%I}PRbQeH#S7p(}^}=k!iJc4wF#-W5WWiqa^-m#iQ~Br`63>k!K7EH?w1{=> zD}d_BL#s_NWto7BlR@cr5c^UOxV1cq@m-r6;DlM&T_~1kuM6wTOd%d8#iDGb)o5|X z0J-+zno?sS@W9eZ9sRZw1pD&SLg+=RudpKEufYB3HkT;`8q*>deJ zb`}r+0n)-1?&@8D>T5UYrthBXMN}7?M?}VS%qF7N{WK@;4Io{F2G4M|l^r<$Opgi< z=6%1dV1Ox3?5-=@pX&-wzz+r}YDiy;_?j&!D|PKP{5iH*`{6rq^YDG3o^gdlV+{TM zK0=*wJ0?OB222R+5lG$!clW(G!>^yUSaHL?4!EM;sbKcthjB*irD=tXhI73I+%cq= zMysn5@EJ2OoB8%2--@l9>VIzTZ+8Omal4p3^liurP@dN7uTxGT9LJ5KI%f8hxbaEC z$`@nDP|2b6f_%vM3mH6ALu{=zO$UL62z3XbKnIT5jP((9T7-x%o>hj-G=ldBtse-7 zTmz56v?g}y572*4_Yu1#*B#V;s?GNeKE270aaVfZfpB*mgX%M*gl+FQYfDF0$8F`nhM4M^rR!2~Y#C7RU~TRh;;f8VQv*i1Ua*TiFck$EuK z&IA2GKCt-u_peGT-!8D2@r4wbAe8xKtOD9Hfgz;YaY1@7PyZVA=L#@a=xYrqDB_-xI4NHEjcDnPBe z0N6Oat_j`w=Ah#Zg0p;hUh0R9M6jv455CAac(KGV=Dh!|=4AJ$BSw0cDCPD$Q3~89 zgaY9nxCz)MDSyUsaBQ%kPy!~VN76v|A-Rr+;zAb-itGHmMXC4e~l)WMBBC} z9G5=#vcGva;7hHr1L|qAJ-Qx7jG9MJ%L@cbmNVwlvhSt00~{pwd$WT91SKQ%u$?!KzKoL_}T?JDCCmd7loj?KqTMwHmwq*@QWWjA1pi ziSo0zMe{n030KaEbL1&e?C|EXOeT@$B#W}a1U-ke?RPqrD#r7NghP}pCxVb{7Lx~N zuljk7G`5O)f>{jaEZ;m7YIzAb6>6VAkeW!AjyVeohkFJ70WX(5tgYND6fN#G6$Q%c zer!*3C{a#?JNq?9)+B%pJvpmGjj;^)R_u%YP*D^a6Ufw`cTcAm!;cKt(S98$gG`I>Lg+7eIbJAnh(i2--RAm}rW&Q} zfZT8hPC>VVbO%mV#!j*ZZwh0A&3!dnt8vHd`n8bZsOwm`^KA;-(J`9#MQrkw;S(^Q z?Y3s@!eSb{U8i5M8%IJn&Ol68%W@r@bTh;s?6le-J1-zX}z%&A3a( zW}q|VEA}^MScUCRswDmV7-y;f-ZpxZ+5y5T(fB)#(RE`MaBtmtd&%lf3q5vVvcEG< zJQw^i)f^Khge7J$vho%N5)^kIk=AEIYkmreA7#bQS06uwACd}wEKlFlpkjxi*|MC; zQo0BzEFi41)mDz{bvH?8-#m*XXO-zUuolDEK@P#xRR$s9+N3F~khz;@E_$?>0C0OV z-sid1d$BaFHV!K62$%thKsr#LP6rSt&KKGwxh7e3I?o>rtVamt5oM&ox2+H}-$EGd z-c{_+qY)B0#Nn&L7LC@ z=MPbdz_H-dg_xk*+fdwQPN~l|ZtpRG$;c87*BBPf0nwGJ;JHWFCnvk=A-g`!c~QtU zG!W**d@#I@gx0TuG%)XhKKQ6y%ne2p%yt?Dw=ex@K#0$?VL`8Tb$(DU=zyDX^ge%k z#9|hYP_o<1EKz!RzDsuFOkVM{CGI0A)L#+c(-{J&h{(}sEIeV41(~Q18-hR$;h&bL zvG9K(d7*F8R6O{Si z+2bumQTH)d7k#Jz*>{;QPLg`6@sX?N7CT#-zF%_PV3=Ek)R^p zaD4A`>fW3$7c9WF?kzG>dVplOA6~UrGzqG1I1*A`+tM-i1nQSt>niapC`|Bk-3;B9 zbEz8|b#(Z#rdv$OM~8B1wy!aYJH)T!%{e>#0sRAJ^G_xP$u9yYoQ!9u${lG(6JKnX zl&EAYd#L%}isw4{vqNflfeiBfL57Ns)3`SbqY^3NT)cA*=*2znNY(|jC-9p>>sKlMHy@UL> zw2noWK9YW&uS)QjFt?o26rK#eJiWku22!jvNfKHp2#oJ_&|!W1Kf5S(2JWR7lERo@ zd~9nlk*HdRc#ANcJ#%7p4VcKh$bg3)YG1cieu>$t_RBjjfIaf$Qyf2x5@yK z%$d)7hw$Am_a3mwIKmh=*NBP^DzblS_`)GTRF=TqxlQekTepc>q7d&8I!u1qB3+bU`Ip^(*vB)kWTg0VY(lFS@~SjPUt;7&~uj;HC&?2aEUZrEnbO^oTz?P5;6i zBjX|V*7=355xcx{xE zk43rv60J5ZRaN&Tv~Zm~3s2h}NiML-v5!b1jma=U_sIJZ9;Ms?jMz)+ntfdqD{Xxf zFcE|t*8wj$GrWH5N{0A zX_lXZ#w)jaU5!sSeXKX=!MIO@2QZ@XEh!bb5keC(cigyDG{$!i7FX)S5Vk+mXO4Bd z#RF+h-sfwO^FfBMY-0#0= zGJ0vhIb6v_`;!k?u-32h`5UwEc?DOiH{)fbMKjiSuSf)0?|OdC4d(=;KLobU{Nbxi z=GC9l;;wETuzk^7+yfqoV^(?FX`Z;XEX=8+TltoI7~nOuRRjCEGS3!MS{U zV4+E|-4Eg~^*6@vBakH{2v)332l&Ny&k+KifXR+HgQFQQ6+G~dpg$4>?5FG_A!29E zDeDoYxBkfKH9}XNqvw-Q2+@VxYe-f+JbvRF;YE6L=GpXk zd3g?ZiX4QSmI!*$A}7J^hHgC=l?_Cv*lask)z|p2?iK|Ka)y&o}aY zYA@p}h=6(KWvF>_RoG&v!CTzCk(`b;Gu!wVZD-FmUgBtNk>9!2IkGimQYEko#ZRp@AF1VrGWtV{(YT;-}fsq z1)8JlStXjobjVq*S<>b|NvUTK5l}|gv4?WT+j}_SG1h<-FjI)Y!?Ltq60Q8!BDelD zkt1qIh@K!+##VYAO(JrifonKEeE$vmQ>JEYY#sA&Fr^|g=oW^)OTbh>7_1v4s}ZIY z;ge8DgN3ra^foB;6_iXW_uyZEagbH-YnF$1AYxeINt%KjiAuG7^Lnsqv4^%5RPt_7 zqpLuXn1u1z8BhyS15@|OoG*`DX**lmY0l}LKe7Ey@n`e7M(cucp(NlG4mklm=i{MO z;$BPj9rU#kSZHoVRxJMe=OB)|=Zl$-Aycv7firX4$z?1p<@}8}0fUd*A|Jp8KR)zA zUNuF47IAWo;rX+D6LYQxx4Ud*kz6XFA(~#-5fO~!6vN>Q%y(S9P|JBl6)+dDe)ts> zT&+m^If*8bSE5x1H;~dkr>=&)leaO~gk?$$7lH=xY7rIOis>cgdg9(Xs$~kZW8b_m zHX^d@JwzM=oVCbUfRs`F(UAMu-n-p*1UKtl_SJ!PR1Fj%YF1qd*)JFA7=6PoS#Ovk zVC7no&f-e93fn1|L99U0b@aV(4{^;O`Wx^o*j0>J0mJ%N%d{m1X-NWuE}5mbn|)zIF3G8h=h_i$LW`}fGujz^5B6c$rWE{2J})0*O2 zS31}PoX+pc%7L8pcPYnZP9D>d;GoibEhg~^gRR2`!0L6fDS$gJ%<$%w4~tE=2pw~z zlqEi5(HXVfr~nLs#(>QQo-@hb8WlB;k9yDqb-Wa}9+DfZUZ0x>{lVp9>XrBL6kix| z-WHj+Yw`sT5VU*D!;`~CZbzmNlG1{a3k}mdP{i?REIY5q`9Q?SGi@iQ9S&071R9~! zp-*JaFX7oP`msCniiDM&yBmnADy0PPm~Km^SHK>tX1JGTbKICvd}tI|or~lA-SOs2 zR)SejHw+T@mdA^MEW!8zPl=pLOWg~}G_5txbMDH;Ji|H~R1}?IXOy_S81utMAdM}F zlK0enGJ9$L`E7v2FHV6){{F<8J&ft-+k(+SZS-60akSU*VBo7;YR?!v+Qp%y=b*r4PdnDIYL7u13FDoEMdfsjpt0fT=cpud`$Z-^Z94LL zX;hjW`~VH7m`gWCxw7KS!>XYDL8zuWFR%QeXTacicHLxjlKxZ@u-Mi`&9?^>d@Sga z?RmHzxug%*XRFdN<>ixxz$DUJrp=U8*yAk2Ud|gojrJ&G73t73xZ5b{XLcswrc>AYfLu4r*l zyx?f3dVGLFYW}9XR`*zJm_`xJ5%iG&z1ZsM^1+j1NEOB&?{~d~bJW z%cg^vD%8oRAE;2G_4%I-*}ky|GnT^)8=;oS2kJ=leQ~Br7XI^<;!lG}*Dljw*`K_H zZkBEvBx?tui6Zl1=di46UQJ7J;P%%!}~fvy)rQqc$bUzH;y z!xR`2UCRLdIrva|Uw^8+dML}dt`c9&l!YRh!=f#}VC$RIck2%z7+JA&#J@stCSS1k z%$!S51#;Bo)5KsdcPWKkjF{n9|wk{IQrFbor%VPUcYDF##c_s z-{y&M$1Tw$17P|N>3>KX(I6r=fD8v&j+RgZ#+Mf+of+_W%CQ>-u z-d3y{)9-lI@3T-ZpioHM_*|iR3$uNsUb=@11lr4%@m2lX zz~LmMx@He#mC-lP!n{a{h@}BSnR`fvw2?8Qw))B6`#HG8@nS~Uin~>SCRn&%sCtYr zT1()-5;E4?ZhU_osw*1Q{(04x=z#Z=RGbIMxIiNgsS4TGced7Mnwu65_?)=(hZ0r} z|EJ+kE~oS-GjH;NY)qh>K0}rZko(>a2ykrxGM--vU{iUTy@p?rURI1;El$)p^3l6D z(lyUz$&Pd(vw=~cjck*7T9>*5>GrtZi(Q}~B}dz|GSZ^nqi@r!0(BzYuMOVQ>H*>2 zTeaOC!uq%O1s81sFvfkEo`UP9RG5PN!P%Uj?oQ?5X3#{Irv4X$IzTOq@3a zb5zTzKc~gYR~kU?q2=1a5z4iC~;} z*CqXL>k?W618IH6989|$fz}75;Qh~_*u`7OL&P757_s=2nkCeV!Z`rD>m>k#oy80& zmV}g}AT2p$*^GAw*W9XffDnRdu07+V(Qt{U>AY@19e_hP?lddJ+*>dPDP&fluqeQN zpzPMBigAMTqS_o5r*{~&82S*6KfSpJ3I4g7T8;=rY=QWNs>2rFPOjrEAc)^b~*OJP+7W*5YeoBQe|OtjBZu z^XF*8W#Ra8iJ;-il)Csx%94Cy^l1<(>Rx|J@$FA88v}V7{CZF{|TI&l@O7$;_8hB_=a+H2;B@Z@DRf5BD`OHZP?!gHl z;8YqO4X(lW!T-RN-=qVe8O7`1l^w9v00YOhlYW9Fo)S&0{B>`k9QN)y?h}b#6yUWY z%UK*UA)YSS2w3p<=Z`~`{Grgpl4t8Fk)LWVrVh7%S1D<8^_AoLQTxc# zj)d%}`Zl3o6Lyspe(Y%*2P-LNUDctthkc}|O)z4b97>B(T zj_onoya@yb(M_-s4j}-)=9>?q;<}q>Hco>jC0GUo?djp+?#k91nU| zgQn|^i0)#1YU1A?$z65O_L(m>(wGB#jj5Bm=0X9F$^DfrILP3(d02p{eL+U*KtDZ6 zQL-xVCsT-B0nan|Vu6p)6!#RR!>|l1<}e)1qv+{8qGNbMfrvNjf>{T{fcIoQ>?A2lS>jkRg6UKD7_Awd$rKGE1;?x2*P1*8pFr><`bQt(p z#4+Ar6xkqU55TZ`)RcH{H+TUooVyd6B23b6N)Sbh-8u|BeQkeS@7z5dN6W+9y(V9n zvw%2GC{w(L%8U(#g7{6FSd~fXSbzT8OkIN4Wl;je?9|&0OCi?#XPZD@9M#0;i~X@! z;5rk<9MC`zWBK6xl>LMTr;-}Ye`#ouzhc&R7fIHi7l}UoY?Zl5@UZEu&o~8kNWNfD`BUC=k(IIEiH!y_O$24?+@mkS0=r6?f!rfL(~q1EzQep+g>wN(LdJh=gP#wpO03i9OkrBaTW0kKMKt-pZWqhaxAK zi*(Qio{KL+*QA7!o5m4G8R*CUvkX`&5 z636bM3%s%-((n<8W9`n4sV+79{1AL4RDpzw9g>$=hE(P0HZivV#9ZL0340qB25NH| zN<-iy_d3fwx(oCN*H?DFclqj?ggn$!pt}$gFx4LOgvyUfuU}?wdK)zTClyy)m+8a4 zkCp6M5}SG{vuH-0%&UmHk!1h}+(Q^EoejEg)owI8O}r%t3JW9yI-{18&7AH( ze1?7m+lLU6!yAs$`fG$*x><>KpWDZF#<~N;G@3F=4Rr_RphP@IQ^Cllq=E7Y zD(XCaxJ+s9pj?(IQ}1RT5v9BuxLJoQGG&R!*y*Dx1NO)mK9%2dRH&P@Gr$ka)&CY? z;5kzzOKDmzZOOYT+#ux09c%S$L8D1$t5AzXw}M6w!ph9T)f?k2QH#MXdbaOnHy7Np zn-5Gzn5r4F9yLteqkS^Q$NR>E{7;?MF0D0=?iTf$bRfA=VIuGYM&l^aQXb!ckO`6a9S?=E!&yg6y@~9FbiUTPl`>7y*p~Tywa06`7uClO>I?VPV z2lg`fCGNX{p{b!MhFq4Ou|Lhku@bwL)9SC46WAXpGW;J|eOv}twqqhNd#F+aPr@iD zh#IFu%iM<`unXZd>zgs3WHvj`xg`CAI{y0cF_hX>m{P}GrU*pt*O431r2ah85p*Ki zkerL97c!c&-J5h0qiDh#QWK$0%J}iFB}?#}w1#$2K_VQawkO^0ds!x^xLxHWXWDIt zI&44A1UF|`Qg`DM+82rE}a7qM5^aGxVL1+*s zVUX1$W_0dJp~y|PZd&X>jWTf3mq>U!UM<=|6w_JEg8;B{f&=vdOaaw~K9tRZ0MUVX zV;U?1Dpz_h43aB!jyK%c*vdg%ya1=hl(LyPm>nj~p`|$Shm&Cp8cZZ(1^xT!{(orG z@%8@UAC9CcP@X!k&YeSKjaF8qqAnhVhxwKC(dTQS15INz2U}uZU`o@4cp);lMDNv@ zUhw+sK$I;b#V3H|%qi_Q_bM5{_e+h*fY#dv9|++Bz4MeUt6DJsF$eIMkXtqt0F4~J zQJqMaq8}bR5dotxsu&QR$LGo-QpsFAVH#QplC$f4-<+&yZxPWPmk(qEPQa@9jnBe2 zkg~O_)Pdr_u|;XJ&rgBaxZX<1D#HV!;MZG#fwX{d)!TKo5ndY!-|pkE*k7@;y)i!% zZ8wC^7Lx5y{)ww@D?nhinH367UOJHh?mG|0_zu|JeUu5j(H}>gs2)RODQdCz|bR0#2W}Y}k!y(a5=;FUf<-!QucR9aHh(Rg*axYOLb&uig zUkl^c%Sag+lLA8V$URx_YdzUMAT!lW`~V!inQg(6;pBSJVJ0Amz8+=Y+-|773fjSP zdta^p#|?$sv0l&^OO4$*5$-#s(epCJO81mHi`E4APa^W6@>>{`P{bon@YU` zmZx~UfcGJoUuavF{o3ej&BB$PqmVvV=Cbf8_2^o4^&ORwn1aM9$)kXfE^Yh#nzbc| zQO1`q)k>JD)eD_gxP?#?=2IUUId|#RDR=dZ&_33B%aa?bo3+C4mzoEW?P1Pml1a~H zkkVy7)5W`Fq)Apck?f{Hn9YEql&h*(gS?e{_ zS@uukokM-|yyD3tnaKoe_XG`DJWNFFmk`dRLIHuKV`|?OAdRXgCE2LsvHIE(eO>7EC zq;v2i6^@cRBTn1lk{|bbK^?Ey^Ws__K-fqSW%}7De3A1fjp8~f?3bV#qN1-n`ziyZ zhGLL$ZlEX7`}LkFwe5f>%VBQ9j;}q4q+S|``-%nW<@Yk4^3G8U)=sFWzY1k|gXAQB zWm*3EAaXQuuo~!kFJXRVQM38=mi=h;h@isT2*hNNNy5>jpTi&rdkOkh_XgT@?FjDk zI<8_1*BQm^qQNhj(=Okl{~FmQP}}E#0PuySp+WG|&eEo9&>@MV9$!9DxD(RcSPwABAn*X@jr0XQ zm0P{b>xdjU^Ds2{A_jFrgI9sO?MRouEY&Ufx2)~(-Py~RzC5{!FIcz7v| z@g<-?{0x0mfY8U#S9MkfzsJn}$gjlFk`Rn5cybZvoV{vDZ8Qf0FFSCXI-HVXa!UaP z+U~9;XF5AzzML4o4$}hCj;FPEws}>b_0o z5Cu!ULO9Gn&Q_B7$0+#236u{%>H_rk(8i1j>qqdQhT?|AY>bz;GkQy%%;6lFf*%NV<*&?&@5g1r5H$bvU%&5v?_w<;g5--lYt^G~Dbqe6KQidOt{L}lN8yiO z=5Yk6(gthU#kP4zoHO{tpX5&r)KHUIJ!NdHKf~CLp-=E-r zmefJ{-P4%je{mXX%YS2)eCL2J4ds5}vHMk_Na`fV)w}_{fBLQ; z*QYFuh=$xpt#}6&|M54+M1<7Bg_#AOFE<4^CYPxH_EBM62vAtd&gW*Q|LGigOiIA% zDB1@||7F1X$oOc6g8tzN(VoKjZhvnA3^4t{J-H6l(Bgnb_v|?rd zPYcSF7NszD83eVxDJ`+7Fw^jV(>4ir?3b~H>25>63RvXsb zh=L$TVd?_Se|q4Jq%gR9NiPt61?B)`%d+TF(&cf}54(FwH5b<3^0fl7e^`Exg-Hq6 ze}r9RUaSZQv2M=)&r1!Lb^|NV4(Nv@|ErgZii)y?+oTB8dkiPdR!RQh(``1yfyQAF z1n1eX5OME_@eTfVs(hluI7S&==?(se&x-aW4nvTmpKD|f5|?7A;EMkJT>LqZx2@_*%`0Gyk zYoRtv;2sko_K9Y&S=uSFZ=1KP3(hu5=GXnx1~sKNEcq;Sq5686Uarw`&d;`-j(X9Z zva5u9SC_|3 zCwP5kZ~kCPI5!2^4E8{jFCO9}%qe$YV9gV>aQXEa@kGmM;TsHI^Ij`6Z8(_;0EydE zxk<8O#rA)?bTAPSwZM50;I}P{5;E?DxYXN}`6%q6tIaWtyN{{lKuuvHdU?czqKE)&GP@4{U^6$;>^ zgUrJo{21J#(r63M4uKHg4pLfj)b2AyOzad=4AP4dR)Xk)QhM^fP8KL-Rsnjim_nvA zOu6%K@|q#=+n5Pj8Kx}ZsComa-LuH_y`fFYnRyFi-}j9GQoV*xWae$lIc9|8C(N~}qry1S#hceX z_~n#1Xn?VS=Q9$nX26v1r74&=;&s^)?Bwm7-D6XKd6xh4t$`%zs&&S`*+mpgl?zr! zpX5iC&=BOvkof%U7W}A62c4)>_#9LBg@eV(!)&9f!6-#U*=P^&3&kVP4E>%YMPkJ4 zfJqGezob8MHwEFLAhcpOo{0^oQSeQj?i~00jj^wr(bIK=IeMPi63`Lpv>CX zSg;3=0hxI!eNiExACwR{SoheRk;_>Xn&n80_qeH*_~ArFMx6wqzIJ0W%H4sy7y)m_Bh z15t6=Bwzn3)NDh5AI^txh6{(a+3H9*0K<3{rbZUNi=%c>CKN-Lb0PbD(bsa6_y}l| ztVrVpv8At~>at;O_iXT?zr*uE00T$Zm=EO6ODxvz9Z4bWfjkJ|COf{|%o8VHca!Fy zc+Q7K?uF|08GghkNYsAtO%T=60Rq11FC?Ma4l@vEa8ueMgYqe#OLwe-sg(O0j;9DW zW)85Ys~?u7yg?Z<{GoYgxhd1gD*SzzAph1Suh&1b&T0(tl z#_+?$Vn|CUsXC7+yoWc-R%AdS={p4A`e%KrPjqEQf;zcZM5}UK_;sovxeboEh2iD% zHLEHMwr~T7V(r?eq^xT|Zs$I{!kW9K&FKjKR8+q#BF4k$H?>hs<@Q6P1EU-E&ZBo{ zHWZKdh3zSqloKbMD?KHrvruYU8+YfQ`olf=t2>W;GM6$~?%ZM!`W*bsJQLPlsaNLJ zL<_htMwZTqwl&vAIUIP?Q2?fDt<@y1Pd4hMg^1vXoN1Q|p@Y0f3R0r#^CS zyFkLU|b5Y|3&wMShHCPsNJ%O&yti7xZZs*!c~g!4Mh-P;tJF;Y}_d+nw69 z`qh&7b3biq(XXE!hs+1JfJ6}D&Vu`|ILV1$d(UPYu*T03Iq)z{9c(lw}Dv_A{CC?UE~wcAzr?r zk%4ajMUbkS$@R3%!>Ji6cYh$t1)WlDL0OefU`10k58f{CdQ!HA;b=HR7pzO67G+bJ zp|wrNGxh~MFiYh@36KHPH`!z7>0EX3POF<{3}6|;hkNJj>;f?lQwpgX6RmfTq^))%2 zbin@U3DwlRpnB%J>U4>fj}0eEZMt+=O4Y9VZo*Zm)(LXa=#8h237y{!6T4}S%gX0h zA@{3%S&xQv2e{0<%xl;HDQ1P=J)(@(82pIsP&KI=0IHs5Xn!-C0W%BJrH#Z*NK`^d z@}=^zns3w2c2}Cu3tkwy04Wp~D%`Tgn+etEly2)e<$!VGVGo8__SS%5|72iZ=7VVb zRY%m&#uR+B9a2$D#l9osgm$VPH*7nii}cy>*bEzb#z) zb7}N~id2^n2oYXw2;eeRCgo}>b}~L;;`5@5DFS**NaghFsFQx zRlfq0o*}raoI#kPB#x(2;VC}zLfP?g#x`7E+N*h&&_3ep>VQr@F!7W*FY8k};jkv_N-wO?+f- z6zlU3dWf0Z7(fti%2W5U*AlsXV*#p@IRs`T@om6&F!dy7~ z=UG*@pKd+7P?BR0Jv;5!vr!K%#C^wFFRU_J$B*+}{N!HYzfLOtOd%uI#~`ylns5AD zT)ib}%roBTClS8T6{shY6z*h%r`E>DwpU)Zbnsg^;XBE$$Mf37+f8qeEw~rZ_;C8=S9%5)qs-m!IbHX+$h@oq{h8AA6@1@GUT-6K52?~8 zEYe8zL3=@QRQr&OH`m)){_}oE?cN`g(YCn+^h0;kgZ7c|#=PaH%A`WI^h!W~_Qw8Z zr}^?}@r#fEL*YLD3j zMH~1nh)lvBL0tnxTi%|{p4F~S{eOlx!J^rEN2W-i^@msJh)E$9`Ih^rzTPs}0V$;i>0?Sguq+e&$wWDQQv$K??d+%Be`K z$BPp%Ok@JkBF#dJ2~i(H=$9opv~-q~s1bk_!Csd#?D0GdNAWugSC)zVdw?DGQaWwh zxlHD1E(r|>S#>1Cu;0_2d-DmlkoQPwsfIq43C`_mV+|H_mHsNEyEozj=kX3tX~bSe zy9@53w^r!L=gf7M8 zTS;zXr>C`v2+Pl5=6uX96u(cb!P8CW=Ml&ps>g zXDychd4;(ZF#*1L=9tvdwtp$y+1kjC9L!vW;#aFoR{ZdywKj-6?FNtr7J4PM5bp@H z-1KSO?`?*zjGiHjDrDJLU+!@W#LvNhE*XGz39*or6#>a!L}(D zSxmCyq7i;Yg0ImDlQ-wY7vNO<4Z%ux-~dMQKJoHtL1U2zd8gN!`U6@8rTa28zPU60 zW+nJPWc*#^L^rH6&LZAsi=*{-NS8V5Zk*FmU*<{4m%9g-fG^ZN7n&%2FYdf@9^Z}O} zW3huu{f-MG$SouXFht?=SyV;?7BzuHGP z3+&3f8J2PX@^UF-=F>yg^^OCi`KzJP)a%MJWSg(Q_V;sTFr|0pep!znGhTJNoCs$U zcWTs4zw6lJSBEuIpMKQtk@Zi;3O9FSZRC=k8BF?0?t5~S`uRmu7ti=U4VXrEohCXl@jkT4;f88!!Pc=DQ)!f;L(EpsszILrv?Crd2^ zn(`XsuKc~iDrp=WT4DVstz7HV9i}O>@|NSbQ%&3b;l`QI5Tuf zyu_GJkm0k#Nv^KAD0Lm^(?Z6NbP8H$hhzD!4Miis2+n*ahF;k5dERWvIBD5(@e1kb zzELCX9-}u}wqNc_P9yLf;ACfU4{IpOfn5FNWBBryV|--NW}Hw7ycnt8aO3P$=!A~5 z=Al5S%eUTLcpC{mKVp3I3ORQs(*-YvZ`<*N*D-Vt@?vhs1QKl`)2p=7pcDLriPn zf#H%#E}v#0KkqxFR^zrmq}Ex2p&HJ2f9Q@4uGm^(sp2S-=In^|4b3+cJ=n_V+9ONj zj6KV#E(jj%ox^8v`AWM>y8RsP>(| z=LmjM?Q*DGQtn*2LF9p>G1Yl(D$XG)_pj2-Q0La&#l;?Za?!b@X=0s(cf<=Kr2e>Em3#QFxP1Lu4K7)tZf9xh#A5E#xh29~b|fSceAg0>0)1M8EB z7f^A$F}thZ47lCO1qzs?FVJPL-JuXxnW-mlJdlZgKlAfpDi%hy8=QZIPX&LZCOc~T zZ~K}UljM$b%oe=h4Ymd~TW6&WATTzmV}qOU5!k3cI94}f?xHWU8$@&LmSOA^$U)ae zqtvy<^~<>|2Dzp|Cy@>tMpi5c#seqw>~5Q58$zG#AX!HaLt}bf)aKw_fP5oKlG}N` zXf2f=V{q9Kyenoc$%S4|`GU;?8bmvjwZMm!*8SOpp-7tm`rPS^0{;vl96l4$8!`1p zTSy<6UO^YC(Ni9XcwZ$$N|>(T+m5KJCUYO8dNQ#EKguwNUUEEOKw)4!v`@w6HB?w#Q2Jm( zOR2dZn*b>&9Wc6XXOYLphFwWDxguLp5i8sAvmE1WkE3QDcze)ZtiQ<4)|qreG{XVO z>!r7C(K*Y9^H;$gL3~n3s|o`T3EVcH_RG8#Npi%9@Ab&@78qj_1S{Ohx3|6T9=~9I zFCi4Q2X#u&!hd8F9>3Mx`0C!;HsI!)pvR=hHBZfdvmfVv3~ad+SB{%8R^YdvFgSc@ zz22V3BD(tRjeD~mJ3RsjbyA*9xi6qTHe5kJ9-HROt9HOl8xsi8&CeuaRy9s%#N_j0 zXAO%U?pXp*qaC14%^F#8Zr2Jfi|Bkwm_d$d_oF|!02CCih8t9EkB^a6L0d?rgM&~x zQoQh~R-vCu8?S1Jk1Hul4S|vOLzeorG4N;|4jIoANx4Ph13IFM0dy~x@_RHLIMy%! zycXH^!hiu?tfVHdHbw*&)wcpjov6jU2WRjMT!LyX{n^fY34!(KI%`RdH{4ns z31h5_vyP#nYZD(50VvKQ#W1-MVS-VKtE=-$&EDT( zOdy4q@5??Sn6gqVon`vQY^kyGy-~BKl@}5(V5ztSHcUv8p+4y1$mwFsZvfbEq0>Ha z;`N&X|E743+hcdNCqEsOx8{49!`iyFLcz?b=}^B8mbX(ujq|E&)0hgRm|$Z2K0|qe z-9bv#<%#PT?Sg&z9in&D*`|+^&h7Q2>(GU&CL|3A{i4^3d^X&+qsSMIaH`_e!V$895nOnD7co{)ZiuQrOWSOE) zHTeOwUnyXA$I^pxMHDYdiTjtmE<=_e9HtZ~@)ON3nhS8}ynULqsM^a+<%Xwby zQ41P=?xuMl1h+wLy8q}TrRJ!4uxjZXR2OM**yXJ3*7W#h|8sxKq_7+CTN?KVW!!&b z)jz+I(qyV}=I=cmENl%akh0}T&%NlP?R!Y=#Z}=DQ9vZ8Vni3qNZO0aopT2= z>o9(Vo#709I8-kP)v9bh%+Y1md1b?C%l*;wGg$dmYc@RV4F1K*Ti{8U?dd_c}t*!KBgi&)qQuhRCI! z2b3in#}1mm%ko;@MdHrvAydA|r6LH{J(I8*R_)J3Vt5?$3lsZd+_pEQNXH3IE+rFgs&9l*~2{~RVaj#}L&_wIs&jg5CKr@<~Y?Re?VKrW1^4*<~(VhD<=PG6n|6GnS)dSR^x4K_< z?U(xP?`?~WJ~JDPb2>3!fN7Tcp?d0dU1T(RZ}$FVy$Z>RG2&KWosD6y!ye6eR%@KJ zQay!VcI%mp*P#Xe1U2>x(R7S9^Lb?SLE&~* zVbUWkV=&cyh>4_A#htxAURznF{xN@4U&-Sg_VYF2Z^WmMiV&692Ox^I1D|!6LznG- z^cZEWW5F^HkEqZ5(agGYc~%NIVFt&M8;{^&Lr0C4CJ~5u|nPc{oQ1I?EoT!1Ht%pq|H6nz+kH9zxs`6baVJbl|BOrgZa*0waL=epkO z@2-+5`x!z0wetzq-@A>m8vy9!#H;%SaA+eA>qqm*jmOSs1qdizf|*dHT&&xeX3@Bi z82vW;UgF#HCmkM&92AA47be`I83Ulp%W4i64U4KCS#=U~Wku+UNL1vqox7`Y!+wvh ze(LpSw3&7H0;K81>>Cqu$6OpmmGnfW(G0$m*zc&fasjk&DNTlV?YaX{}d9_R6{M zE6&V&(X2+O|M_`KEYY_R4vA3}J{U!}LmEqwN}_g~IWVvJCID_r2Y>X3UZF6IGZf*) zvDag~H)8@%=20nu>SOXpx0X{l2eqDUG0c|qfr&~%7h3jm9S+~6I*N~kr!hu1yD;IK zFnQ=8X=bIgpG37-_pieL+u=0`C~-0vTNKH@;SMfiInRSEy^BaA5vNR(sT8KBL&u9# zQS|UHTLPS>ZNJR1-ko5UHX7dD{G#5WdU0(vwO;PL$Hj()H8p>6D`T{He2O1Ts_ISP zOnc7n0PWl)R5f<}{T>1rUPzP@awGppkvIt0j@;PvtO4B^rDnX*E5c)B*k2k&I5gy} z{XF5}DNz(ZwpR&fqYWuE$L5U-!1~bOji%)jx@Ev^14U$3+JR1gJ@jP*mKV44g(-sM zfmb`9>hOc*ckGq|!rdu)&wxx(i4$skf0*A=H}#9s#nVUDUOq3trFi==8r^AkZ0}oE zw7H0iwGJ7Z4uf+tr`afV{z_MI29kWK~LQVq9SZ0~q zUaXJ5RD#LzR5hui6O;0CaUu79rrA@_dh;&F!O1KBw|iqrp)(1CdUxM z-p!N2w>djxB#+}zm*pd<{2gE72RRq17_%m`3vqk`#5ayy8hnppIbXdB{XPr*O70TB zyaG1s*;)&`NV(45>+$`zMSEB?Ll*N^m}7hSVYN|R_};c&fzib3MlMvw)7WLh-O>A&Q4BQ3pN2c4ZKk zrd0NYJl`-kK!O{s7Y|K5-IQu3>(*8%!KeHhuCxK`#+nk*0=4fQv{f8XguWt9{K~wH zu5`kV*0BGI+;MQD+Pbh=icn05_EGzGQ(tY8(t3JoXE-jPr_`rY<8tHpQN zVbcNr(a?`!J~SfhP#APfv}yBTN4VsVUq_LsA2%2)<4kFM7Xqp%cv7R9TcI?iUE+JV zgg?%P5^Y4PB&Wp9CIx#;RoAfNJGOf?#8F-nLB+A!o8}lUSt-e8V=`uW8>(!5njcj2 zXq&g;MtK5Fm4SSe8quN!@%wj>itO#(|3g^%QL_2=!U=V5{g0HDU*@QP|5e2RDy6Hc zd{xq2I}+$R!GdklUD$!YYjmHcVc5JQKOM9pzK-bJzdGFqU3NmQalEK z_6xXR*h#FG^1WKc2~y$O-QaqBvE6C9gkOa?wpV-c5r9BvQW>+=G#iPjnz)Wj;|U)u zzY@1)Kf&^85=L3fI+No9rEN|)LRH*3gI#}v9P{e&c8+QLPe?zM(Ag|#d|%2ym))w) zr#BW<@0HM1IfUlva9J}APgdbrdZLFM4qrffkS2K!=f=sU<MGV* zsaKoldYJG1BGDJ&dVG=7qFj=pjO!S26wg9G(NPVwF zh_EH;6ZRfDBCA|BwmyL-f_boA;S;0}1RHW>&}|v2w$LgSdZK}POo_LyEaps>NJX3_ zA)u%ko%lr~GzqJBg}Y6kUW0xb!I!yNCbH6t$vZ}@A|>os*TXF`MEIs){Kwrvb5YqZ zl~#Hw zA-%c9Hul({zAApyn^a8?mOQFgF

C*YH`y9Taq#9LuQjM_qxb{;ogZ>-=yjrjf0 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

  • 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

    t7OJBH==y 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

    rS!8In9QmqM}vYv`!kgFH5=oLekz~vg1mP{ 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 literal 0 HcmV?d00001 From 1fd234663f43034b7da0f295f8918cf92cf0ce63 Mon Sep 17 00:00:00 2001 From: Wali Viqas Date: Sun, 19 Apr 2026 08:43:09 -0700 Subject: [PATCH 18/18] fix: force TeamSetupView on first launch + structured per-article digest Drops the bundled ARG/FRA fallback that the main merge re-introduced. The AppStore now reads only the user-saved cache; no cache means showingSetup triggers automatically on launch, so every user builds their own match instead of landing on the hardcoded sample. Adds persistCache to save the user's fetched cache under Application Support so later launches skip setup. Gemini curated-synthesis prompt rewritten to demand a structured block per selected article: numbered, with WHO / WHAT / ANGLE fields forcing concrete facts (names, stats, implication). Prevents the "one vague bullet for three articles" degeneracy that was showing up in the Notes drawer. Co-Authored-By: Claude Opus 4.7 (1M context) --- BroadcastBrain/Services/GeminiService.swift | 21 +++++---- BroadcastBrain/Stores/AppStore.swift | 47 +++++++++++++++------ 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/BroadcastBrain/Services/GeminiService.swift b/BroadcastBrain/Services/GeminiService.swift index f2f03daf..847aa69a 100644 --- a/BroadcastBrain/Services/GeminiService.swift +++ b/BroadcastBrain/Services/GeminiService.swift @@ -42,16 +42,19 @@ enum GeminiService { let userPrompt: String if userCurated { - // User hand-picked these — synthesize them on their own merits, - // ignore the loaded match context entirely. + // User hand-picked these — produce a structured per-article block + // with concrete facts the commentator can reach for mid-call. systemInstruction = """ - You are a broadcast prep assistant. The broadcaster hand-picked these headlines. Produce at least one bullet point per headline — never skip one, never say "no relevant information". - Group bullets under these headings where they fit (omit truly empty ones): - INJURIES & AVAILABILITY - FORM & RECENT RESULTS - STORYLINES & RIVALRY - WILDCARDS - Each bullet: 1–2 sentences summarizing what a commentator would want to say about that headline. Plain text only, no markdown syntax. Under 400 words total. + You are a broadcast prep assistant. The broadcaster hand-picked the headlines below. + + For EVERY headline, output exactly one block in this format — never skip, never combine, never summarize multiple headlines into one block: + + [N]. [Short title, ≤ 60 chars] + WHO: names of the people, teams, and clubs involved + WHAT: the concrete facts — scores, statlines, dates, injury status, trade terms, exact quotes. Numbers and names are mandatory when the headline provides them. + ANGLE: why a live commentator would mention this — the implication, narrative hook, or record on the line + + Separate blocks with a blank line. Number sequentially starting at 1. Use plain text only (no markdown symbols like **, #, or \\*). If the headline is vague, still produce a block and say "details not in headline" for the missing field instead of omitting it. Total length under 500 words. """ userPrompt = "Selected headlines:\n\(headlineList)" } else { diff --git a/BroadcastBrain/Stores/AppStore.swift b/BroadcastBrain/Stores/AppStore.swift index 0632ea43..a2fd5da5 100644 --- a/BroadcastBrain/Stores/AppStore.swift +++ b/BroadcastBrain/Stores/AppStore.swift @@ -73,17 +73,13 @@ final class AppStore { self.speech = speech self.whisperEngine = whisperEngine - if let url = Bundle.main.url(forResource: "match_cache", withExtension: "json"), - let data = try? Data(contentsOf: url), - let cache = try? JSONDecoder().decode(MatchCache.self, from: data) { - self.matchCache = cache - } else { - self.matchCache = nil - } + // Load only the user-saved cache (from a prior TeamSetupView fetch). + // No bundled fallback: first launch has no cache, which forces + // TeamSetupView so every user starts with their own match. + let initialCache = Self.loadSavedCache() + self.matchCache = initialCache - // Seed the default hackathon match so first launch has something live. - let seededMatch = Match.sampleArgFra2022 - let title = seededMatch.title + let title = initialCache?.title ?? "New Match" // Reuse an empty session for today's match if one already exists. let cal = Calendar.current @@ -97,7 +93,7 @@ final class AppStore { }) { self.currentSession = reusable } else { - let fresh = Session(title: title, match: seededMatch) + let fresh = Session(title: title) self.currentSession = fresh sessionStore.save(fresh) } @@ -105,6 +101,12 @@ final class AppStore { // Sweep any stray empty duplicate sessions (from pre-fix launches) sessionStore.purgeEmptyDuplicates(except: self.currentSession.id) + // No cache means the user has never run setup — force TeamSetupView + // on this launch so the app is tailored from the first moment. + if self.matchCache == nil { + self.showingSetup = true + } + // Back-link whisper engine to self so it can read transcript + plays. whisperEngine.attach(store: self) @@ -366,10 +368,12 @@ final class AppStore { } /// Called by TeamSetupView after the fetch completes — swaps the in-memory - /// match cache and starts a fresh session for the new matchup. + /// match cache, persists it to disk so future launches skip setup, and + /// starts a fresh session for the new matchup. func loadMatchCache(_ cache: MatchCache) { matchCache = cache showingSetup = false + Self.persistCache(cache) let fresh = Session(title: cache.title) sessionStore.save(fresh) @@ -382,4 +386,23 @@ final class AppStore { func presentSetup() { showingSetup = true } + + // MARK: - Cache persistence + + private static let savedCacheURL: URL = FileManager.default + .urls(for: .applicationSupportDirectory, in: .userDomainMask)[0] + .appendingPathComponent("BroadcastBrain/match_cache.json") + + private static func loadSavedCache() -> MatchCache? { + guard FileManager.default.fileExists(atPath: savedCacheURL.path), + let data = try? Data(contentsOf: savedCacheURL) else { return nil } + return try? JSONDecoder().decode(MatchCache.self, from: data) + } + + private static func persistCache(_ cache: MatchCache) { + let dir = savedCacheURL.deletingLastPathComponent() + try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true) + let enc = JSONEncoder(); enc.outputFormatting = [.prettyPrinted, .sortedKeys] + try? enc.encode(cache).write(to: savedCacheURL, options: .atomic) + } }

  • $; z-J8tZLq2cclUVgG`Mf=7TW_8{*n2KGcy~<2M^HBu7(M~8*!4}fdmW5Ghp;5e&d?@n zJZ~O~Z-&T^$p;PkwJ+Esb@tVbDIBgPzfB zm3($g+vOSK|3lq($79{UZdQjQ9I}p678M$8i>@z8bLxTfahU(2Sk) zS~K0W6|09t=Mq;-KoCKa(4f=3)qN!IBJ+qbutx;kQ9x$6DbnY01QUF7;n)lnNmnoqem`2#ZO$gI;=j6+LfX41WI zu=>1&xkroZnK@(|~A{0iKz2iX^o9Xy;~ zNft7lE%F$vZ5;mw1k=-z?@GU$Y6|(bHdroS%=@O*lATS-d)OOT3i5U2^!=}+dXmXT zPa9L5Ue%uw@$oc@Q>hBW+ki~;x+tmSqvSfI!w1fWQjZ(?WiAuo$kD>KJCOz*yh<}~ zXG0FkdGdqv{DU84U#fQyWmECufTTWpn^zYGZM$ECnrG2mE*TdE;I4q%a{4AvgBjgx zBe^#3y`%u*M}>?B2neB8Xa0=o&A~>Hh`}Hpp zz<(PL;EGrF3EpB_5ey}&Tjv6qa>C!fhRSlF!vJ?7uA6+t{f8Y~3B2icF8&ygIXzbG z`{;v$y>EaD()NxNbdqCGA&;i@3NWO7ovv!}9Er_yodnvQ@+PykrlS$k+n2iXqwFt0rCiqI}jS`U?@6u)Pl# zV~G1Of8E@(0DU~OXCpIqz=EEvEKqxWoSxQ;ofMvgnzVXMF$i0|9vhWvItWUAKD}H?MB9L9K<9s+eOy|h+gI8E1 zS6}+CPP|*)HwN9}=aBqc4!qpxIwZst2eQ03+s(AcIbsdZe1j+A%R5p)SJLJ@-6cOn ze@|`y{v&s*7cTDedEGO>*WqVIzf*Vg+~Y$GaDFCL+*yr1aJ+5U_>iQ$_v%6A?#IcV z(r!oA$wpboH}mOup=angcq96=C#voI=A6K+7k!X`)!Roh{{rO`(twnzD7*ZTnKW$G zey=q9Y!WFS_N@24tS6TEkK$eo;5C($U12S(E`y9VTl$=TKy}28j00Bp0)Bik3E&Q{ z$CmRpA{b~Xpg;TVyuSX36l>376oAIIBk6}eVRG^-k;XiLtiPJO9VB0yMfR{>L388k zoF9+6wX`4B-r(D{1>80|NmMznqj*9VU|PwQE!~cfOOb3-+TcBpq{s4vj&w9O0Be-K zBhm4-u~nZCKReo*C;f`CUQ5gko8CURhi;4Kjcq8I()ee&YHI|0N#Q|{02%&iz7yHC zby;q#k-FpsVoG?-0iEG}fFL?aYEAo1>=%+7gn>P5PsM8K`Nx#P_y~%y+dh#s=!XH) zdqbu}jK0--F^$?OPbu`9*uCO4lWNXh%UUx$c#POVDkwX-1~sz$kh~`I;WFNbg`l z!;#1KzJ~}qK_V2YV2uh-(K8T z>*eRou;m+&1&Q%@kc+R)sAM^I0T%F%JmYAE*?aE`&GyG6t`mDtkj!iGlL~n{L$Y}s zedp->JQQB)k(1L!BX#ZDB#g`>_Y8?%lu0udCfHZ^~|BLnm!#j;KC8p z7Z@^-;@`Lm`A?Zso0(u-CL*&a<|SCpg5ONi^@NGFx)>QB&ci@I#$*}9Cvoz4dgzUT zdbZMP?ekrcZTgZ$i>9=P0&uck+@#XKVh$`S8-y(MwK1#(MaA5>0p1}zmQPfRT( zQGPx7BAZxxCa_A7g_iQ+=R%SbuV7|5!O5BI?q|<4v+)B+Q!e-e+WW1I$~xK4>7HBd z@nG?bG=NSjZ!c(x)tb_FVYA-{3uZObCf|^6)_k^1?c1cIH_-z8A}76;;vyYpMMk_Ddvx;kRgS6+ zpQg@A62EM(U@M>wF)F@eRqw$i`DQgcP%ILdXPs^#q-C^|2oj5r{R^!r?g|!&0*zvT zw4!WTR!d=p&H`u_JnlE8=}s8k@VLJP*b|=eaO6QF&VW4Pcbf_>6fQs*5fXm(Z#mWQ zqx+u(b27h|f3MC16>KQy)W^SMt!G#a2{9n~94VgAc&{`p`fyl@O*Jt+gz~#_0v>9$ z@OZN{f91#%-)Af$)r^vl5y?BEi5B!AzpkFCKj3}HM-%86L}{cK>kD*YPq@qT!H zSkpfqZ{-9|2>r(?a;fKRr_EAFPKtZN*ykzcOI+*s8JGfPRVNI<4Ja_3A5`MLkD;Y& zRm;hrI%=#jZU|0xV$p{QDUw_vSM*)1j%tccBtxTv)mPOXPbMzg z?WClkpZSMg>PU%ugHoPiBBg<|)?tVNI^0v-y1s+4S_Q6SY87?!VfQ!tRYwt?s$lI>VUwtfaxY?}ObkILHIQ>tP6D9|uyE-yKc4^f=_0sobyjOk! zfMSew16q~{B*mj zRAm}lLdlcnRJu3(dttEYbnc92dR(2@R36}!dFu8~P*gXjvV&ota{I@JKulzl(^c(U3@D0^5!pzh@SWRm;>pekGB3k{6$I#}O zBYlgJExgdNtts)1R045LP}WDw!DLx-!RscrSNBr%4Y0n_66yKD|+657;Z^e|RzD z5Dq>e$lOjCUCR`35NsyS11AiT5GdlAlJhW6(GT8`oDeSpwASi2f2qXwxgG&4D&4gs zU8fSE0#=Z$B}BJ&fsr!wz55T1+fdUxyJFct#@V}VR;sO^jUzkK~~z9PBDu14qD zpET~D?yqU!_$mv1jWOVP0{6He+57}}+3s)Qm-H0pP6KhI(tL_`UMeD5B!BllhPhW2 zJR;R2ea%>M)B(Qvk&k%OF)?Kmo9Me^)zM7p;2`xKLfb}~$nYlgfRbDB+kD7BlXx+0 zfC!+fc~_H0!M26 zbwc=~353j^c@0}a9Qu$t$}{1@1gspFSEt0TT){a+5Kzi9+a zw|B|MeE)j(B;cZup=i>Vs#QVu$P#dn;&B;}^^h^zQyg#PLXQy2f_ULu0dYVEIjI?7 zv`>ZZ*iz|)o>8tY%>?`MTaZ6B$s`=>frIG{EXJoWPIe7mN>dJzF#3rlbl$a_K&6Uz zeFmwSj`G{bvI-Glm@Z3*GUFu~nQt;3*I@Vo#tw zAq@c({FEt#Aa(Rh!g))8x0+VKkTM#{(zpCq#zA#^>CT)k(zzZQ#1}Hl`0}NT5Vh(K z()Hq@@_10e{>mW^;8cnK%esHEZ+BmW-rxT<<6pl1pM7z2cV9^T>%IVcY1rekfCj1u zJms^~50rZbvZMQE^tC6Ep;j+Am16HRdHrIRmm?vI??+@MEAJh zZQ1E`;Cz2$wj^t2p5O}F*#H=EWQH_9(T8>n zjC&21Is6zIaDt12foRzX;KOu?oi4OTdnxO||C?#m6_f;dt1#O9D^T-!ZLvRX2O$s1 zXp2Y0G9lx)Ltu}*tqCCZlhub;(lucZ7VWL9qjaN5r=#zRLkNqv*jSlI-H6a%U8R_X zBfr#}{5kM$v{US0(4-uAjvM1{$H3;;*g3uM_+N_1>R-NB)m-`M|KmU&@m&k1^?wnR zf+xASJ!o4v!!H{9iP+EdWVZt>f8UG_mkPu(lLz`k|xhWs3A;V2gAfjA0j(iENNAI1VUd2kkW4`1jZgZNh=SF89nzu%$PyhIXo&#KC#Ir^=j<{zBE+PJ^pi&s zD<^{v&6Jl!IinS`lXK^|y^8wEMqP!qH(ppXTfiATsW?MEFS@`Z?9ME7@yVh>+dTQ^ zMi1!Xv%}8tp5(0^G_HF^TY|&p7e`q5qu6@?_R_J^JM$l#=RVGSY#tm~i|l?B)z`Q& zIPlW(o4`0A(RUh0VGx*6giZcMJU=z$IPNnI)9Zh`Vhrusxs~dOV4A{pm~A{DlsWtY z=gv=ICNzNBm>cxv& z0l&Y@W%@Q}v_XFa;kl34N_FE+GMMr6i5H-cr1T0Y7;fMoRyz0Ly{p-@2#Xc@&$-3_ z`KSJ|7%g1`k*?`Cty`48kHP!(&9N78tCfNyC&~$RPaQE5-kqEbBBf!=ts2{zN@Tu^ z?%jmq;$B~2?n|nWi9K`u1hBLT5|e(mDoj^a)YR2Y z?aHt(24K!)KG?wR^f=*R!1UD)7>IdiOXF_=Gp9JD6hW~O#v;iZi`wI%qje<$nfTV<1Vo-xb6F18-O2!JMV}Q^X;U^Dv|I5SdG((>CM_txat8ukDqy z&d7EET;i#mcwJ;;hHI!ssIXd*c=WB^&>+&pv&-I?fkHZJUb4gQY%}5}I#-5R@Af&C z%;q~*CAYV$s1{xwDHu++fGaggwo#`%Aqc~UZGe5l>R3i|NchJS#~*{}yJ+@Vx6h_w zp8<_Yy81~N1VnH0K>^YSVe|SG7Ch#PjX9wLeU>9p;1OZlyK#8_XrneW9hFT5^oLv` zN?Ll%j^$kn3%)50gPL-t<+Z;NXg{) zx8FUbTH#$~+ycab(zbShxJ}pTd6bjJw$&L2#bn}7DhxUtVCrviBU7%|L5So zCwS-!+|L1Q7|8Fxr9?gVLiP9W`1=PE*g*RERj{HabSj(9$_)n#Hwcv--P&$hCY3ILKlrKPRUU%aEn zi$I)|`ky1Ez#1;)G1=nKAXqoIMkz4ddYOA0jF zZR_v_VvVy;l2%H~sT9=Ius;)?Z#G#{^6O1OQw_vvA zE9u&Y9N~pA7w|BYC&Ad}_KZ!}tK-0PjPks52`fbFrV>b(+_u8qYgihmq_ME((wDH& z>{>VS$Mj)qVjmWJo|^m~BNEl|(|er>`_K!76GCcm+y>%eT>Z!6Mse@}g9(TI zj)VeXe<+YCfpb009QQmPFSo0F;v?yvwWXLHYZx@MbU@(UyLXAxo1bE~ze+Q<*K@KV zg5g;h`|G6dC7se9pg#|@6Vw*uuB1WI*azf_d1y{ zVVPPzRJXWri^0x%w{jZSjT1>g*10@Yh;6b4X`roI_ImzRv#2>oP`=K6h5-oe407?l z7PXv#rOx%t{)J+((hTj%c8d+r)|i)m;tH+dt=5Mt)||x?CuoAc0?K@8ny!^p#^;tK?dwfRJ^`^0poHuP(SK10SkfSsV7S}e>STDsd^ znX^F5-8COueT(?*lwD}GhHKa}j?&x@a@h>K!HV$L86&1jjNB)T8kZIRvahkF#ZHd6 z`S;19f8QrL3&LiXC0HBky%}Lcoy)45i;JnoUM{5D4V16c?pLZm`|fyaued2i2!HKO zTRRv|TjAm1aa2E#_)p~h=SSKP?+e<-h-`UwK|f7t=mCZp>=Rf8TaBdLlg0*rTyq6oW8972;y6tZHe_YYe%;8mr zn2SphxOmqg{!mkHFbI39uI3%{&jbF6-hLd^XY4oYzuwK?SGarri(R86lo*E5-5){m zZUWOp>>kwaeN)zWU_W;gJhby+a<2bKt1b=-=pY3g1;?K29c%Xc>j!@i-cO!af^;|o;`>#bzL)gia9K}G zLINJB?e8y>)=B@lNOqsItcv0G<|TNlIpAG!x=7}ejr4HpnJ*x1tio6K_|2NM0s3`Fr8-}qq4!hP3dZw$ zT|~Vpnu`5JAF#1A06x@EQ=@bx#zDRIl+G9=O}EO!zY?H)oTgJh2U|}MdEOrzALrAtI=?$|{?FwEyA~P4Zt6@~{>)lJ|E*Eno(sc(v+^!@=1NJj#%?tAKg-cFrXmfY)iNMnpb~5H9b9>sZ(ItHrG|`6tT)zqq0ZZun(P1tfrQp4~-;k zxcQ9OSf;e`Zzg+O7p!{|d$u?xad}Q&XvvxASU2X=-%p)Tul> zzf*f&sTPH1`Mn|z-NFk;@~6xpB;`8mE9@1LnC^=i!|SpY@(jsqTcKM?#HEr zKc>!d!13Yg*uC2ROTQk>?}yV9B|~t6px!KSp4CR&N!3v(Eh(ut@X#2;G5K+E zCm`rLhqQDN1%KE(*b#D{hO29uv~bAST|3-4Vvc0GF5H%1Gn13;s~|5(m5tw_TamgC zHqo!jDYLe(;qBY5T#Sk*s^`G&;Yy8^EM+ngX**ZKqqUm`S35PiO^7S}k~?R- z4FaVk5*Mrjw3|f!fBN5_G~pI4ABX?KQpSHRzSr~v4Q~AF!6!mDH}BagCyNx7|6nBW zSbcN)$>3nA=l|RP1}<(NE|i-O&*IxXDLCXRNp#_;kChsr;q%_BT-Yn9|2$?+B5zjf zZ2m83fdH3KcdSz48})7myk|1;uV0AOhZ6?-J?qHsqUk@vWFM;25>c|(>H1ql|Hr53 zUH~~PBeHgLW^^PK{I1;KX!<>4%fDXH?y-fA0ibM=?boq-pHpnOA<1yBDDyx39!S*@ zG$Kgkt}XrUE#8HT98JkO_*aPf{fA>u5kUr-{qSL@hL)BEB#?<~JXWbN_SFdz9PO2( z;g6p?*%qG~5L)rtQj4W<|dM2`_sUZM5bCJH01rZI8+7v?ZXC?77Lsg+z(f7 zsN64S8s2KGe;`1(M^tL9#_d3>FT@Dus?=#f4U8dk#!h{gO+xJ^;tF=xy4A`H09us{VT#@_My|>W5*`;`0;%>pJ_B9`#^94sQ!EK>A5rUw`Qyyr1!W$ zrd%9$jdKOyHK*<1@Uv9Ad1x>|hQ+=!pzzqQJoFo@*l=o*@I?&Go{K^Rjb+gZ)v>TB zkTv$`Tjw?X4MF?QQV?SydLEXUlasRsPb53^Id^bSHekN(jg>ckm8e0m0$+Vm{qkzh z4LeGtrlHXbOfiVawvVl;4h5L*@jS$+@wnTOq3yp)^XKol_-52_F?8SF>+k-^TUprQ z9N)8VsqXbF6o`R{g1`|h=(P68QqN!M`Jc~%FrspE%~S(gO+ZN?>wD8#%!q@^lhxck zt;FUKIBvkKC2Ft4ljCYEbi0fbX6W&+#&f`MyJ^xTG&VQj~qk*6IJgAtgaG+hCm6|Fy4b8Ex=Fd+k z4i{Pm&~5AgBZ(G}`QS2net$L6r&2ryNjPjrT-3mhAOb3;zNA8JzhI`g`kB zsScO}l=Yebr<~lvCIn&!amtY{!G|V}sqM`9$rYpLz$FpRj z!P_n71)!J@RvH3$>mPtG_c&5n`GOHkJ6=Xd{ZOL3Lqb)>88`-^4GZb-{`IF~O%*d! zxAs~Uu`Yz^^M#h~N$RgO%rvHYQj3e(+DFuXW#-ORX{5a7G;7uj#q<#XLt>}$QcB*p z>K&ums~r29bst}Sb$dgr3s$NU`)?~$%#lYPJ4jM@q11D)bE(?+o`p zj{)>I+Cps@?3cjTNj%+Ol39!eK<$#Z!Ih=m5w!7r#F1W8B z>@#}Akq&%qc@GZV|3rb`J`xK=FfePNG<78%LZ{JDCH~q`OdZHIxK#`9r2R$?s{*-_>6-2huH;9Zpr8rDE2uCPXp2 z(&`fLzH@mF1iywvARn-M*qtSSZzZOD<`>;#N!%BcjEytOgVsei3@WvR-i^HF_lljZ z7JSm))T^23XM3Iegtas;FR!srL%U)#lvzt|nC;{tug2YLW;%$#KzU$>!_LWB5G~9{ zbb!A5&zt|XHWqR#XFiK+Lc#zjGUlp0gx0g7r}s)RryvJa=RCyzE7CGq|NK*T7mWY` zx>c6o*Ysri%HL1wpO5gCmLUuSfM90CmBJb%OFbVKZ_sz&aV}qm*4v|5e+gvxxo+ zC)Lo^J;p1JA^1-S{l`c37U=KaZ$&`k89UKdc9r3O@!+sEhjMK`$@AsK#l>YEzV&M_ z{|tPOM|&U-#PFWe{Gc#%`SYwdQ=}5ty!gXWMQ1Q&J`s zC8bZ`|L~Huk&GfyaVG{l)tUCcx+&;-UjNlA@c$qGk|6{~7{6VR|M_MF&;RPC{_EKK zzpMx_`36ySH%zym|KF{NACp|xk2vzPfL8DOKi?GuXkMo&wdqg(fX!AA_Fvv(?<)mE zy5(xG>HF(w8~NFLn#>=2;ayEoPqkOVLf8X+FGws!p#;HiLeuHF=^(IoP+SC8*&g6o%x4NsCC6LCGRKbdECQFc7pOzD zdFR?5OD_nG2C!J#ID;qkXGpoNI98~^6}uBS!De9Al-cbD9BOBvwYZjiRuGys0isic z=y9RL+($1M-evG+=Md$h8w@IaDqxyn15S(ledh6jmKr|g@Nk$nMu5FjHQu;h3rIfN!s{442v&;mzdch^j zAu^2F;QREl*#LDEX3m|pRx>b9!?>&JZAT1kvQCv#;gb~O2H#nHN7EVF-ZP6Z0qJ4XW`!n( zxES)vjYcmD;CW|)AmIZ?yMt2{S1YWWqxoF$zEYeoCSIA(C7DL00A?y!4cglW?kL@Zrs7via zDfTVQ{>P3;QPW$uH>6>T8=8TTmpoeX;GOb*g3i{~<3FMdj@ z>q3*NT=+wzi^uB(nqBds;_pe+D}OQCsSt{*0AHP~b>02yEm=UXLPNLI><&4|Uj-Xj zx(ETsL{hr9>Zpx!tlomRnpw+DE;PmN`OEmJ!Re)fy`8rLu4`KV38Xgr%~wa>%5C zb?1^pobB>;ov`E2mQXx`Zw`jMi!w&g}atRcJl^BC?PP`*7{z8t zK{kiYP4@GU1B-TKc`7Zlm>{MH1S4xp1Wa7ioaQRh*A_b%=Kkk zb~eb0#hoZQEx%|D-6?3jJD;5k-TYR^=$1}D@}bWdyjAiCocmmI9YpDc?BDEbg#p#% zEB#oGjtP?*Khj)8;y;uQgr~Xf_2t=V&XUQ*h?%F?&Swvs-vs`eBlg|4^wDT@;LO4h zKWhjIcCG4l_!!`>P-0ld@fBR_LnK?IJ8-1v>3HL4RKB{VFw;xLXK}Vy)uo6rYL6;`6D^zl5>{^ExLh zD=#HXT<#NLGP9nrzQ}Tq@f=Ra%VcS(U&;AD@+ByNYOT)LrQ^>RKZn0{>Jxus7>ABg zst}o@a@4JjWd{1$BRVR>Q{Xz8FL6k?qo6%NkxtJdK9Ki&my0HRya>47ap^m3930q!PDwU&+BBx5 z`FzRDrGg6S=e1<67P4`91@-3v;}Uu;{?~AJmOOyFX*45v-}zvko^G6Y z0pU1$0BFr~FD*YJ##~&k_sIS&8n$l!_lYz_iB6L~9VA!b67Rqf z92DJTDxi7gT34>1p)d%?QDlP${Z`>h23V8oKl8W>H4p^U&tO&mb-D8g7}DCBMLPI- zru#Fx)`K7EWDCLROYV9fa51;Hfh1CL=eo4M0Jx3MK4ix%+#E2=$3cNCsF>mIFnYTP zi?KRc1O_v!jW7RM)xgPtuElZcWH~*^wM`wUymKAq67yW!ja>Ctp)-~TURO#(qNHP= z-7f>DXn}q!$L-tKmPCEpzWf2EHHMx`EI7np5DxmBCN#D&G)<3>z4ZR02!Je++X{W1 z?>QeXOCPo#!a)WCgdqGAppvDLD4Hj{gi}-p^#Ad;Hz09Z2AHD{L|5kO>Y@1~e)ONg z^KWKb%4T)xv2;-Tvg5bSiJ&xNOOvoB-f0_P*eyDLSkHlx45nL=qyjhUf}-eibW}Fp zCRB!s3)A_2UkqVl6M~_O2jDAI7vO+dj~L;27*QazO>I4K z)7V?S&!!;i_)`_PdT^1aTiY7?*vB(@7z0LH)7y-I!#2;Rk#%rC4aafRS0>F}xR@VzfQeslhXw6&`bB)R{2x^&x?@*7@Q~;? z@c^4Yqcd?q@x8V7`U#C`w`lnr1?je_j1Jf21QXm9+}o}Mnz9MI{>UmVE!D2;2xID? zg`t@;&`y5!B&=En=2xm_%o@{lIO*CXaVmiFvId4A&IEPBtcUK_6i&sHY*SJ{V7@~Z zD0sl0bqg6uKlg~iX|@0ga2*)Usxtrt3t7Vq8@-6GB3hJv|D!E=iS5$FnroAvKF` zOqA0UWd*?ijN|J8E7pEz;!LLrr44s|UNz*=(7Yg z_`>zK$y6anJDC|=CvJ4XB#<6;t(epHrd>~QP@u2LLQK9rgOOpweUM#kt@S(r4)Y-7 z^cOuB;UimOX&z|{A~bvFI9uc-Rp65Z(^P-;2c*2h3zY|)n+3*u0Nfu~?@?0AVbMj> zI_EAevm)b(IsjAbP$-PxIv7Y5jiuIT2uYN#uU|Jnv4QqQ+yCIvQG=4HRi~}0r-7B7 za03>Io0q4y@5mtVs0;PCrLX_76UB7V7dlw#%CaiOaZvjYvi{oZPS6%8+QzS~*m-k} zrsTfzX5NTqs&qXW!zh84N>TOCtQf+0>+CH!LW}Xg4{sC4SifzPwrzuQ#R{eC;9KDe zaUZ+9Fln<2aib4PrMaf{nB(^r&{4PBub#Ib7;wINvkDu<;QB)@d5n zv^>?1IAvxPtM54bRj?0du)4iTipOd01Az3n_e(Vi=UY(NbaJQ;rvU}SR(n2D*Z7eu zY7j)KHo?NnSr8dohC~YWiYwTwjQ=IS8v!=2gbVKhRO+4LFF}0+HMGL(lBnR7R*6H! zuCEcYJ}k|zT`4t*1jjd%rte-Qp?uDE?p%(`(zjyldN#;9J_Gx3YYj%Hyf5EcrsvCS z_U0WdG)u@$bn!SXnu-#defw!E)~~|&#p$O+y5N*L7&tMe_i8GRa!%>ANT01xN5^YL zYnP4LJG!eUos0M~LvH4OPMl+UQV_Lrbonrb+p>*JXl7W?wj)X06`AN-VGRdm9#Gi( zV!9=*pU61HrryD1CYP@VumlD4nxtjqKTJ*2P|7NAexWw*24(bGUF+?*rFHrw{=@Wz z?XogXPG=GoDq!A*(9S_ck+pd<_d+(Ln{K=|87vq5lOn0R-!$4w~Erk465m?U*+iUT7 zzH5_et8^JDaF;p*Czc>FDkQ%KAn7B+|qAFA|F0WRtimNzX6%tqK zR8<-3O4gZ6Dw5kXD8$83*zQ!Xw_Wwra+s|!v;6t%Xp}L11d%RY=*!<(SFxtVKCfS2 zjzFlwi4oF2lnu>4zRcAV9s*^D30>6GLQU|6&bAc9swjkWykb02=J9GEy_PiBkf&%P z>-CqzFTiBA4_2c+U&a>H^VD}D!ISQ@ou}K|wBu^RqhEp*Z^yTq*C@vaWitx97P`Nh zlDUMfUl|f@9=KL&)j>E@vDOrz9iOH6>WA}5`(>L_z5blpf}!&&1Qqg8)5a*1I7Wfx zmxK3Mr3=3Yg?==1xc4Qk{!?b zKBbGV#mA@!$o%|?q}Yf}<7?K#a<9+WB_u=aC|*G3^vW~j;x$5&bDYZc5skIVKDqeE zP0_-Av&E1bt-a1Lf%kYWWgtE-u6ouJ4zE5KyFHuOxxeSNKjW0aQ$gvCzM<`JEp8N0 zUBXf=_5%~Y2yttDWivCn$rko(G`pRPdyJECV~@Lrq+p0@r7A8}`Ix#%j&+=0|-c$zEC@V?=1esJusnb$h~*f zK{4!s-*>}dxzoztM)tLD*5P)Wg+cGMotGjb8wwjFoNk~rPWq$af!H8{y9zsepu%F%04= zyfReUK((cEv0>h0MX1{`rwdP}u)S2;?wLduUk@yVVg>j8U!VfLJs<7*YVP4e72y}#laE%R8GY-}O~Brzrs7k#lv_%i*aJHXC`-sY zjf3UwnW;OEM&D{kQFdabJE~u&G_Y{gEOIjFO;B-ZNRP2hxk{1&D83^5&O7U=mNI|n zU~z*q<|rv`>ky^b+H#-8_8FcsR~r?pAIzK};<1Lhbw#@%kz9!_D$F#Fv8YRGv-Eyt zCyxjznmy*kh)=c3y6}pZRxh)DmIWl^&e&c{(S-((Z5=*(#jY+vx=>}~9TfGYdb1D` z9I<2CvFjdA_{l-I>Xb(UGg!L6L-Lb~P6MY?X=&WZq-zeQFd{55q`0*GB{~g(7q=DM z5Yw#0=67B#O*(a_{{Ti$o+kHm{VIuquG2ry=e*8*vDoz)TAd2>*yM&BKEP&Iz?Q2g}NYqfDzmRz|AUK;?VW!6Rr z3$lnjPJU7nvF%@#4KQ_=h&->n5?|?$!;gem>GB>k2p)SL^!Y04RZb&h=N%*EuRV&Ah*;$xyA`H>ASu5j}IM02tn zf+gP;*sS#_2xaV)Ei}JT#2!oKJeE8I&wUvZnL>;CIuPC4B7jV;=hn2rY^?us`?*5htKsIo@^!Omx)gPC=H|8MD%xz6} zXU5QH%Z{GnQz9pI#_(@=an9_bi#=T-8G z9ZUq-CbXg>ng#&bp-&jwp_=&KBhy^J;@Y}f;w@N1y~;8SV;LCiXYxL6f*XG#;XZOq z2cdo?)D;F{GPcXX^^g?yQBt()tLai%rw^$uBta&bWL|T{(+bdWyu(s>%<<#8E4Pz= zf+^e7$-1<@_R^_1tf?nepyW`=o#T81YNAh5WR`JIRmBFKcIDq2(zcT?LRBu?Q9rLg zEa#L*aQyNm@MV`2zNJSK@}M$ws*{TC0ZOf66+o!9w5LZ$M*9`!BcTNCn_hwM8RvBCS3M;ofEl+XBmq>be;KuQt)vX`NO z;$uTSIi@%k$fsWbHGYqL+J4o*G0>$sECD=ciCerfh!r0Bpmzh;PAweCEw`6qJWJfE zCRDQ0&R%099b3ex8nCW5*-5{YHYBFbe0{m_96!=}kitRr;nH*pML}=@%vFK*n0o3( z92AsM^N8L1+@NjI7&Se}emmSfpoBn_<0Yo+C;X(VRg7U;jmU&JhqlASYyaNW#V_&8 zpFRR|ZVXykj1D9H!>fGuZpI6a~~r>c2&Aa36)aVfT#dpRCz#lsgnWmEmkLt%_y^NyFCJ-wY^r_vL; zw6gaTNNvDVZu#}Ju#ny}*FjQhI8T?(Bqvm`^eTAL{4mA$T~y=F#0G-wdVUfH)@&;G zc%dsGr!8)VCQHYmEC4{cQ(x;(d!JJ88!o^8NAq2bAFsMqDLSw+R8T-gcwt?z&?&^V zR8Lpayy5u=3>It?ra7~M7-I@RCxHR~iQlytZ#1KVc$ z+!Qzw+=?=EnT{Cc3U&PoVZ6H-C9V6o8zutj*eDTA>R1E(b{!_*lFYthJPV03fbYjNl9DV3oplc8Jgk(@M> zcvGiEK|#LRgp6E4GTO~`n>>;U5pSs*!g*%kwcBHmKI=6Gx@MGpmlNfkDm)rVj>eyR zK}EPokZgvv z&H;mvAqHvE&Z$|Img{3^0!I5XvXbx^&$}&_5aZ`oWa5V`a8nK(y4;F*575K31$u$& zWerF|c=V8N%4v1Hoeqg{Kq#gStR$el)9PYS**afHS2N9)(%a>9?8Tp(7O;U@> z)VC=ZbbVAK`sFc~UQ{CA_fAX+*^-cI>hxr?trE78E!D9rc^2ClZc)qb> zD;WJ^%oj5&7dC7?B;k5rz~^gx>boBRDbfpz7$MEzQfNxLJOW>h{1kR`io6?!tQ6RK zbd8k!O(UPQEO@3@kq|jP6eF#yqUWq96`x)P?TqcIZhbe7k&=14NHB~g)`hVJAHOdx z4KT3bzPVG&o=T%`u8Qr+ep7DvY|0*cuA@02E@)bfVA{78@mEo>O?iHo!2&vcDnzlN3M=nVsqpp0)`D5%m>0!je&;2pO9_W{zBTC# z6*a;0vnF=(ea-!r@pH*CWIR1i6A21sex!Y!Iy2oY8zeXs#EF57?&5}5N3X&u82Hv# zaJzWy1@?+~(-7d1&d|`e%F$@sNGsM1>8X zI$gpTC$r`cIj@a{Z7dB+x>vES(7 zjM&9YPRpILr=p)y<;Nc1S@rj{c@;n^^G2vT)XNf~0@$VTmLO2Aom+sQ0M|b{Y6y+x zNzTs}w;ne-O;S94w_DHT4|E}Q#Yqi2w$8V#W@IVU*|x-DGRlDt(5Lc zaP;q-SzS_#s|>9^$XWIyuFth6YsB^|-8>V_4G8u*_r5qb*h`bxgva!1(raDj2uMGB z^~%M0V3y&6-KiNkC`xE5Ex}TsB;GtB0Wmolkg%s@+DXKr_~0k|!6JNHM$4xo?bmbJG}{H$udQ*EwAxp)__LaOz%5`viaseIM*J&yx4=5J1w`@iq>g z2j#*;jww7W9FBZEm+Gju&NIM7LtB$m@<}=!+%y#B4|w zEf}*BeRrJ9BhiSyKiJ}rHY;H!QrjY3WwJakCk|ISXh080q@NABT)!=lJ3drsBqE??U_w@k9 zWqjxnDmdL<-FhHOnv721JCkRh2`iX6#hdWLa9SGu#e7VrY8p!4=f6^=$1H1XLL=e_ z>p;>}fI4a>6sp-AG`o}eGT=w;heRe_p{OLHzj$KZ&XDy03UrR#oel)vK0h1Y!ek-?NT~9z9@@k*{N?H{>1P&4j_X=Q)$ot%PONMqQ;uh`%XTS!yq@mEl4m zQu0b#u>BTKJ4{^ZVQ_7Y&Cs29af&)k-}uSqOvTFJMt>MS62H7S2YK8`$B1K~L|hN? zEOokc7COQ=pRIqClqjOfYX5mOKZ#Qg?@-Nf{Xguzc{tSj|37>pOQa1cvb0%CB}@S&~$?hzv7hDf>>^MD{g%$u^d;4K)n+^IhkBKIc^Dy1w80pZogV z*YB@$T$eEK_iK4RAKUZ1UR_8{Z0U_ywr%Yh^-xXD$X=v4+MLCBk3#)_JfcDjWLIp? zVFSu(2P&ZvbWyPh8z_P_|E;D1$J2M#=>;*h`QGlJ&su<~a(%$0e8P}k!4Ybe{zs3# ziNh$nE1U}^c**jhL49H zUZ-*yli)}o=3E*CynDErPwHtCwjj6nT*WREKI|x@OS>m&_(T6QXzlso#Jdt-CA9o4 zzRSVNjaP08ov?Wz*-5GI7DBW_lu1qW0JCt9!+$$s!G<0&EH?BgMQ#7t7c3mH5dD=sNBDSaLO~q*3R#V%h7sK?% zzK&%72sXXNrsiM4nPYyWQe%LZ+Cexd$vWZ7$)sDZW^I%PekdP1B@5a_&srkM6Mv$vx`>MA(sVloTN`_#940?rjYn^ac=V zo)5HW8He5}rNA_+dcgMfz3{Jdz?q-eE;aq!xO}qAgCb~WgD4Cr4(yV(vC3%1<>P+9 z^p#lV0D0_KF|RC7R`rD%PEb+wP)ldrfk_bz|Pq z;{LW7=}R?#=z8;;PeKyZYEqY^|6X~Ea__^jTKB57Qj{;nDsDUdnv&hJ1Y;2U*>;F> z`bC)!zszYG-eKUc@mctp2ou<}3g5&yk8KkY^cD@(c@ur%!4lBRc7 zGTo=AGkq(Ec)!P~#X&!!5}~rnGcAc&*qv)udD(f1z4QH<`PU>mI zIg5dIo3jAPs&|(aM3nq=`<&%6YxT==+zHVriBlc~a-<)K9`<4lrg4g8pF0mSmx$P_ z4y$cCN~5xiweuKW__*QaDgHvZ9wYOEw@KD@xI7?)<(AKuW$wHI@wg)dKA4lZ_l%x$ z2HYJmX`Ub9X{Rc!LwZ?E!;UgweX8-s8D#Cw2HFPbWvtmuodc^?liIL3rpe~#czd2X zM4ees?Jj*(oGfEWZGZ;weHsy3NNn-kH3qz<0_l}q{#+OVPm(x4Vg;4rcuR-gnV`r2`dSS4hpM0RWCIBU!?()Fq^-8-nl_3Zt# z^Oir70}fVt46Id%{ToiBv+(d^!#{b(1Nh0*Br&(D)8|$O=N+; zqMsSl6Flg+AuHi?RY~4UT8)b}V^r%MC-Op2t&ZI_eJq%}9eN8&0)>h#hgB+SV)gwlK5Ow|J-)Qg zg%PRk1l7<0F(Q)BvauU=zcAY#{hOBXE7B4U_5=!H?F-^bX*;v;c7$+_QwcHiUbwTF z#rh)@#+S=yjoUZH7IkNeGxNz0uwb_A&gF`$LA|0f zkZ&MkAo1`phs<^F4qgN=^SDmFP?QM3Za}3+-s-b5GuVpvOSw7+K=<5GD6Y=yoKC*z zp_M__&$YQJ6yZJ^YZa`Hljxd2Fn0a_!TeDq8z9noXGekZ@gj}P7u{ttebdM5X;g6)t4${sW}z5X>tH9F`fI~@`A21< z_H$)oyz#vA4l*q2rlxtC2?!APx)h%mcOIR|y5&adS*f8OF@3Hqf7>#OVwTNyxN;`{ zTb!C=Df?&Op)unsVvjW+&pj?T6*C5fn%qX)s~#;br<+1%bAYI_Nz~p$&qs$|pvh5= z;&O>SGTVD#5>E}*EKM9P+RC47*Tlb@+NbIp-n*!crRwE9%#}aG~3C8vuzhA75 zOJ>KOJLrI|00goKkUeEig^LH~lxf@PwLydB+d&=<_o@sHG6JYD3=w{>=L|~wFakes z;?#y{MyfM90IU>mqc>y6p074wkQNYym>}+Av?XoM?qlZDO*0W1qh`*a`5?vPTav;C z;}B)L)P?M3D+l|TI;vl**Um7SQoKHRKfd`^ zxHBr>i=qqQZm(j}+sUdRkLvlzXW|i1qLnn2f!B1z;r@#&jndAC=?iHxoBD;=Ph8-1 zpInhU+#{Uw4VtC;^ zUpiKqGN>sBFmYwV#0o56DlfW|yap$gpDZj#Q9kIwo6h$REbCc(lfdW9su}W&o%Z#2 zIro|n9=u7ow?P6wp0KMqFj-`SOQZFy(X{gneqW+*o6*}rqlXlVpxRkE5Mg>zMfnNg zir);$zT2BiN+f1wS2}x1TL7Tk-c~o0NS}5@xQbr?>Nxl*e(7ZFcaWO>ZiWV>*KDIM z`ryHX106TrYJ0TI4TkL?$65Hsu4xw$UC{dIuxMx_SO5F((&a_+&VA`>X%^Cukm{JE zytNlDvjKVyyAS%oB@zeji)+2AVy{JYsN&xmi}m`Z?+?U-K&13oXr_xN0-G6Ej!f#x zBsi8~r_^;TXY4i~reQ_}Nh_E;zocjjqee2Y?@rDh!5AozJL=eU z-j@3#Tu}KRhM>Am=zhe!Jm7Uv_KfGC&v@xE>JE=oD@A#B+YjZ-q0D?`ZkwZg{w$$p zcVj;pHya!_9|qZRmFs>XnwAd!C)qWzIedev)`(~hU3M%tV+XS{T=7jRDj0mQ9U66flyx=xHAgW6ZG5n zYj)Jve3)qEGaheBa#&ycChpizPEow%k^LT&2DRHx4c{uI^Znv7@>YcqE=Xz6 zIj-XIknqK(&*65wf!DaxjyUh{l9;m=ccTxsZ;$nu?m6xKHC$t3eWf}o{E~R9ET)$Q zoIo6CnL&_HQJnhVSfQXY5?#a0K;H!B6@{dt_w^i&sx$OXQ2RME>t0pEX)aNTYYR=q zA!B159+`QDmcKz_Y(2`#Bsyd1?h-Jo5HC+)M$siiqOxd) zdTUya4e(o(6gDQa7E{{)P?@ zAG#C&CB5C#YJntREgrrf+E;J2qWWzwDUi#ELqK7c>0Yj19e{^R|TKA&;3 z{yKRvlLUy!Xc4>T(_rrX$*0<7DkWH%%w)%q%&*66BC|H9m>@cNw7A4?h07D96057P z9TR50fzW_hjZS1--^x{idiKfwe0$v~0HKqHOzfMVa3uI9ZGAY#0&*2PYPI+%CLkt| zsU7yQLU#L506|4yqx*$`gVfL)aZ*wWLB!<+)%D684p#3ty-W`!b~P@UZ&nFyQ#I)w z5&}m|5xNNiWXj(fM%)mEdarxr3yi_*$2>B14K;IbRT^}hJ?Skgxsf6toZ97g5=pNn zri~HHi86>rVE|V~rN-co3}1ERpfpW`cGQuKXi7QudSu(N7|^SshUHIYqjaC=S@#(7h!-#O_FfW9P#vPa}@v~C={EaD*x$ONAqTN;^VNYJ1Mv9 zSVR)8k-8Ro0*?&bLjd9aNrX7Aw17WbX+1P<}L4EP~oVMuF7`+hwEd`06n? zGJp-y&}*M(J*88lDjm{=Vo5Cpj&GoR!XfQ=c&+fz^~H$d%&zgGKF2BL>IEvrL0ZsK z6(1QKhlVndkm*W&jg#J zPaO-m(WA}Gh#G^D!S+x_^ug_6W=RXzd3|{iseuEatB!i9!*w!)Z^Ahwnlxl7?h+hQ zwe3>Giji8)!6FZTaL{CkU#hubj2Ao50~r38@)?F(!J?Ntf#4nn%Y(!`1 zxLG`;wj#B)14$k)PJW_tt(4SdG6Q0Za5Gc;fTf96PjLF3ec}|$vG?4#)*X#Bi8oSk zuvgh5Iqy=D$~tXqCKWmm%}#X+5VcB-T@9(d1@dIy?9P+gfD3zJ6R$74Uj`kkPePeycKgt=(pjh+9iJ6t zG6g(2x8ikp@PyH?MvPCp;FLHGxgJ%_p!~$5N`BhYULtAS-(w@rfe0q0H|wnw#rtSMxGTpYloAv~Qb zXDpJA_=wdL#%fO>SP!U;%H}jgR;~Rw%wSFuVsa~g3-gV8B|WdL9g{o)ms1sZy1XBEj;^B{-5HyNA4oM=V6=HIj|X(j%7hra1H@ve4@N(dBtY&*{@NN92&==^4ql6;6bJqO z6YaQ&2p8vbv#bRmNrCatB!xO35Zs>LV0cYqSZEglQJinh*dB%`DJgXo&Cptu?#uZR zi}sV8B`^_zvtYd?2GErH{L)r^_s-ClekX}`{?i8u=hQaoX%J`#$eI{4v@hokag}?@!O;uP<%% ze)RJ4Klk$WPj5G7|9+wUK^1Z6hpjbY$@%n=-yi!t_cs0b$xQ#}{Ny$C^6X|uTT@4Mj)ZEZ-po7n@zE|9#`HJ(*h7L?ezVpm zyVonLyZy(|Ii*deC*90W8jP2Xk^IlNHzq>Z`srpj>)9dVYSPL|up9$mPEq@aqV%S3 znEx6kvKNMl2nGv_XN3K|sQzymME~p@&sJ(UVcOhXJ|6wICr%Z3eCgmjDR|=Z|Iw+? zf=;DAx*1?Y9f;pjVW2t!RfxG|j(Gb1URD-&)p_DEMz5lsEABRygU@ z+TUC${@9!U0^cjPcnPO0Sn=FnURq(mK@81HB?oCp? zpsnw$#_R8)fYVfjBK&3T_eV0%2dWq3=taK|lM{#odkFt>>IXZ>e~Zd|*sdw@qkg`1 zw!+>eja%9q?^=k}xdkv(ZdZvKEf}zWF<^c_WCImg=-K&K$X*_MLR!IviQ94Pl+$0? z8b2@ILjpTGq7uIdA4tf+ZvZlU^D*6@-y%00=JziFHgMynP{~t|PO{HMdSq?Rx%^kk z?O%udfB&$aZ&dP>x^L1rcM@XxCbE9=`0?{u6cIu6XDs(7Jz}_#F2(uB*?M8i|289fN&!>tf!HY(egHI9Y;+ECTN+XxOoRhHurH##zg=Gmp(>0j-g zVPSH6XzSZKOC+u9P^X38y*7^;_ikd|yyH0HD)xuW68+S(TM}UE8nlMnA07~P1{GB= za6V=i$v`*SL1>il=c}(j{UQUbX@brJt{gW6AO6RcGkv#F&WCnjDbY@u5u^#Ska#b& z3LSe=aF9G?)HT_}=q0T+9IL(tuG~A*jzB(kr7GR6bL0AD)yvKAhD+7Qh0!$oV)fvF zD9lLAa~-WupP_|Tr1~0UI21Jqmm9()#~9ya$f|(3Qhf{8XCN)!0Y(ra8C`hYj7Z?V ztGa;oEqJ14^#{E4XT{UqqMPDCMCuP5NI?@TZ55dr~+9Rlt7;SrY#jO1#q_3ler z=YnMH6O;`7qH9J%W@YXlEOod^x0pEkeM8y=^)h$3nPj(&pHDtnc($6cg1Bwvz>w^> zZ{bs;5Fqh1$(Mk2)C7T00f;0U{Kx#u$M*m2GWqjFx_3`*4>@{-69Nal|D&l2-i$NI z{nR8bWRJ>hF5}<+z<&4wwN0ofQhcqH2$v<$)@Q$3}W)N;X zIJo&)b3cs7<9hf?=)p({NEv5+0+C zXqnhcBq~7#HUmVsKtJ{Hz)uH5SR%5P?z+n6Z3N*JRsnBtK+LNq{a9T-KOm{s5}qy1 zgLU*u^O?nPMy<@;3l!zhA{fNc_d1k08|rOLl?1wdeudE4z)}+Ch?7CXk~T)B#|-ds z`S(jLenY(cf(`E^Zy_l}Z`dyGv-jwIWPcwIZl_XbEf^jO6Nim*4(Rj_o!ac=j7&L$ z^+k+)24VQiUq@cxha$LT2N71Z2>M6dQL{49=97CMOlURBCJiCIWx$Vprnvi5MA6;O zrH}S)&q6spdn^!r)#2+AkOFhf4-n1)N4jnMY$UI;|K?p~{diX=|M{-yO|M*>cGoYl zgZY+6jq(mXEhm5|LcDR?o-PDx)a{HL%98T={@Gv!UKZGK zD{vu|tEBC<8KJloc)4qo4V=lO^=V|Vm{Oekz$u)9JJ?6d2aq{y@e)o?=1ky&1uVl; z?*rnDYs;O1<+d?MR7^H?z49ZSRkS|`T)76@d{(m7P!6#UmvUBf{=lI`V@b_H5y`+ zlaHER6(f~5CCd&igZ%e#uJ%wdxrW)6;HHPli_wr2m>nZ07TdPJr6B+xxm{w@#Voh* z@{{8Ky|n-Qzrb)-9OuqNJ9xbnKY6vOVB&@{ zaj;Ise7YR&xU@{z|cF*Y&V@0b&pC0HCSnr4J6b!-cJK-beRY6m4p>k zX6q2*`X~oRopRUp%rae0q$Gh~3edrWQ=}^Llk2e0uZ`BnI+hBWH$uV!M9;B(6z&S< za4dOAQ&1293*Hmt>2G@qdvT6q%6^! zvPzzI`e}rj)*nbu#MW688zkb@@1kP$ImgUvpc4_#x4%AZH@OXoCq1KsHGTK=T+uFD zxACSz}zqw^=}K98Y2t+l_n24C3kr+ zK_K(F5zU>(Jltl*a7mTl2^%9mPXp!W_63~(x0O?nqyr(7epcF`%D}xQO}6vpRdTIO zUEIinVR5qWL^hbw!)mB0RHaN=_K>!`=DSZc++yM&-pQP3bd^qq@unUVEiaFPe%^?X?U_&l%Z6;GVx9fKwF&xf`6TB@HUH~5ac){j1 zkjUD?vWh^4OX^IHQhJ9Z)sCkqx1 z4-i?I`x(K8y|AqTE^LdnV_Z=Zpr43+ zhDA`PlNWVIr!(8VXaZtZZsIhM;oAG0`~VOyZw@Oy4uW8d^FHFXZLhbap>+3*Q^7<;#ZJKZ5z3j%?hg z;P^)8m7kZ_znx0-6kdJ>PN`m~MF;`chtUxmE&;UlBpI?Mbvk_7uxX9_G6Gjyco7Id z-MUqRABPs`nT_a~awok5VdbUjwS~JJTf3uni>_XY6S=bMbS#xa8n?8~B`N*(?FOlI zm1)K5??|BmQD>h_4X(q&IFJCs5sKptGsY#w=!s3s0NTHy9OqjI+K_Jf06M}8Fdcm$ zrL5R|XbXGA%4{*Lo`mI{c-!MNYQp3q9>YE7{mvQQCS8*4+F9NiW;Db1i0b1ebI#C;(WT7ERGA;d?CLMHZUKT&nq_{BxL)t3yl}4U!89%7^zP zML&vgZ!TE?6?Z-`=B{vAU1h9-6+`LfLZC5vk;p3Y{k5siTtDDs`*by>S&N%hyNxJr z43DwNZ-x-JD;#O7)Atm&%^z!8bb-NwgkaPqO@AZyt6!J-Q3>g^ru| za8K&+b&60+%JFkBq=|Bun!6ft9|14*g`ra~Q|o0;=@`4jj=e0IttnSqeC%$_!!%N_ z;C%MiX4RIvFQ7Tjct1ykgX>DOF7mYXtXAIeKFsPaY+|asO?x{nx7Fe{=NRn_D}Mt% z{WE*UXR^(u6(m0f9xQ+NC&8Y!VyB_HYsIDFs;yL&UgoldJ7RJ~^s3%P?v1J#pRDHB z;5SVAaK8UYY2I@2L`^3o(tNU3*XL;(56+cOY6>cmSwEdkr4zd$LSy5h2XSx!19erv z@y`yqMB{-+WbJe2o1~rm)_=lCSuXx{qYD~OZmj61A4D&bx3K)7vx7fL-5<+v=d3}$ z_C{dPS-bcORSM30QGpkxg@@`1wfSUTG*xGH6Mduy~|os25Z1{sC1<)r8-{qLhg1#RM#@$Sm#Z1BzdK!VIU8# zh>y?=nav#?Q?6o#5tsr;JV209o~Cn3lM)eH0L@alTW1l%eB(c}ER{iiZb_9g$-=fR zGljvxJUL^)jJBAb<5ATVEa8C^NGON}nL6O!!ZI zgKfyR<<_9{D<;owGcOv4w<7;+8xS;%M+*V61L?+0REO(tzf}D39U^8x@+@=SgZ=Q_ z;+5&J3h{H}woL8?`{9fE(ss^AY@Cmqt)$oLvA=G>+ukrjnTj%79ylr+DAYLIlWiiw zW;j=UJ0Ocl!!9Z`f#3rO*NTqW7gfn~Au>c;bICVEAT=RJ9;%TvwglQ`vA%Sw-SS8I zolz};uEaB<^jY!-H2i07PgrVo@-WHJ(Htsp5X^BA%!vx{ek$)tQ&)l6>&W`YeC-kA z93v&xit`5Tm044J@rOA|1Sd$L9{WO%XnyHcCaTC9zZY^&C-T!oF1S^Lkf}AqDRoG< zIcAIL3@mByKp~pFBNTDaPhUyH@U-r_~$1 z$WdvL0eP?}b&hpq;}qSQ-eke6(x7K4^@Nfd3c7bF3PP*8IgB4|+5QT#Xi1O$Ip5^3 zN?4AT0qFxWX>%?Q2#4$~(aBW%Bq)XoUr`VMD$s4yHsT(TZE;|)&8pX>RTC=~Bm2(A zC?kP3sE_)PP?wt2si$pb!HF8uvF|OwVvX+$hT(^FV#YGj?=F%A`JEBFQvz9~qr)pL zpbUnQmJ&W8cHD$HWnsJcjtk6}X$qlD7*bzO_kdV~)P#PF(%s#TItNh!7sM1WzbBfZa+Eq?ePiA#6W$!U5C_LSO@e9%{o&$5QTsrpe|_= zF8hx}T+P%}e=4VLjr5Q0hPQcZ+XE_b4lf4zx;0`7a$#q6c5`Zw^Jwq;Llu`;uheB|x_G;}(~;U{zhR<+xA*i$p%XL=^@m?uoq9?W{g@Xn@&1o}Kr zYCrY~Qao*nSX~A|aPk^M%|1}A=EOe;Qjg!Oov&{9wib$(mXL%c1NE1|kQ{edFZ&QI zbPE4P3&BFfiNNLaWvBgMMJc0XW?2VVCu~I8Ze&KDJ1Lrj9F}dVe70X%c52IY{DMd4`7R? zK4OrQ$kDI&X3qdenLfK-r*t0NKVI9&JLR-^j-a|vv39HMkA+~G_nbs9nLGOCyfmTQ z`vm8GAt)be-Lu^z#N05}9O^3VQHNnZi|e#6V0B0sTgeqjRa^=RGELq`7aheXxt;iK zzi%m(@Zh*=GDqW~X{R!;rC=te*Q*J#!_O95$5rz0*)5|6#><8rp+c&oVCs!=VQd2| zPjsC-hD3wsL983?Jgg?m((_UF7KBzxZl`F;$uhJ?(JlqkLE;9HPP%*hp{3xRlsy*k z1M*>V>Q~Jno%u@9t4)b@QP<&=v|=d23Oq|E22SXMb;b0lq{GO@J_);yI@)dfCIS)< zxcRFHT0tWsSS;1}aLS*zg0f0&K(=@wbDpeyH{eVvQQ7|@;hmB>jTGnYri&{qKMgMC zIZ5+_gxgpd1iWU9H?56JPhG`diLlZ7T9TlMqF43rUk})f%7yLeuR>7NLB_nBRR=2Y zLb!})gJ+j4VzHVU>Rg>FVbKViy{%XGe(2aPmJ&&*Y0L_RNlEHY&YbSHx4ajuZ1b|DBk0o^S2ZO8<1-QMp^0yIR4jA!-KdGq{i zJgO?S!Mhm(j zNRI!Mqz#EE(8D^gYm4dRDP(X2R{488--*}>e;VmW8D8jdu@`zR_P>#@(BFK@eR>e} z3vD@l7pkgQDt(a8IXk6tr{$WKipVj#_?WI$hy`&S^>ntvd^#ckA&J? z>{|Nmf0SEqgm*(&vw&Pmm=rGcnY?4j#nh{(Q9SQB`1MYm&5u-;pxG|!jn_hgai=?U zH5*^Nhp34D@Mz;b_+1ejGz^+HWBN2VL|gFko-@^#--NA0E3NTHu2j|;z;`hTKU?I~ zt#~vW1rgXaN83wjnHVylup*H8C(%~S{c zRjgmg&&X>_d$kO;5hYC#v|xvpcCXjOHmN*)I`RCW^-8B)RlKzhDadSoa2N>&kmXk` zs737w*!pR^sem5#W%Z$RxE{=y|F}RF?s-aeI@#}BvWk_;eO2=9mSIIdi1T3dO)q@C*7?mPLO^aL28HFW&DUL+QzXGVXXl za`TZ*$_(V{o}!AFZoR|lx)~any(d_!*rhzP5>UERtkc?^(ExY*BxEe*4w_Kk_d)G% zy@9FSV@GzW4B9;(FR>?kM<Zse*d zbtHR-LHdyp`wAYTEH>Xjq3muFVv1B?t-3tZTzzH`SMRyoP)u$0V^0q#fiI~W;cWj%E5iandb&@hsdzp(U#4_?L=(cvrL_jdW#%PR!&_A z6hd!Q;1=|7dICFCV-!imp`q-%+f4l-1p%(uj8czyIUH2jfvbkqX=*VNp$`S4@RI(i z>i){{n=h;q`-*e@;>eBbq+Ily0i_;T?2pJ&eq znzkBqmRvv;T$q(Ac ze8b!6kmW0BYgz8KU3-GH18ailoy?bK#n57L6CsqOAAbQ!l(J|X7$M&xZ{7(ix4xvk2sSIe!S1PJFQH<%5tY zXo;;so_kQYkZ9-tv`=1E){*YwESZ=T3_)Q*uhU2U5++O$%7Tk|)vW0?v2UeW?tDl2 zrx=%$&znb~4r8IfEP_ewi?wQl%j+`2>MWS`bwhQ33x=j|oUG4vLj*`9#10Y7;P_%$ z``#!hFyKoUe_Zb)@;8r&a`(wydtZo6nx`%5wR_!C@D%+`gQ)#OL#6*al7+z(VHq)TCmS9J zSi*_#mM^3{WX>QD(ZNr}y=F}%o~OUW={1*SzEo>Gg9EYcqf(=DX;BBOn`4+vv8nYi zZ(?LngL+{7kNAx}OO|M+A{>mCuR(b&i=OdNA(JZw)R~8kU(Shc` zf5V52vzFA`i}22v_|FkCP&It~&SLHpS_Ur#$~Gh?O2S}B#t09CDAuR5HK<9TOC+~9 zrVH;HPi1JwVAz-}E31QQJo;gToAVtQopYU$E6>3ZRgrVwc zj>N8IA5`KwcXVr??OSc9dpgvSxc>XNu@Di_uQ?ytN5s%6e1k=Uz9FrMX^x0p#UHOh z9O`>3KD-bioC8>7W9tL$^3ZPuDb%CuHJy1^8v1$cTN3`hTqeGfMyM#Nin7A=*e%l|#ORu|e+t_`W08c`cG=x)seEg+4@92}wYiSIZAlK_fT9iyL$?Ka$ zoTLX1i#CV}M*%w7v4YuP5p0`(Z~6og-1`}6Gnjs(K2^3Zavmd~HwyjGj&qbJWnOUe zPI;!yZ;h}&)XVa<-9J5G7_o-sggsvAt>E3gQ1rg}VyheWIHEK;Qz_+O>Vfym>-$fS&c zm*IO(91t;##rf%=@+)2vkSJN)y=OR|r{QO*4S-Y1X5yCVucQF9H*m?d!m>5R%KZ%% zz`O+WT+B;v)P=Sih1Noy!v(ZhkdsUbh93sirIpFXJmzxB8P-7jk1Mab6~;&m6y8S? zE8`Cy%GhMlXpGxoWC2TJW8>tWhc&TYGhT21zJMTICJ!LTrWb_U)(nk@`#^9m^mh5D zd&^=ExJ^*cSDoL6@68dcTu#-x6?75_k3`aB9p8bJ0F&f5TN=$1P9~-Debu=!0*9w( zUlhAoebcFttt+P{xY1Vxj@d95m<2o{O@C}Rzdoaz>LcvWAJ}19%we&bM_r({thHnwH`fov8sY`NGVF@PU)+UvZgOx~7AZ(5j3M>?m zp@@y+=O3I+FxaBmHzg%MBJ#hzzv#cqkwiD&svA!E?`inX{~sN#HTOzIaPb$MPFeg z&R<(9n)C*Va0Q%PB;hP>#b<)fv5~~|HJG=vbkK^Gr*|A5p`hNr^Sd9Y&*J>q***`SNp!j|&sfk#8aa?~`jd&VtZFrsZFg)$} zjHLdsU4My-=UCj;vPQkh2F78Z+{JZVGZAUaH9Nc4A>z>+e*~&`4xB=)APS4L5eQkc za%xbP{Wh4rLy`2@CKKkDhnc&=iqU^&M*q!pA~z4_29TmaLGX8_xn8dMt0V{gE}T}f zhxR`H?vw)B6+L-tC|EsE*F`xjwO|%*48TPnvvug-;FVbm9KclQ(ANd)e;g+}nQJW^ z?uaW$|G1@7)X(Ywb^rGYJ>%t>LgYjh?YpYg9-ac@arUx*hqlVcW7TV)1BTQ5>W1h|zlnK=|6Th^&vWn2cLMaXtgCqu zZd>k+VBD8yuDh};2HO)J*Y_#2zGrfU(!N;U4^= zjSS!6M6b<9&yX&G)X=dl_e#UV($RRH3;U0vb$iZ#5)})vt5|n%;@||6(ZB_NaXY1> z&gl#mI2H`X4OMeAt_W~Pi6^P&9wW@F-*?cQdCO;kesPQ1&Bgxie`qm!Bte@ucW&jW zf&%$kdfpob(>K0Rh7eIM>zhP=0e8mU62{Y@18W8#@GAVb7$EpKoDKHyu95|VeBC-% z&;UZfOli%^!m%|l10Gn}0N&3UQ6ZwmqJGsL2bTOOr0)H$kkbC7=C@480kP4{Sntv5 zH&0+I)=dYppK0eYmh44je+VpBuD?f)I%WNj9>D+mFXabVYo$5}Q5*^;x;m1vf()(^1|J#@+Vqz0Mp3+t|V1w#g1+vB}x;dl?dr@~IkjZjAG zoX~oLt3iFIZJH60K~8ecRba%`PsW4QZm_&!HdnAT2`Zb}7eR^)AuRer!f@n8={SOs zv~D~5=hNisN1mSFAqZ8}upsBq`Lc)P!21DnDct)6I#@+lU6#ZQ?x=0}rE*W$+%g(i z9Q48z&p_aj6^MOq`?0f(9dI5!H~-UIa~|kseu#o_3fRjR+!qasTQ?iEs>eDbqYWqC z(D)8QLa3_Jev%5(MVwytdc$ha191fdA}AIe?jS1Nb|8`3Bg?38T@%V1N zE9&y8hyu!l<*UJdAv0z%Qi!e2>5xDeVLwWKW9~D`x(ZV!`^oMhY?Uc`aQPzA+u6zm zGBg|Mf_CI^8xcv=a9fG0`AiU_@NuHsm+kYgYTE)>_vzhGn*oz_sGf}*8OyB_^vU+eS5A~YKl6j8qn+Ja6|o~)X?*0PDGTv9nyySDG@0Lj8|9Z!MD zTs0a1;!6*!1^CmB%Yn#e2H271+&oAgplz!0hD)vY#wP0iqF!ZLa`)C44hcth>J)Y! z3P_v>d{J|)axU)eDJ2RtcA#c0z^|unGGqE8XgJ304Ny+oH@iz_@ajEhb8ENas=hce zv5PuW7p`9!9MRkQAOmjgF#D`Upd+=#xKOr>0f$oMuTgHuz1)csZQD){5@o{dVVY5v z@OJ4(k-L`;-h|FSF5vZ3OrUoNE#)X#g&tcbv%aGG#u8nl5?OYeWMl)0iG7uV5r`H! zI!?WEz3^dOQlH0b7iqRI=E_k?VRNuJ(?W%``EAM^?^krp|TxVVg@o^ zb1IAIXlB`XJo}QRJ0L-Q(@1@ISIjbZ_8TxS--i=CQ;u<9`boL8^ZLwxC56DE%06pZ%amqQRPcQaX#kxJQ zkgzxjV?F$E>pc^=kAt2dU(7`&0!8!06rUmIl8;wZl}&hHy{iH!zTGOhYG(54l*d45 zxEv~Af#iZIq=4@(CXz^WGv@>MlhplUZ>{z5Uq}zop{WRpCp&dGc|m(!-YFj_#F>D* zbhtf8(Dm>l*{Y~=ojj$^itS+8(XrX$y(qfVvvL-+x?wl{7J8$uHG{WV6_sV!CwL=$ zI95R$>xlGudonMj#>-eT$d7hHrELkAxK{%IhjD*LW0mkQw4RGsSI{9{6`@lh+i6_#woOe5^m+y zS3@F(Aj@!3;7D{6X49!gIUM)oJ3G)Yxa70j?XI7|XnlYn)Ks>2*K@d6{7xPsOXxgT z3ntCue2`|*u}H7cYVQEcZY_^QLv`wAh9Ci!T|(cZ=lej&XgPBr&op>4ev4RUI`k^B zflq?WEt4z-bDDuQNsL>LH8_tE(KTNUEfi*zRZtxT9zF4!Sq``G#5*B|QkudP27N3b zET30-02NlfGAzhCbiTD)Tb4za21moV`)sajGix0ZMdOyOn_dk$10TUu{LnrLEuXdb z8C0XO|560l4dXx`h{4UjFG3)1K?vaNHSAke+(&Sm6QuL$!++L-QSAM?q-Hw>oS{1N z{YjF1tZ&CgR=^fgQbsv8S&>-|nR|-bVQ_fA`eipTQ1k!|JMqx3GvhMsg7Em`>ib1# zjMvmz@g47;%^8{pvZ`-OmqTJp*tVqFUQ2Q4E1E4NoF`EoXL!YbXWWUQN8sjz3+-Re zE}fNnUm+9cAl4eyq(sqSxF>Md5X6Nyz2>1Ch~t%AJ*zFGJ_oytP;cN@``BP367S9E`-1>({r)Wbw z5^<@!I_@XgqF5vJ8u>GAd9|48Z6CgcYDr04Ks)s&2vh66tC{H8jdsq-eWFG6EZoM3 z=BEnoo_zO5{0Vp1HjWPsn3Po{P$FThm*<@D+Y*;LNy!8XQwlL00#E-QT?IFyZx;c3v zG6J0xIr@H1h(t_Y&Qt4cvoPENy;x`IkU@M181NAtmnM^sSw<(3M2czXB$jrMeocst z9knj%RG>KB3i6j%-!Mrf8W$pyBmgt3O=&dz3Ch2>i3(c#V=(LEbAVqKQcgTzIif9F zfSb%zD<=mrmJ4isCc{hl_YWx8@t;l3juOHCyV;ilX|J*FXuFX^>nIj8)?~v_ zV}nr%NkT+qv>_1RR(f*V8z_0ltxtERWGMU*?;;Y1X}Qy+NS(31_aus>vLWywWutAN zRvgMkd()PwgKU&P$>0GeAi49`A2+Q^$t^r1LuLOU1MJM(h>Cn?!Y(;qmTLO=}5!YA9y`_!ML zVa~;Zc6ZKH<+;a{ez7UDDVCsrfZ2VtcMGE{eWvka!Tngx0N@1lK~TJJ%138uv#3iv zd3R@Z?m7I@@8(Q@0VEhq!jZqIQ2vJ|;o>{9`kSH=;aFPtGfP}kc1tYp3++{4rOgg6 z0t)>`n%G;2kJxjfR(g#4Ck)`vFI6kQi-(f{nfkjW32ZJcZ^ra~?IwO0G({1=0`SD~ z!j3x!9l+Kz0}h_>M0sElv!PwV)a%Qxe@(+5%84~zhQ_!LHqqXX5C1Y|{;e%Wy1skH zKUU4bpI6QQ(1hK8prQ{#g8GnI<4ANZ)Li0o7m#tp0M+KH#R}5oT>Xt13;8RaDSv+f zO*em*0sT*3z@BMOsDr;#5HPs$h>%bNtVe5bB)M*&usZ2`68C5P^l5*5DfbluAENeY zhW@|&#s7!d!y#q2fU<1=1as2r-`wYaP|@ssEaepmLj31E<*KXpTTIiF9!vaiF{Dh; z|J}tr{J(H917$me5(-}*4`F1361wpk&~@*Z8eV?;#pd`Y0`YX$S1=P?gK=h3R0d2s zo~A#H&3O&4B7fAl{N$gE&C2Tk3u7~bsSl-GGQ4&IjZF6xb12J=<=0N#(VSSU@NZ`2 zJA89+@As{J8!`!|#lmy>Zgj2?djBWT{k=1yHM^$4`m25U`}0$ckpsCN5R*mz%eK49 zLf^EVZF2m#y?x+d%8ia78d*aKd(m};IzgwlPUFw&p6A$Kp66`}QyctkauB6=bU~7} z>o+~zkJ@AUP+&?;>^3Dzx!vLO58cu2-lu4jDLMSX~?ouFB&>4_E&Eu^)VXrD3;8-j}O*0DBUTdd-4&OR78B>(4NJJxFs< z@Hl;H&+kuGxfE4~oBN#$uYYsx^Iwt90+L**?OyP|ecUj74V1&v-4`Dr0pB|bx`&)u z2@S7a{&=!lCGg7_x)Z$qNhSWb=?Y6jUNK~(7Yumf?SSSHj(nZS{Hv|;`_s^}qUp*p zvj=SDHjF3{>KF%7q~p=;;6EMa&NSec%8?-cRD}HXAn93D0zs(*b49iTHWA(l>Z((_ z+%$fzHNU?HxoB2Mor!fAD0>4+1$KfP2*Cc=pNm8M+H-+IRIY3Y(IW?-?vWi{t9uk;pnVTw0rJ?;mITmtCXkWIqZ(vPQC+Da0#ty3-ddMJ_L zdNB$Uv4e*zJiCkK=fknW!;Qo{{387P`#=cI!rq1yZCKDB%F61uWDyO)q&GIp%36EH z_qJKJ(D}tYNLW$uxU^MSUc+|K|Gu%PccmKxTmv*(rJ|o|^%}K%*C}xfJQGS!L0b@W zwTx@|2m9?iy1X9UF_J9<>J3?+`-3=l`X=O!?E^@1WEqltP{hEudWFSvQ&bF7ygjSx zv}s*R2__LV2cEEA36ed;JYPS#!w~uV8r_N`{yO?0*NVtW@jxrtM2hd>mQjWC$U@ z0Uy>$g5W#r;9rzX|NQG4#&yQ6WddKJnI7Ig(lS7$iXilF)Her*?yj1#yy;BuGk;*U z>5KVWtA}mpB>r~0D2gCd+l zzSSzN0QJP0ZD#?;OUtLi1yq36gXcjs242x8k5D` zu?&sz@%K$W@UCN#zfJ{7lX);hI5@HqEC`H21G-W3U9qm~L_Z~$ArNygAV7Y+oy{ql z=*tnk*j@0{abQtWKLO%*t^!*80=%~02c9&%3`bWwaIKpPcl?ge7qM=hEb<+eclbq} z`uAxI&`>C>c~M5jr542}0Iq_RL`T5Z(69_C3oxYc;WQ|J8^9WJ5FlD_Z3c&C=s3aj z??Q)zHeIvxtZ6@(Woic{ad}Z8mhy?Oz@09Kk!0q{f^E56MpWQPm;|jJW>1EjAk^-9 ztvTUI7NF1bgGO~zI<(P-A{{VZF9#-6M>E*mO+SRMfV*w#xv&$VV|Ehaf6~EA;jdA3 z_bk-+GeiEU_YP8~q@N?*xKIM+`tTrU_b+M(IK-cA$@)w2P}N&7*x{PaB+&5A{fjaZ`<7nyb3UKT$P#6 zUPX>qtH!1Be{a1tI6GWu{{iN1eQqgm3mwPA!!U-~5rCKh;Hg^lPwZZRnUNX*>D!!j zcz?Ak4$Y#43u6fXY;46UrV!rnR~N6-KV?Q+8R79|eBtrI*|*I(BGDdsZVuKPCzjiq zf)OY`Y}{uW!q+NU5O>4cWUN|FL=8!pQ&8T?1=bf&^@QY#4?uY%NC}VGwH`=aI+hCm1R1Y+$oX;T8{~fi4Sh0@oT$?xG_|0X z4BTe0%XFUmCYjmua~D)-l^dONl^uoW}G1VZ@uT-SGmDq4`es@g6}V3h9M$ zgEF`L$R*h9W|=UfNUDmw`0fTRE(uh#o+Sc^Tl5b1UJWSTXpV(rXaKFPwL4dMOApvX zq{3;QU2^<%>rLv$b_gpMIQl>#Qi>r?IaYDp%t{c#zFM>=kAph%l32lx^AH9^WggLlhbrC(l#N0q%<{&d?O_{OD;+T z8H?nEOgPBn!l6(;wCnMG+Zz&24q}i%u`nGCKm7-I>{e1aMJwi55i7@upA@m4zrNm3pwioaA+$yPhc(V(T5Aw&KpIYH=mp6f!Ery_r@9!_I8F>ptQ@R8G60uSqZek#9 z@lXpumgpHkN6n({ZOl$Zsd%Tk;@Oj9_IuVt+L~6({&#EE3uZ4fG%jLt=m)SySXs8D zWFWyZRjtR4^w>h+RvL^azR*vO@L^2ShLN|tyU|>~;SwHPJmV8WbnBK_Fbb0E&}?Q z(fsUGCR{O+wY{$167T4nU?~i;r+^d1C*|x9E%d6{e=Cl?1t&=li@9GZ~>fIpDfKEsE-AB&R@bJMae=ZPwFVBk<0XI#5550IV6JaoIl{Rk7 zN_LE|APQf^N@_b#cao^Wn1pNAV6|ml@RLoM`}Z~_Vx5M--k9q=v$4Q$xf(u(aMc|j z^sp}Yb+!CFHblR{0fCz%v0YtienbmURaza%Vc}cq?f}BsftJOE%!YBuI!XbukkGpi z;9S&IyiGmENJ_g%^3q}VHOgM+aE7Bs+gN2E+wCu_GpBS;g`JtC@76Fs!ZAl zuVw2?i#ux$r{q*tlFYc(qBTwrZ1pq0t`VL~ywLS+ytf+F8Ft(N_<7Qv#pG+dW+M7$ zLJkbmsHyiqIV6(;%8Uc}n9@QKT#5oY2u`vYrrdYL+K4{Y`x!uYz{Ka+_8VYNO$UkV zG%qk*Q_>v*Z-)`{uY3BPuffqn>O`d%?JFR=a!~j=fxF9g?`0XD_<%7kRy}Aa4y-s1 zQw{-R6PzTpLO%%H?eSt5nT0nAW&xR;-W6lpvPN%=jaCYUw`#{n9epf(W})&5bh}!j zHG5fZfIvZW-BE%Fwy`&tCBUz*h+O8&A;U0KgE&+u4;wu)n9YuWQ^6Nq7SOS_Nk)D zOz;v1xR0@}RP50^!d5R?*lO*zv=08_g1f81=qiR}@bOuj8z)u>W^r$ENs0##xr|ZC zVrLI;50#Q84uto~Xe&jAqIf%R2f!wJw5M_)>bW0hiKt!kh+yA0l5_T+5ku)ep< z<~HwQvF8x61*!Q66cW21lZoQ@K5$C2WXQ1zCYHW5(!qYeR){r^9jyQh?8p5D3O#3s zW23O*Io!Z5y#%w1RG^lS-7C^$U-?31qey3c(uL(b3A?^bWh$2H3UVe-RXE54In_5R zFJp?W2C}vbU*NUiF>e+$1}~K-l~e)j_3D9 zD)VAwZI1{!PTGX*7}RJx@8q2yg>}V}h_QkGLk`2q!p4xH5zKav80Dcu+;#4^ipjMD z4uFH^Z#h!kdbt##q#KQj&n|AzK~Y`A2E>ES8hy>@hl>n83SaubHpkA_ zFWh_`CLSfFGjhbgByx$#xE{gTjIxVJn7`co3f%e|zkYrxDJj0T*^cNJX>^7^Lscvg z<;@l>E;usP1^^>`5PxLT~A^jK=phL z4*d)$wFD{q8o?WfYv3gV(!c&?(`FhYC4%)v0p46k!?AkU>^DYOO~9F6ClvIAdzt_V zI+?dTSu;^--9;RU9;=kZmSf~yIP(Qq=*CbVntMB)6{!O~oaSa3*Bv_!-wZDk#Kv@z z0rTn~qINIsh_b-j=ySU#(a$IW-ztDMCYyC}_TAnrKym_U^~ofyhQj-~`20RSV$=j= zsdTA^u*o5z;hX6Gm{rw)cWLTYn@5IrfN6I>Bioy(qZ;x`-wh#~9WE)MsQ~Zhb5s6P z`7c>ofhD&q|AKcnKbJcVS$WGkIIRBSB{4k~>$gA@ z0%H%Z^Re%=ONyYBXolYXIHy(1BW%d$-`+C|vUPqR^bPxK@wxmbT`izJ$5JL*uPyz~ zmsr#}PSb+oU9=kJ6jqvJ@Xz|nuroh`iT8Qz;;0KzKW{OpgyvyXb=Lgxa5uILh^a?g5~s9d ze4Y`lBU6F5>tTPyifqYYaUG%nzrbnA@O>+{pjwWNA=3g1BBsu~Xw&uyApEI7b}a`n zIVWM|&$9benjEpmi93VEy@>SD!(2}OAgE}05e)h#DJ>$eq!OyXJ4ZR_+^=1;#;+qioQb8;i>HZp5uyT>At&PP;uz{ z5~}*TGJo#j!M8c~!)9!e`#ESwM8yIDL8RBE ztK%M|BQp=?oE~RU@7CIx4edMIX|N3rO zEMZUH*GN9NLTP^!a_84+x{u{pC@)>`1N5l2A8=>L8r8Yten8pwycotkv<8`~p%A6H zpa6C`NYXM_iIU!d=LD2l@pNtf{bCHrwqwd)2vBex3ePUCzTFcw@`UNBLvN(N^lC01 zOp&tF#Y-D8*7TM4&4}2SeMgOe?)!)>k0CC$URp&(<)c#xK`Z40ZX;MvY7gmSWuE__ zU=wF+pwD%`rF>e7ObQQ@W(Kf_kt0hP8vY)cMr-%4dBiJBS~ib1?l}IJg#hPA^H!;S zBuFWGJBW7`a0&giXn^gHB|ND|IVDMN3Y! zDo+sXAlz=>-EH?QPP04ze8?@}roY2kLI|c(&DSIfHly}JNQ{utJR@;XV zF@1t4V=TARPs5}#R17K2>WW;c;gdcgO-B=a*+aIV&d$JnfAIU<<2?WuQq2$W|JlR; zt5m;z5!(4I(pt%-!BmkfVE?}5g(tvD!X59^2?$jt45;37VzEir8@eVkT^1J}t$GC> zf$=ad&*s$uT!D7~;Ur67pa)W2G{V{#YEsPM<^ z_oR!r@w<0i=Ha&J#K>JXWlFozQyFFlqU&z#2#qPTP2mj3k3e+<4u<-xgBu31IFkJw z#uR!wm%pCkD`D+8r7)1_a|Gb7IANHC?u(-*(z6S6$dSuegq^h!h{@NATgN^sncC!iTvCKK%M(M^@Dq5cw3N z4%YrCmiGF?)Q4QjF1X~fxR2rUws7Q)xI-sQjC-I23?U`oAmpbCm&O2lSI@VvC7!0> zl~X>Uj!CAEPzVBTe4N`8;woC z39F{tM4Q1`2`@qqB=)uf(u9g^nQKE`zHwiqYZsq=B7Eu z4{vh+IBG;BMh??CEhx)){=T8=;MHVpTP{?7n~iuN%g1nM%xUMP+D7p(l(NhxcEjBf zfRa?2Tfqw~6UheXZ5H0dfQwuTR60-Yp;RtOa z0_xS|EijZ7TCSNSwVERx*!KQo_gfm zMJG6N)A2dUg+6J7T{Sik92~^hai?>j6x~l@nVDal?%w-Dm?RtKi|S+Z$KzvAv>@9T zC0z+l72A|6bP#=gkeQ(5Q%3t7)w*`CH}Z85`hgwx5zvNyKQIpH`?lOjKpllfhKpcf8slI#WoD#=q$@5LTBMI02LM;-CMtl%M{AT>E(!k)hV; zbrXSMPde1R4FKH-JY%}>Djvx+CJ@UPBx8Y8s{q-tBO86itOnvv2Qj0^7Apnf24TXp zI5y2t(Z^IOSc_hf#GNYIVhP|MpT+VHdPz;(3)R&J-Lp{j&^!gacRu&>syZ9NA~=)F{WG9{9200%QB^gho3aWp7wOL+$qAP$yy=P zsMx9+V7d1;w?4kel?H~&!mj@6=?*^)vt+SbYqCcIidEpy%%wf+Fx-ptQ7Yk0piGs3 zZ+AXBq!nOM7E+4z>kMKMR7UfPRcj9nCrEe&uGh^mI0dq8 zq0mt9Hd57A73G*+QkArPhO@;KB`s;xr08G#kxm(BEu<33F{&*5rse0dz6O5noy>D%}(#+f_B0<@6pxHh6KWFZG^I1Jr8@N(alf z2-RU1@K>z^FS16X(;NegO-LnjKB*JVs!ULD!k%o;#>+^y9dXxjqq=xnJE{GC9s&rk zCTw%Zp}0d_Uu%=75vAG5L9JG)C_p*wr*Ph0H{`&;Ptl!+d)Fzm#;o&2?;0l1-2{ty zNHzUIkuU3$!a^`e0^KR!n429|saO3w$1yhg*pUeKE|5cNA}D1@yNVZ3jm!&A4oMJ& z3G^Pt(ns1EB2taewbi&Di-ih++S3G}9T>0oBDAamMhH zyo7+0h+~K;Zi`Y6JO9ZjA7Vi@G8>*8Ogy*U;l$s3@#VtP=M}uQUQTkqY*+Uc=i43Qmr8;^O{AUWOw z`I9H{7=IYONU+zOH6Iqjm-dBwa#@js>GvzOiu$HY`Ev~x%K+$W-yJzvak_h#(q_=4 zi0fk2r#0d&0$rGKC5q`#MAT-LU@yn;`;#h=1!)@}ca}n~ohd+Zr1z&1yXcOvnM4{B zz-CVaa6=hicbL9@73caqn+3P8Y0=HqW|jZ}4#Fjn1VW%1D4uW1?mLY6TBCg7JcT1C zcE+3iSuFVAf0`#Bi&1}6$aAf-$bE3`L*6^=S2myMsLE$Ubx4n@96Jc5*)g16LxEFn zCPcy9J3F^FM=sy7ykX`Jvzf&dZdpshm|K`bM;|)Qhs!~uh{pX*cw$79t`9pW&@%T+ zc18gdin|IL1(?W?2PG+ZirS@Dh_u@;2=aaVc&rUuku8{&%+ej8=(%i{PW(I{-ENGO z9x77>?3KPp)Q(e(X>(e^l`{E&_o@9UK?u-yk|fa5U#scT;mdQJt9}__{{64=2!CRjzF4|`X;Jy` z!?6;Z`XD_T_`^Zs3_#uTOuw%|A|3%wrm}9RBv}u6-cbo8+bI^@a9}D>EQOLLD-<|+ zk6Q0!;J<&MmF$?9K^|r9JMvbkR%SqB5k>0~aX@p+xU+gK*tszAf2-v<)rO-U^~22L zbO%R2a6hE+b;|&vr3dXp4DPUJvvwG(yRLE*M@$LPBNa`Q99Xq&kMF)EuFJr#T$+xk zu`QT0RtfjiLycpkgv4Ynv12Th^*LhT+Iz3OaR8YfYofwXz#DJ2v-%a!OSolb;nwE}m)dg`LQ(&39! za>O9b+6|&P^e52kur5 z_>Rg{=piR4b;!9~-0L{CnpMJK(Qs($xrc}Mqz6Fv=VUGq z9GYazy*zw*cw_Fpn04#6d$7EDNomK9v<#my2xw}s%XPF*9q4w*&w3$Tk$2Tj&!B5o zkhC@kF3@`=^l91fnVf1BDhs{~lbMBe5H~w;DE97i7~^~r5oj9$FtuYcy8Ro|#Jz|; zNjC9)pW}Exz#QKQq45ooZk*_1Da*y5?*na_Mc9eNyN46vL&;!*-}Rig?#h#=nbF!0 zu7ozf2fyR3o7{Tlf?+IZ2Q^_yqo245wy9UOhT|c=Cg@qQ9t!G2@{=IV&Qxf`EN^Kq zxPwcIngC2O=br4p!^Ev^k|T^_AuP;Qu;XksQSFN7CG#0#^PpTIU1eEZ!m4;=K%V1L6PbC3zuLPCNY_%CymjVg$C~;bmL?k?~GMBVb=#kndJCW1Duww`Y zr>FwVDryAJL=%{gO#;|`-BWpb7etLCPmoDi+IK5bGkplPRl{Bcr#M*!Iwz>F3ulGC zO?Bavl{=_{fmD+4sY_8?Wr94V+M+g56*>H%FeX|ok+mpU?_D4P>xmnm$CnPk$SMtn zU1yJkuZk_c2lvcF)4XqQw~TFHf`$Lhv!QKjnP!Vzd zo#ff`a@J}_lj8kASdZ_p65jS|;Yt^a7Hzy^VY+rtzNq!^n!eqfGRBpmEaL^&s3E`Z zWIk(c(xn4@+LQ?y`$dSr@zoPrTC}{PaDb#cDl%j!p1+X4*EH?(xu`uRU)>eHlBFBu zubsI>JHc2Dsigg&w#qAMmz@$nrrrwi70Gb4a}T9_Gx!K_h&%JiLNJLZz4Nc%q+SxI z!CyUb8I?*}Mu+T+l{JhAfV15NF zNVZc*lH13~fT5mnxtI5K!h&(P$+xaCwK1x~#f4njF18IZE!z^~9Zz3Nm=#IAFaErF zl)nPY#C0$xDhD4e}F4%x_K4 zWm*~@i^y5)910*bdvfFyu6gZbxVz^&Q}(PaVM~!Co9L86o=fsWpV*bYcxT${!%+?) zgbJyR8W8iB^iPIK#;-W;gi~HhU2& z6nsP%72>p?5t-+(BW(&if36Q>^j%p1l1)>5c@%2)O-*Y}_h2=6i24k6D-dtjb@<=h z8KaY75%lKPwqkP)S5&$6XPLOvD9)WnF6Df!IcjYf7?4b7b3=H}IVyP=UpE~RI24d>0d-Ebh&Ll>I$l(y18lE_^hl)>DNAopEJU5n+jR4NiL1O z{Br55?})m|lm)(cc~C19)b1s)Dpk8|C=bG42IKI*EPOX`yq|**hXz1inUj@~JOZlw zb@?`xyqEb8tn~71Y2Y@=o6W74HEnj$rljIx!O?(g{Ai)2?WSA$zgF>oQ>9Y=l2^~E zl9K9DYkyk;ktue}Z;7$9klB@DGg|kPMa1j|_ru1vBT;r67K*@zb^?_`lQ7oYoFV1) zF!Im$3X7|#JQcpPvlGH~+~kYmb_;17Jf-t-CAzfH8BrlED03^|n$v@9NwtQ95L2a) zvhU|Ay2lC*uToOZbeh8|+Ak*dN`U!z=v@xFzsf6sDp?N)p(e*_roYR5x>*sp%+Qdqx2T+~#_YLmM)Jm&Yo&7kdE=W*{RP9-KcR(K|TXL{Tns*?a(%2+6Colm;NKF zeQr~7bcKdQgpBLo z_QSXB)bZe^*On~om-S)%OCMAdDN3RtMZu};G-F}_RFlMuT$5h^{;L1|18qK-WKg~{ zNO1Zp@K?;J@z8cAgZy0G($Z3SEX#jUK1slm^6uDz)dbJ|hG{~&J#KXg*?|=Rx zLi6$(o#$<%fV;+Kb*|{`I!(;LZTa0xORi6m1y6+s+wwRtT7QkjV*4I@I;})dTz7W8 zvWg1q@x}G-FL=EIm2zJ;N|Ln9Cx6HImcG6S_RUXcOW*fhY-JDFJhrquOAokeuGa)a zvLVMNOutGn=j3VSKku2+EvwU|`GH^4-K!a~YFdHMAWrM^XE&`BqNe~gNzre?0_z%L%a|Li4}Fi}IpSTt$j zw;S-W$PNrX4RAq!_0eJ?7z;6V%6ji*TZ{G~}OX);g+ecn$IKC(|F-Lt+<1a4Br=iJ@Mh9PpW<($|kO z0nZiGfpQ!^9HT@>g|{uM__V@B<9ZvqwXLH^m)EA-A=u&^*~kM4OG^tB%1JT32;qMp zE&nP&M76R1x}^9;oZ+LKu`!}W7_{@v^S<4QeI(#3H2LKhdcBE~V*1!O?qh<0$JL*+p+`>a10e z*Pv0{CSPfU>@HF8DBMK@z@tt953Q(-;}?Hh@SV-1j zNMs!kYk|bZn6XmwE{l(7Xj)p0l$2DwW&78nlRgry?620xg{k#5#fOJCsw9%q07gQb zS>tPRv8EYt`>4Rc0QD&Jf3feE?$FBxSII#{deTpK}{B$d=C8DP_altdEMD_|7HEs>+XmXC4t{Su-_52%TSoRtIL?~ zeztacnlNwC_~!-T<3eS$-MFpTy*5VSj4=>QbXP&aJ`@`hAD>iJ~p2b3hK?Zx)cq*u=WhbcPjC_54Rg{&lKs&zPiFbqIgq9Y1MQlJC zN$%xeZ}r*Qt*czaAm0NKXPsD8vIkKH6xzPldr`~~n*TbepZjo*iRWl0cX zTn#`0nVNfB7}`=TB1Fi7E3Pf+nR6mSs58$4A1*=v1F^d;!wq_ z#7TV8$EY=)k9?ev9b~{n&*#^?EjO&IzezAnu<#+T*3-4qRU5QebF`Jwj7Iq7VvkyV z#Dym&bKk#lU5{o_3=wu}v=~oWFb>V3n2u-6b@OV^r+-2boiH{vvvqgSn+T2xX26p) zd;RVg@XpU#(!QB~Qf^#2yyvR@(A>Km-geFkn_s_wUK_v#m}ho$eP6l|z7)||own$F zffeeYygnmzq>4Jftc*M)aT9v6th@RB+FL8Z4QBgDZTs>O{Ogq>TBP|B7giWnVf(s& zXDV^nZ6gM=F+M4&(p?Z%^7gULxzO!!MKqmAzVd!QQ&n73zKXdywm$9J7J&`8e9i8=QvyrNc-046bto9O| z8+mPqGGN+ZHdKQsxa=Q{-P|~WOfv$sY(7ia0WDQU4Glk10cDOV8}C^U?=Kx}AGt1% zf}MpKXqN+mCZRPsVYYj}3f2o5KV<+rQ&Ns}oD_Ul+1{lNbQ@ZmOGP+qM}Q`2s9~D! z8}!4!*5~m#MD;cx2~BC{f^W?MKguzbKfz_e zaO}WIt47Orbzlmsi{0kX32v1sFYM~yd%fk?2|NaVCd@De(l{qZ>Je>5LmoiZ)=kJ} z6?3-Fe|82ewSc{w^GSbgLxynNnAUVd%Yp$I^`>e#!EuFV2(x^hcV?%C&7q{Vef^nY zK%`W{O!gA+uF@OMMNujNcilFXJB(XE(4+`V+bGo`d@R@#U!~2VQ+u;B)O{!9oFBfd4WD_ba?i`iBId+ z;_`Z@8MCS^IS$+P#YPiohE80A*>yU7hE&ao=fyW5bOm>6m!Dy49~{A%4Q9EV#Rmx; zU`=A}dc>S?h?0=G(MhE{_bZ(ynm_>ccgq&RYJ2InbBR|3EFuS0rgnmN*^7!&YNo#+z5bCuq!G01t5(rZ@p$e z0sBG^T=guzUk77FbD$%UpjYD;ENAX%&X>G4PhH%GH79W0=rV2vEfy&S96XPGrEdbF z_#`OAPG1f@cYHnRJ2gJ%9E!Z7=v5+y0C+MSpZJ6lu^dX!DBlbDg!_2Zdf{M-s}^}T z-o`O25XL!i{+S`P+Lo+I1Hcgh zp8*)J18m6<`bq0{;1#CBcBq~>7un(sPCG1(de6lbn=_8D*F-jq%4>%+CG*2#*QUdP zi=wSitTKsy<*j64p#lhL`d)76sKIhK3P!RaO z$5p`^*GKX_X5sP5Ge0I%s;hHE=Gy4A)2DycO|cB4I%59ds-JH)8xeamKQX1R*mmCI zln-)^1Jw5muqFrDArB#z#OlWya-$gJEP7z<6*QPu{mCr&Ess_t)IWfWUZqg`^{K0? z_eBBEt^&D_-LdYKOZm|!4T4*e#oaW(S+kSw+u!KR?*bn$`(a;dwp4eONl9E z=U^0yXhsQC?%j~o!urDIag)ngwNRxduLHjDp+u0z8zm^RH~p zQWQmgB{mJG`(j@Ha5yVG6BydB@+uT1`IPS!zLAAMc(YS*beXogxDdy*?r+j$yYd~5 z`8#}kOUIt{bwPzzA{QwP^kKC%O3$R?gHwtbt}gGZKE%jm)ENZ1cRP)~zZP^{U+TIb0rp1*9fmX`Dd#N^T#f=-05`Or zMXVRiYh9k)1r`)nDp4rrJYysez4E;R$D0E3yv!8AXn@E4%aMXH9t*J3z8G}M@^aQ% zPM3RzP{;CAJ$cR)D8+b0X=D(tNBi#cloA-)7k6KzMvgIqDId7Z)S=w&Uw^TXJAj4+ z708%{+_e^`OwyFlqU^+M8r*id7eL{XZ>V_?y&snG=$sY?Zi|C*7AZ|Yd!UYzYn)BuJ}Ugs_{iE{OWO!25&uDA*3n#mqtoZp8rxs1_`l!id3-1@5OhR( zT2M*zIozE@d?8?N6o<#>G$))4gU&8YUNm{P<(o%gMW2~b%bnQ>y!tjmrqzKk5inSq zTO=&RcEew>y+bipwpA+M5zYroDD4kuz}N_6CEEb_@7lx%fH?SSKw`|TIG@8c%DdxC z){ttHY7hmjZyd-eSw%3`(&~IG>Ah8onp3Qm|Fgg%6pBma`48CQWK$6xy7+ zL71M;$M!M8xc`SG<8vA|3%F8PlzJ{mygGz=9{vF$28W$BPR^sU1#BTt4nle<5-wX_ zssu&rZI_U_*&2H=JgPN&EPS;*u=CD|Y_t49{8a8&Fzc4mO1W|$D&KPO4K+k`qXFps zHefU)pAp2Bb~AK+1b@zI<9py{-SzvamJFcu8{v;X4>8x9h^+n(Joj5ozlzFmea*Sn zKG^EX0Istpgt%>eeK*7q5>it^_Znw5jl3&CzteLE832RrZ)pD(<0mrwbwJY(vI!E? z2<3O>Afs7mD&ihB8)>`DdyTXKii@;?n}o)FMyz@_T{&Tq4npTT2vE}6YybwAlaPOT z+uPV4&x7Gb=DGKb41QeoiVuzYn#%f*vGL!4d%8DApzZdy{e7KYhhrj}-_3QxZp%bA zoiZNHB$wde zwkF6i8YzA3fXp2zj$$liw`b)H<@8_HK4TRd`@j1ZrSfsT`imgP!lxHVR}7%;#P<*E(Fy&X(|+`swZn2 z>h{}zVxVF_a%4k@pR^kX+$=E1WyXf=?wgEmeL#i7zKiMEIRlLQGZguUBhK@#aU*ZG zQ-hEwWf1PbE!KVf77PkIT1qzw4CsQE$nv_BO{v6XO5g! z+Aigqr0gML;afHeX3}9?6O555U}m2ksvAEs;TSm*>Ot@}0+8h`oLdDPa1KCaJPC_ENeJ~Wi8`oZUbuom2iRrF5uAfk_^OS}B;oIpK z&(0&G11RXQm~=)7X-a8j*jiP9+Mxn)Uk~qt-?sjZAD5N^a-|WO@4b%lJre+$p%+ED z0wuJX2s>Cqr%iEu+N}UI6pG_RzTmQ}8H6mwbypxL+{_<4cDUwcc=JnSL(eydq@kd8 zZ@V+WssS%z&C50P-aDWMLv-}ZvP4%7Er0B*>5KBzKdKKH-%GX;&)wBW3I*n4mv0M! zfSqd`$@UQiS-gcT(8S+Y5(^Db+e9jlkCB}AG<}v7RNZi}r6{g4@#M^~*jI~)0u#G3 zt7Qf1kN}M862E;fTpaF`$FuJML#Cg(#BTYn|9QjwpVn!<4kL=cls(oH*!Lt{Xv`TEG)iMm|%Wcn5DB73y19D+}^%Nop5Yh3vDwL|KOJ( zF0_xwx>6R&=T=R zP%l#doP)2?;ub9*fpRXq$d_JiXU=l?bCK}vYOP2u_4OzW##-*fGjW<lV96kSX$X>51;sTdNba1iq zRt%}{D{6^lX@89k+kBoKUL4yN+GQxx2Uw1nUK4qyUvZ}8UF>RuG2*wFfHv|AWPChU zk;~V3VOv{A;tK+Q&PL9bLYGDP(rd%_Y{@|%L9jXy73&`d$eYMz=SoS%jhet1*iX+Z zPz46pr$MI?%fQH3AF^PR2RTTNr07JL@zomynKBAD$_ek-jSZJc1|Bm?uHPCQJR}PB zB|M;64AM9=vtpvbrQ7}SqG0^A@?x#4Tk2&MO~A&EZdPEt|Y z6K9-teC0h4!T{`;hbFL#?b~NwYJWl~2Onuq0R3TwFXs-z1wTgLta$TWCtToZF7y35 zW?yEXRKO^sw7rZYar{){RoGDr^TRF;NL=0*ezOtcMh&1QRLJtqG01B!8=oH`9Q*K> z1<#G|7N8-1*C_nMRa!s=dO~JAw<6X78t6>3IUv$vgP^pFn$-fXc~x@10N}^;R`Cf% zzM@3Oja#y;{I~qS>pX^?mG4sNdSA~HIfka@C32JpVZf+>g2-L{_tCjuOO>wTOu z<%ujm+hsqJx%*q?ns&uP=lT6zjtBYz`a#$;an2MBizmS_>h`<*5uZN$w>z%hjz-of zwXjo0vewk(Rsk=(>7;2YbZ%S5^0&CV@it%Asl21fo`#U}r>ld*x|!IQE=CiN&>{)8O_3B99+p^_8Z=gKec%eu7~Odmo#W z5UJNOra9w~v?@g}gepAeP7U)5e9ainHnBmvfFqd-udS6=p$wqgopAx?xSpMTm0`Dn ze0zB!Hb+rzJtIU{J1Eyd4`d3Mv*qg<@7+))nLYd6k6brwc8iGG!#%GG=+qO_Y&z9t z8JDX?6m6-wf|n}{7n$8eO=(EY(}X>P{7NvD|@_i>EZB4L?h)-t5k!o@ur_*cZ|W-06qFtpB-&c0LyAq1tSJ zR_-VfWJn0Gq;A z6#n?|k(bj*tDOetCs}u6xNEoJcm;~Z;O|6UDvVorO{V ztU@t&cXu3v0qX^k8&{@4pWa%}WJ_Og=JK62zl`%jzd1lu*bhLp?LW>gQ17&q(7dY|S zO`L|p@|YtI5N>acs|$0}Tf*+baQzE_pgXXiHlzThphPf=MNXPAEAYfsQa%uOqnfS3 zSK=P~-O7I?y#^@rLm{TnVpz59mN5ZLxBrq9hLy`cYxb5D>>>T@*jI zp?L$8b#r?j@`d_5BQ%ZrBY*&z0xd>7dkuX1^!{wA6Xa@DG`F$>`0)jz zPR+}w1v+53b2r6=X(A$G&&wJ;U*}toeIaPM1ZmnSw1Kr_Qd2`sXTr+Q z4DMb0F8OBIl@P30q0FBA$vwbgUEWV4{jE5coPKOE&pe@hjJ5Q9XC`6>Z{?~&bI3GN}RkD6JXd$S#k+qy4A zOx@QZm^G_^ci7tN^wmE&D3j4S_$(ph|L2b;*vEP8A=M6hg&n-eC^243e|F1+Nlmy! z9E*w<|8H~!1nTj^mk4$>!Z&wt9ymgFZzxfq&2TL1Of4f-D)~xuwO*KsK7MuQAV;;6L*{@@0ne?zvixh!eMU_>KB0ul|>Q+a20# z2|~^I7mzK+=jFvm*+2O_>FKc(ECXbY*RSFDGw({&4yl;lJxW+!JeQGFA=k`&0ZMM?Mq0|f^D!kfDX@@g8tU3w`d*Git3igJK zmhmKo+RyV|li!?U=GmC8L7jW)$rvu!M>K;PZ>YSlm;K-PIxrnSAhywQ7&E%l zs`u`5d3mlRZ0!PKU__EB`ShXwG_{K#LQZ^mv=XH>mNwov%Sh`bZl{W#iqUT6{O$0) zG!Su-VQo@Oc}DeV7kW}J^)V+#9t5uT)|0s_p)FPDcv-VEZh3_?t?w{uMW|cGKa>_h z`ZObD`+EaBemk6&+Qd?7*OU|-^7k3ZuY-++>5BmxZ=a3)jz7O^Q5JEyziHMkv%fdn zxN2_DQ`&J4iDh{YqSGgw(7kNp5MF5`aKpgRvT zuSCgCLFQ5Y5hj~|K7^4X3xx_#@F}#?N8Ive4^L0y$9GIuS~ct5Y&p!yng00kRxmd^ zb#$ZNmMjnJlxHg(8tZ68;R#pCQsI^nlp2f`n*|z18S&U6g4v;?bR$as1{YTNhIC(V zm8Vui{;WWkgjM;PU*yyh{q5)2^SAZ384sVRxzk|zMQ%nPm~PP~4my)Gkh!mY^!U#Q zHhi59tVhkYq3Tz@EsjseY&ruU{_%KkLE^exTDSIotiJ=wAL(|DuQ8;Bz~!7fm3}IDcv<3m41Vrz z(Mp;n_UqR@wS304g4b@>{5qjq-g>3Rt}vnx+*xh}*z$k%IOPE+DCjLgmne2%<>%3+ zed^~|-{}yi(kMPP(6Cn zf3fI5r;!940f-*h=yvYB(=tr9{C1Xidmf`I1j~WjVMz|O?*G*%RY%KZ3On(pf|K#u z|MA=V7ZqRQzgiG5vTQ=+HpKe-pLY@BM_$J;)gBB`LYLl+Wx<{Psy#(P_5G|ZX8wa&9~QfHcD!{ z2yb8MWO6&S`8Lq=rTcvSNSZ+=`?`J}NTSZb{49Go_EBM_>zIcP{p~>i9o>*>`p*OX z$FEpUxUw`#%G%LDDX{+7-XCkmRd6euIFhVEXI5%mjn1>Iql0`}a^-vd)a4_1`Mg@* z6^t})7JE@jCLvL;@ed;KR2;B3+WD|qyE{5;WI}QMxhouz6#FQf8?#LPx0MR@5$cfFRcvmGkAu>uY9cj~nDY{*=L$~|89i^N| z%$JMp-ysIP^Q|h*p#E1;Q|t9JtciI9`m4V*wF{$Xv~Zs@(jT6UjF11w&dz?BOA+Y2 zGm^iRkFIa1#Ihbf&$?rpb?ib%2%VBht`NQ%1LxvH#%%CE8_jg*;_m2+( z0iOzA0j3sf3ksBvPGPixOE}xUcd=*F*(twwUd&fP5>hr#{o(b2XW+hQ3Ru=qDZ}v> zV9p2&!qhQ(<8 zxhMcrU2e|6%kb*&aMR$C1f;ACpSYWT+oN% zhygI4T7eOf29urRf@&KJfQi=B_Dz)qtR!#}4ZZW@xhd3mejcpy#@+mBWoqikW_+-o3^BjGU69ow{)UETGw`0n zsqu&#>jX)j#~zM?3px)bCGYVOi%z;+quuUe(K0~>VBkH%tI%1!H){qsn1&$4Gz)+U zVm(ZE1^}>3g{8@o*Q|E+g}%DC+i&lo9|MP~gOllHI;iyri+_r;Mv=9TcCg*1de$Uh zsOJI@`dSHg*i{(+Hob2DOpW}~9ebjB^Bt!$z*plWVM{J(lM+DqUp9Vy+v7o{e!!5* z(uR=*+9By@x{xK33<%H{7=#%Zg^j_Md3de&SaZQit%MHZ#9K&tYycSa8Zu$&hqKEs zqnx+l%f7q29*=~DXD9$G9-!msUa@e5za3D&WwWh%ZVb>q6^Cntq3mvT7<4H$hv$Jz z*cySrvs1v}Q3VXK@f+f0WW3%a@CDd8A)}MW)keUsC;9Q?$7y_)MXT3>5Mcf*sSs?C ze)z-zxvfp#uF+Dm0U*iZ_Sg+aG%`MF>E#rR4m+RNNfrPh$)fgI^Vt;!<~zuSbKA*4JbA_ zGME^FSgg2Ylm@ zs67DNd4S7uo4uD7K$wD25q3XbyENv(yC^|1!`{0HxPyk#P2Iz{z~``4r|Cpv8zS_wJ@X`(o1XgFVdh!W%euwf6LstT3>ZK(7~ zcry;nF>)bRV(h6L%xYT{_^{-y?qx7P9V&&-R?c?*L@R7QM<@X{(j+*%Jkp7cYIUQ) zrk>d)&KFnqV?+QRuzcX5)k|_yrjZ(Zf31YJDr&}eW6@VDl+*aGfSJ>|O-VT>+ZlFO z-k+sA39|p^Fb)Wjf@dP(@%#d(SL}2$a4Pj6?f$cCc`|I3_zm9xRp=FSwnE_;8;q4M+VZETZl8C5uwdqo=(q=E<5u!q zlJ|SEn*5@EA!|Ed`}4+29n=K5T1~{jn~-}fxAtn{f!w<@5v}v^HD6I`*5U1>YI;l#5`@Bx$1a* z@VM}65!;Tlot`}~w2+y%UN3A;8=FiK!)T0_@P~40!}BeLc!tV|cbRD@J5y-*xb#2a}Hho`RL(?3WGTgd(MV0Zg-h8h0L8TQkL z4VWAOTAD9ku_^L03{Y=rHZLyn|Jkyo^kOQ8bTpd|Ft+1t=}f@ihcn+ib_d*-J41kAVB0H zMrm3j87FgL*WWK3m6D)Z_Wbju_XGa4hFh-ob`X={J6{}eU@&Px3k7_2B~{t(RqC8T zB#Fq`R4TE?qT#9B`SEy**F%OP#41vX|SMhtN48IDEUK`jQ52F|=S8NJ$vPTl#V=7~ZW{SAN8<&%yqh>_8=jMu>^wK!?{Zi;f0$KdbT!bmL~me;vQihO$Uk>82Qrcll89A z???*vKWURENC>}Cm_vYbyHs0-Qz>eHo`Ag!Q3KfzABfR#lt(tFQK^_9BxMuftxmLG zr$4nOdnFMeagKbfw%cjDx^ics+Y(vs&D?PQh~1x!!F@-MwMnCPW;QlwckooCFtLH% zS8%%68QZjMFm|p3Zk7Y^Bjl^Zm_LuWCEg>!0dcsm1}t7G zv!`rum67X*pE1^gP~&(uC;$fC%;+x9eGxowY;|pzd9H|wwZsOv(%&%UWo~VPx~}#3 zU$fqWN2mXTxBPWK-k8$v7`)=e4MeXK#n$$M|JO1b> zcu}6DoKwSndgOY;92RqXWOOh`KH%?Rue7WwQOACSLktl?>hZ?HhtX9;(}TjdVx%#4!Z^F` z4P}zd=9u+-{L(s*3@R6?NVDLMH_Rllk%<`QugIDZ>qwS2G8iDggVQM~eMQfrfG2XnQtr5|LP?Dh4<^3sHGfBzY5 z$*e%GONuuMg~>cA!HB;8xO2Y|@HNqaU#Cif;x@iH*Yo`=3E?n;O*8^Nc1!xppIP`s z80>e3n?L7#N`yp%Z=evx=gCb9WSS_#T1c?(HuyJ-WNOP%o%ji$d5{&zodM?QjhtdG z$2hh|yzr-6!yu|C@ZDJHAFQ5Nzb`Gc-eF(9LJ`+6sXbnzR-cG{B}M;MYu?ElTBe); zImesWli#7}I`a)-TNxbQeGlTTr2iqMsG-M%gU~8&hoo zMNe6QgfUa=ftMfPILKd8d+dpp{^~w4i+Ekt+dKoOsd1^)*=Jd(b zPd9z!%G(lDqcJ6F_%|4};C!3gZjhMJcbciK_5RA3x<+Tf!W>k;USJe6^$jD|hd_XF z_PpHg2b4Yu3RX;eL*l!=Ae=)}@t8+-ate!t-Lq4&B8FW%{|?DYP5+*(Be&~dKNxRp zU`$y^ovnFe67fOU!VR#y|3(yqKk%s^W6Nptd_mD0lZY&C1Ua-$uie`Q!-`SpwB5Jv zpkh)UM!6bS`_k8DGb|_dy=bclqr_$uGYRiZ-WkwV+W>qRqp8cN)9GUv9Cl)cNmxP{ zcs$dmg)@^@Zu1b1A0@GuR$j7kRSX$#yQ=o+Qz?D=bafIr*UngG38jKXyBfdRx-dZ6|mhODhp-M)cBa@)52o zsrSV%P(h4HYa>%c?__sds1P45b z`b&|-hA5JfUKoYQ7!}zmEM2h_*2cHXQm0Gx-X1oD*?TsgkgP!W6hj z{#@5DsGSv|rF99tS2Ll``{JZ>YdsSWgf0}>`m~2USWgeoLVG^B`|ipdHUHsag8C5l zNS3OOYsO;}WzaBtJH21^MN4vDPGO>hCVw8(fGMK-!>t?pH3WwOMuY^!+Gc@wO6V{b z&Mi`OWo-egio`ri-2U$nai?5^!_8$eU32BD;SmcY$dxgv6g<&SqLwRt&rTzZCl(fG zVeU24ayJtd+N<0K+fT9pHT-6*xQDv{)~Xb1DkC7~$%O3oYlv`-M0rQjr1daTa_Fv! zI7_2&V1*DWLMhhV49U|EwwcdR;=QP=HInP58>^#|q%kBJ1z|{u*861E93#aev7E8* zoJ7wZ_m(J4m-3Hbj**49)DyLCC7Dj*q0{*5yVSqFSb6Dc$dZ1(d@n<--ZA)q?l_2|QR8h#g}R{RXi! z2*6{=?uK%!=E>NR({?eEj60DaZGwG|v)9-Rxk#DB{y{^T{sogOWez0V`iygWgJZ_G zlW|y8;KSmdEFKkbN}-DfbT%hkZ9@flp5Jsr-~mHlVWk?DD_2!H3m2i$5AfUcS#%Z^ z>)is4K6eE#c1Bv@dKC}$sFZ+{C;Ihgz3j})VQpV{phNU8p~0e{vb1?=59jLv{ekwY z?GrFb(KUs!sZK=LFm~{Q^)xXSD7Sr9RcTnumIb0S1Wa6=Ul>--{oG^+bh*%3C84ao z+D3#WR7l17_X}NS7n+7rOJEW$v$o;ZZv7s}E_wRpuNBRI9`3G$--r{`f3lV$Iyc=T z9GuOy^cGrMBy>EOzp-+8xuS@ALK-GZHVN%g|^d1`wJ1+5K1kR_RN(0 z6#-JDRx{B&ca(eM!n${Gn8b2=sla&r6x{?{agIFA=T+!Pe)Xk+nAke={m-$%1t}2+(a4HTZhRKUjb`Yl2&jPlaq6TAm&*hK_=4 zaJ8{SMe}rX;zEwOJo-)J|47fX1#>K22W;Rqq2Hy;;4q7kn0D7RfNtvSWysYiBN4tT z;X2H631ps9VD5daH-;fg#H?z!XwEKljkf)nEWTdIC!veww zvebO2=hS8Ug$w)efxm3b+j)m-!aTB9u|w-OvL{&IraBh3Yg1Ald!7{DAh?}>ZT(x& zL0PPwa8nfM9i!Pp(+cIhA}&L;VdWS|bCBVu&#Fb+f?A<3km!jtUtivVnA8(Pn~$BA z04Fpi)j40u`E8HbS~z*G&>GULEuMPDF}LYG7diHy85O&SS=>E~b_>v<*(jA?iRVcD z&1*qO_LwXE*NH?4F{feSFG+0q1(>q$QzTh*UV1TyuiA|slt;#uRDb_%9>(e)c!fVD zVVdv;{>&voovq&UGl*B>${Kl60d0^Gh}Sg-k#y>bK*cPna0)5IkBgCdBqc5>(*PdJ zLSw3WDmGn|yPeekVhtt=M??!IzEQq98$6-RMaV&5_0q$_MqBfs&6gAS{;AzIoMJn1 zHEd2VVLWToUJ_P{*>vRbx=XgI!i*=7KZOR>0Dm1!)uE}&XIvxfO zvv&!ZI5lvez6hid{c9p@upFXj(0$6VJnvIvQ<#(ZUKh?bd?|&17iWY)`SucX#}427 zPKZ&25ya3rT-rG9J5VQy?wCem>$U|q6G_$j5&s-AU;HkkbAKN)frP}v{fkt1=V+CT zPQ8;&NUm{tX7=ZHO`i>fwhl7bpZB)!a~-5XmmL*#FdF-jaDU&vDeWsS0llp)#4yDz zm2Yj=`M`*N*;x1-nC}6qjlicj03x8ceY0P94+QD(bz(b1v3#?;GRwyM(lGb9czNgK zNcUw6aT(tWE65G2(2&}}CS*Ylexu?m6WFYDnK#HShFyTg_bVgjR5Xsj5f|;M#vCl$IDFaW-cL@~U%ZhmV zAO8vY)WCYIsWcypeB>D0hk5l6kSmwOgzxYy%B9_C6r3F7S!ULtcd}vB+FFG$#mn%z z0#y$z*Bwt-`QZ~bFjrU3Z=zVdF-28*tLChf^5ju&+%h-?1(zVY0O+XrK~ky4S6O1u zMBnS6N?nvW_YNnJ32KcGDx$~FLOv3*Nc5g8?EEH{xBd;>;wkHCBiwB`r|YiG=n_P4 zPQCY|L1Rdm>~=jd9toTP4De@z;?hy5z06iEYyFzrZmq8vp=g2SBQY{V7K@kkeIJwN zt!z_PYwX%T3Ga@}i?*+t6CLf2N@rt6b%_*Dw2s%6!&)kS;=*Ur?!BV$;?pv8Wzo0M zU|Hf25n5f!#7g`L8MJnQ<2vM1^xR>Wggqci0p;ua6zp7GvZkn0c=k{;QI`fgZ!{m2 z!{Sr!c0+Az;)naYYN)dvpFdfq{bbY5KHpM^Ga+YE(W$LK;KxA5%^2r0K& zI2-V1tAyDN^uIlaK9$D3vKdPBa5JGEmzf(0f50}IomE&7&c@Z}(nJVM{P-}I%ytJs zt#hc=0JAoLn!wUyw@nC=VzO7#)uI1xl4?RyEj8*p^`f9jMTL{CSNkOj0V4uj47dXp zjEuvBnPk7rN>=PZ8GL|#7A633MrcdYgo3!Rwo*gCO*U8O5GbXFRcOT9TJS+^1Yo9j z4t6Nm@;VI@FAlQKfwY|Vsh;&_-+h~;M9-ht_i;lwMf!WH@@;#3>NwEctzYT+<`Hp8R~RLpp#&W}3iu@2hP zSnjKx`ehxOz#)`5bb-zg=?MoTFzpBPFkCI?Ge)@sZP4A(>mc6bICH`x}rk|;rzO^4W2yKH^URmM`*IC9xnL1gzhCULN}RAt;lrj0moe-#wCqzQERuKk9oG$TGMomET#L zkU%XHB|kRdmxqmD_hX8Zpny)O`E9;f-1wyh9*y7VV8&J?kNQ(UrmLh*(`*?|u5kXR z1tho*VphP;vkDm$Yk7BnZOp=G01x8ZzA|CFK{gII{Tsak z5iJ58AZw*|{Civ5n&mc~@wfvWf1Fccw*dD3)MS--iH1Vv%*Y}6Cl@=34}9U?=>c&K zvbEGG)pxR~A9hW}fHFWWR|niRZhypj`5M)S+LCCOe3x4ZfiD~^LRS?yoT#iYAO z-3NSiv!A}~B;-mbl4tlav~RE(a`dg#6C!HOv}ehet_wsmFfnoJ7knB?Ig~ZSlN9*b z#=do;{U^wE3Xz7bLHk6*@z+6};`$)T7SI|SM&+h++#;?X$mNP^13C7i?(X;et1L}I zPHq6>MYCbO%^`Gdu-}C>c+orVCv)pENZTA^W+V<3?mR|R5$lw71qEn1Q*%x2rr_R+ zhur%ou6QY73_k$5gX*e+({C1)t&0ZhB;cAR$#SG+IYcRoGvOn|s%TWKRq`J)dHt*OzA zLt@4w-6~%Jl}>BiC+}0*^C7oZj>UU^e@xN427ziMw2rX88{nNW%pA6TW$$dOcrgho zilV~Jv6l}%gS@sgIQ zY-nBj?a?|d8x#b{rzt&%4pb;)JGX4 z82)kUcCc0jC1 zJlC#?2+qW_ltm})U^=-`brK70br$Jn*oOmiLb$*i?R(1GGzV;8sxNxRF5mOYGVW;3 z5Xj1okV$r&or<_dVo>N5z=bG*LyjggdsT0V>n5?KftviWgXsb+FiR0%8B+|pR;Pjs z(_HBJfrhChk_Jd8-}y!mx?1yb-~tm{AEUA%))hrFDF8He|RCrVQK++ z^9g;nXf1&UT!surs{&qD7?=e>4(CjtnbbM=sXaKNvnN}WueURx*vQ9%8DiybLda+V zq^O=O`!#k>JKr`7Za1>1bZu1U9yf%+S^b&$Cfc%J^x;Q~35JUvT5Yuo%8_&&P8?~_ zOO-r*@eP{FNT)FB%r+gHY1t240nV<+IWRL=d7T^MHcpCY^Avs8T;)Y&e!|$P;vmX! z#LJgebj?OefP4u1jb$DusKoGPnhkOv#kG8wI!8a_n&PFRjO-72aD+M>ug8;}6 z@pGKLqh0+@FR&xc3vL2xHP{vf&R3OQGj%}eA~$A_AZO=+tsgumPDeu%l5%i|QUPBB z9-8XjnnU=z%WS+`hK2bN|NnO@U3n1=9R*5_xAVo?KFxsN$GCX1OBU|a_cp87L2*-v z)4an)LLeT2I#M6@Yqn`bFn0#?18`W3tecekKm%*2+E}gx^6>}_c1K7>er+JT(lW*O zPZRf3G~Y?`p@uxvJj7jkfXB@@;*Xt^$$ciP*3@kAPc*b6yOworm#@6rw+;vXZN5g1 z`>IpQ9|Lpgzh4!|ebWJ}EQaW^4#bh?>-`xbj%m-TryID&oS&a6FBCt6zH@hxv{*@` zWxcy(dH{XE%MT9{;)mFlOQ&xJM(;Hom#m^nA#3iOI1E0GMVej*Rn0wrIQQzJh*m4w zP`0=Wk4anIiifDGK&(=)fFTLloqfZadzwAjN)=gzhPwxxyax3Tw14c-mCe@YxyqF5 z)~-8o>!!Zg2WH1|c=v6VhW8PVC8=h<*TKwS-cNrjhrN-iRbjj+Sz-*BM(Z)?5>+OZp1;_RPV zk6r@Vx{=I9@-tHZ_C}a0#+aMcZg8)gAnxv+R?jGm8KOKJ#QnJ#l#)Hb#rzd14+~)T zKhc2l<#~{@Vg*#|R5@ESWD{MjDalA>evux@wn3Dmp6dfYe%+X?aBG`8)-dlSeyUKX zH_R{tiRN2zQF6FqNKv(o5Yp{Z*kUEz;`zmDQ!zk>EYNt)&yyT4FTFh@cS6d zJ3|+8ft1$n)(uXzW8H%@gnfqQL!Mx}F`ToN^<_@@n5|SRFqx=MAN5eiBv?#F8{Xu2 z;d1Q3&|{{OmPMrxXV5QNi25|jTJyc&fh25Fv4zQ9Bg~=4A!{nHXfVJ?_}JP?#964t zvTG8VV;&|zXh@Vh#!`BF{eSV$fDR8gq(bZuSCb!z=l_fA@fFgomh2`z)W8lO@v5O! zHekVW<>P5-m0w@{z_43wN*j>f1VvXT)4G@3l*B<$9J1-VM~|P>22=L6nXsCN$0-jy zUT)t$4#uHYHe08MBRi=-@Jm>j|H6xH z9srI4x3;6cjsr|~QO8krIcFufJdkT+KKhu7C|sM!oWuwVYQDb? z&ih3x?Sb{#;_|fyB;sS^G?L3?6kOF;1rV7euJf$XF6V_H>6oZv$gCb8-hn-Us2L_nsqkJ_W(2lVTQt2O|VQ|u|qM8-A!UX2hz+?;G3Vt zxEZ0LWL^}NeBu52wufrSQMk~E=SeG3kddSTj*c6aQxX-)=`F&cz7LKb+5ePF&Hohc zAj4cv&YnZ4AXJp9lFXU2P49_MeXzlM z6VfcjzG&XqXqvmGqobv>6ia^R-82rhFgR9g(H#y&0@WrM%wbHrBv5MBa$bdQnUe~M zCAC|g?@UxrR~#-G3KeV+8y3jOyt#3{-NJKYZL!o+){miqzn$P_t5c3rsOGWZ)bx&| z$bUFRw*;EI;5Q`UYcH2~GnCjsA48j4#XO%0kb6eS@j}UoyIO65$yeT=D!-pwHXD?& zb|aU(kHLv;$G#+g|V>?w;E{wvJ?+~&4FxDNt< z)!J`JcjsSNA>}*#zlN@MwqG>{hY(Ug;h&;)D+N~X(>9%teAwl_jcUhv^!>^a{1Wqv zJmuRjAaucKDeX%GPS9t0BS2dRa#O8@YKIKDP8D3ZfA~4{C4Z^`@loP$8gk@ zx&apbwP)+D)sF^~n0BvT5H`PYo9Rn-dB_`Uki>3dfd@Z`Mk7VU?`=RukUt|?(20uV z(Id@ZW0LRk;?&eO{zS$Dv}DgVt6)s??!vzGP{gV23cF)36tf{pz4!57SZD@&OKuNI z5&tSFW-iHAnv+|M3F2yZ&pm z7nGf+Jd`I^uKEiT5^9f@E4n<3uD<^E;;-QHA>9e;%~0N)lFIVyUHQ_tm-8O!T;O&J zCtIGq;FNN-pzN6jI{vEhAuoRa^~F#H^Du{&Au45$6EUp!o0Qb zR656;oSFRHQC^c}8sj}VY!TH1q)$>!+nL;Z{ylB2YV%522E~o6`lH&-Kh>hGYmI*- zuY_m|ZGV}CP%cFle|EQmJL_4|w~-bF&uV~1GhCDra&0@4EKBVu;?lVtYb_tp*4CHm zE?ziE#xl5S+*43t-isJtP@?)I;Q^oW#3DNyN|3Bxtwi?Y!4wVm;3Pxa0PI z3a6GI9tovl(AH|sGDE%o#6z}hUR0NztiWv1n!0|dWVX1U_d&YejI)ai^)~A7t7149 z820Q)WW9uu-Cq*KS>^s`{LBZQeS1V*NBV0>P4I}tw%t9Z;xu_QE;{ABvZIP7S)d*996>FGqy^k_WTF!#;Wb^g}%>YN18e zhlK)ut#W8J1#Cq1%>s*_`S3v7S*ztig|g>$mS4nmzHZaGvf(}WZstFh=YO?Fs_$t0 zzpBMiDzwCGoFFBN-wr4Bc-yI&pw5moy@1uX&n8@;!Z_Op^=(ma4h3M|;N6E;W;EzF zl{9x8Y@ES{I5I5j0d zK?tl2p7B)hYaiZ%=HdjC@SaA-9G;BySOdR;+V_kBTXxYgYqrRfL>dmKNJQz%HsxCw z^4dQZxfm`H^K)(N2v}*n^A2^*damfzv=Cv%sx!Zq%;S_Y9TTTPl^NeqsbX2Z;dgm5 zZH>Apb5c3H1uPc&x9&P-f?3iMtj& z5G5p(lU-bFONwb|Cf4x57OXuN=CryL`(wa0HA>7_Crg(icJtxhOKH0DILAdP{xd8k zP(?Wn?^$#jl@h+b@^}GfNUY}am3!q@J6dmsJ|-nj_IDcahgF0(rko2E#fN)15K{%6 zQVs}+yN>M_i`^y&!I^svn0j;z2Bs=nvA#z}5T6nt>Rc@Ft_fwG1lqzL;-bLSozL3# z0cvzNXSK!uUv0l>P4qmd^8%h>gB>F)V#)@u^u!Xr>O#t!j`A*;zwRsrzUcD%w`A zebb>SX;b+H{nx_=x#U;Ih@UOWKP3rCs?Sp9?YM*-^c|QZ_L690!W6QmF#W(wlij9* z_{+ZP;keENoL%Rf=-V|hdp`FXPZrrsOf)A27W0s8dB|P9Cg>a39L;&V^vQw(*~O$Q zuU+^0Zc+8wg0eUA91J-B@eElW8A*oX6bB=pOB+S|O~Um5$orV%u7-=$+s$?w&59Qm zhgffX_zY)ntIsa>UCgaSE}`+`KN?mH#f)EM3gxuZ;YYBZG}8uX=vx1QSJk(ER{chFo$9U+?37ostg} z=YUEb2bzt|{ruD6ZC9*7u|%^Y=lh;K)<2-iS&&{8rsTtNn=eL)dwusKRQzjiiWfy@ z*>7c}Atp$!FU#O;LW0Q`_^k#OTF;&Z)UzQyjRzc&7k!5Gp;F1Kut zyu0^c_GLI#O$A?BGu$XIw4nByM;h6I=}BUk?O|TG)4W^81;Fb`Rri`gFLnDN$6GfX z`!&%_eKV`Mk9X#ria)=0QKmo8N;bA1TzF9SL3cit(f!_2P6dp9;{E$^DK&g}x3s+1 znVmT;R86GAC`{pgt?|}E86gNE@jm7fq~{#hzuk7d%qrt|DuC`FpH0ozpOPp^E<3HH zPZ54i2hkYWJ1U(yBByDp5veeM(u!jjpeeBi&BSf{+rTOya+hdDJkJ#4ufKG?N9V&~ zQdk^);V{qZ$j=&;!8DXOqfL- z7zh(eP?2^D`41vSE(9jNDwH8&%c-rad!$Fllrd!6IAeoI%0Aaz5ZG5Yu>Bw|V*0&C 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 Z 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