From 9baf3fd3833c79936605247eb7d3fa115234f1c2 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:31:25 -0400 Subject: [PATCH 01/16] Create README.md --- submissions/sapphire/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 submissions/sapphire/README.md diff --git a/submissions/sapphire/README.md b/submissions/sapphire/README.md new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/submissions/sapphire/README.md @@ -0,0 +1 @@ + From d90b7bf413928d9c69f0a3d4a4f9bd05e891c381 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:44:38 -0400 Subject: [PATCH 02/16] Add files via upload --- .../sapphire/Nearby/DeviceListCell.swift | 26 + .../Nearby/InboundNearbyConnection.swift | 291 ++ .../Nearby/NWConnectionProtocol.swift | 38 + .../Nearby/NearDropDisplayState.swift | 26 + .../sapphire/Nearby/NearbyConnection.swift | 468 +++ .../Nearby/NearbyConnectionManager.swift | 536 +++ .../Nearby/OutboundNearbyConnection.swift | 449 ++ .../sapphire/Nearby/ShareViewController.swift | 262 ++ .../sapphire/Nearby/TransferDirection.swift | 26 + submissions/sapphire/ObjC/Bridging-Header.h | 11 + .../ObjC/NDNotificationCenterHackery.h | 24 + .../ObjC/NDNotificationCenterHackery.m | 18 + submissions/sapphire/ObjC/PrivateAPI.h | 20 + .../sapphire/Protobuf-Inputs.xcfilelist | 6 + .../sapphire/Protobuf-Outputs.xcfilelist | 6 + .../device_to_device_messages.pb.swift | 540 +++ .../offline_wire_formats.pb.swift | 3653 +++++++++++++++++ .../ProtobufGenerated/securegcm.pb.swift | 1522 +++++++ .../ProtobufGenerated/securemessage.pb.swift | 951 +++++ .../sapphire/ProtobufGenerated/ukey.pb.swift | 735 ++++ .../ProtobufGenerated/wire_format.pb.swift | 1617 ++++++++ .../device_to_device_messages.proto | 81 + .../ProtobufSource/offline_wire_formats.proto | 403 ++ .../sapphire/ProtobufSource/securegcm.proto | 308 ++ .../ProtobufSource/securemessage.proto | 126 + .../sapphire/ProtobufSource/ukey.proto | 105 + .../sapphire/ProtobufSource/wire_format.proto | 236 ++ .../Sapphire.xcodeproj/project.pbxproj | 986 +++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/swiftpm/Package.resolved | 60 + .../IDEFindNavigatorScopes.plist | 5 + .../UserInterfaceState.xcuserstate | Bin 0 -> 684944 bytes .../xcshareddata/xcschemes/Sapphire.xcscheme | 102 + .../xcdebugger/Breakpoints_v2.xcbkptlist | 6 + .../xcschemes/xcschememanagement.plist | 42 + .../App Settings/SettingsComponents.swift | 380 ++ .../Sapphire/App Settings/SettingsModel.swift | 211 + .../Sapphire/App Settings/SettingsPanes.swift | 886 ++++ .../App Settings/SettingsSidebar.swift | 87 + .../Sapphire/App Settings/SettingsView.swift | 78 + .../Sapphire/App Settings/UpdateChecker.swift | 122 + .../Sapphire/App Settings/UserDefault.swift | 44 + .../sapphire/Sapphire/App/AppDelegate.swift | 245 ++ .../AppIcon.appiconset/Artboard 1.png | Bin 0 -> 118918 bytes .../AppIcon.appiconset/Artboard 1@0.5x 1.png | Bin 0 -> 32336 bytes .../AppIcon.appiconset/Artboard 1@0.5x.png | Bin 0 -> 32336 bytes .../AppIcon.appiconset/Artboard 2.png | Bin 0 -> 8675 bytes .../AppIcon.appiconset/Artboard 3.png | Bin 0 -> 2687 bytes .../AppIcon.appiconset/Artboard 4.png | Bin 0 -> 1075 bytes .../AppIcon.appiconset/Artboard 5.png | Bin 0 -> 1075 bytes .../AppIcon.appiconset/Artboard 6.png | Bin 0 -> 473 bytes .../AppIcon.appiconset/Contents.json | 68 + .../AppIcon.appiconset/Frame 32.png | Bin 0 -> 181896 bytes .../AppIcon.appiconset/Frame 33.png | Bin 0 -> 181896 bytes .../App/Assets.xcassets/Contents.json | 9 + .../Google-Gemini-Logo.imageset/Contents.json | 21 + .../Google-Gemini-Logo.png | Bin 0 -> 16697 bytes .../Sapphire/App/Base.lproj/Main.storyboard | 701 ++++ submissions/sapphire/Sapphire/App/Info.plist | 25 + .../Sapphire/App/OnboardingView.swift | 233 ++ .../Sapphire/App/PermissionsManager.swift | 185 + .../Sapphire/App/ViewController.swift | 25 + .../LiveActivityComponents.swift | 471 +++ .../LiveActivities/LiveActivityManager.swift | 273 ++ .../NearDropCompactActivityView.swift | 81 + .../NearDropLiveActivityView.swift | 257 ++ .../sapphire/Sapphire/Models/AppModels.swift | 121 + .../Sapphire/Models/SpotifyModels.swift | 125 + .../Sapphire/Models/WeatherModels.swift | 148 + .../Models/weatherActivityViewModel.swift | 36 + .../Sapphire/Notch/CustomNotchShape.swift | 64 + .../Sapphire/Notch/NotchConfiguration.swift | 55 + .../Sapphire/Notch/NotchController.swift | 507 +++ .../sapphire/Sapphire/Sapphire.entitlements | 16 + .../Services/Calendar/CalendarService.swift | 47 + .../Services/Calendar/CalendarViewModel.swift | 38 + .../Sapphire/Services/Gemini/GeminiAPI.swift | 137 + .../Sapphire/Services/Gemini/GeminiLive.swift | 42 + .../Services/Gemini/GeminiLiveManager.swift | 432 ++ .../Services/Music/LyricsFetcher.swift | 149 + .../Sapphire/Services/Music/MusicWidget.swift | 191 + .../Services/Music/SystemAudioMonitor.swift | 137 + .../Services/Music/WaveformView.swift | 141 + .../Services/Spotify/SpotifyAPIManager.swift | 338 ++ .../Services/System/ActiveAppMonitor.swift | 85 + .../Services/System/BluetoothManager.swift | 160 + .../Services/System/EyeBreakManager.swift | 86 + .../Services/System/NotificationManager.swift | 173 + .../Services/System/TimerManager.swift | 34 + .../Sapphire/System/PrivateAPIs.swift | 254 ++ .../System/PrivateBluetoothMonitor.swift | 52 + .../sapphire/Sapphire/System/SystemHUD.swift | 357 ++ .../Sapphire/Utilities/Extensions.swift | 184 + .../sapphire/Sapphire/Utilities/Helpers.swift | 99 + .../DynamicNotchTests.swift | 17 + .../DynamicNotchUITests.swift | 41 + .../DynamicNotchUITestsLaunchTests.swift | 33 + .../Contents/Info.plist | 40 + .../Contents/Resources/PrivacyInfo.xcprivacy | 14 + .../sapphire/Util/Data+Extensions.swift | 47 + 100 files changed, 22494 insertions(+) create mode 100644 submissions/sapphire/Nearby/DeviceListCell.swift create mode 100644 submissions/sapphire/Nearby/InboundNearbyConnection.swift create mode 100644 submissions/sapphire/Nearby/NWConnectionProtocol.swift create mode 100644 submissions/sapphire/Nearby/NearDropDisplayState.swift create mode 100644 submissions/sapphire/Nearby/NearbyConnection.swift create mode 100644 submissions/sapphire/Nearby/NearbyConnectionManager.swift create mode 100644 submissions/sapphire/Nearby/OutboundNearbyConnection.swift create mode 100644 submissions/sapphire/Nearby/ShareViewController.swift create mode 100644 submissions/sapphire/Nearby/TransferDirection.swift create mode 100644 submissions/sapphire/ObjC/Bridging-Header.h create mode 100644 submissions/sapphire/ObjC/NDNotificationCenterHackery.h create mode 100644 submissions/sapphire/ObjC/NDNotificationCenterHackery.m create mode 100644 submissions/sapphire/ObjC/PrivateAPI.h create mode 100644 submissions/sapphire/Protobuf-Inputs.xcfilelist create mode 100644 submissions/sapphire/Protobuf-Outputs.xcfilelist create mode 100644 submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift create mode 100644 submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift create mode 100644 submissions/sapphire/ProtobufGenerated/securegcm.pb.swift create mode 100644 submissions/sapphire/ProtobufGenerated/securemessage.pb.swift create mode 100644 submissions/sapphire/ProtobufGenerated/ukey.pb.swift create mode 100644 submissions/sapphire/ProtobufGenerated/wire_format.pb.swift create mode 100644 submissions/sapphire/ProtobufSource/device_to_device_messages.proto create mode 100644 submissions/sapphire/ProtobufSource/offline_wire_formats.proto create mode 100644 submissions/sapphire/ProtobufSource/securegcm.proto create mode 100644 submissions/sapphire/ProtobufSource/securemessage.proto create mode 100644 submissions/sapphire/ProtobufSource/ukey.proto create mode 100644 submissions/sapphire/ProtobufSource/wire_format.proto create mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.pbxproj create mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist create mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 submissions/sapphire/Sapphire.xcodeproj/xcshareddata/xcschemes/Sapphire.xcscheme create mode 100644 submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist create mode 100644 submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist create mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift create mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsModel.swift create mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift create mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift create mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsView.swift create mode 100644 submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift create mode 100644 submissions/sapphire/Sapphire/App Settings/UserDefault.swift create mode 100644 submissions/sapphire/Sapphire/App/AppDelegate.swift create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x 1.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 2.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 3.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 4.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 5.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 6.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 32.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 33.png create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json create mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Google-Gemini-Logo.png create mode 100644 submissions/sapphire/Sapphire/App/Base.lproj/Main.storyboard create mode 100644 submissions/sapphire/Sapphire/App/Info.plist create mode 100644 submissions/sapphire/Sapphire/App/OnboardingView.swift create mode 100644 submissions/sapphire/Sapphire/App/PermissionsManager.swift create mode 100644 submissions/sapphire/Sapphire/App/ViewController.swift create mode 100644 submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift create mode 100644 submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift create mode 100644 submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift create mode 100644 submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift create mode 100644 submissions/sapphire/Sapphire/Models/AppModels.swift create mode 100644 submissions/sapphire/Sapphire/Models/SpotifyModels.swift create mode 100644 submissions/sapphire/Sapphire/Models/WeatherModels.swift create mode 100644 submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift create mode 100644 submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift create mode 100644 submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift create mode 100644 submissions/sapphire/Sapphire/Notch/NotchController.swift create mode 100644 submissions/sapphire/Sapphire/Sapphire.entitlements create mode 100644 submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift create mode 100644 submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift create mode 100644 submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift create mode 100644 submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift create mode 100644 submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift create mode 100644 submissions/sapphire/Sapphire/Services/Music/MusicWidget.swift create mode 100644 submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift create mode 100644 submissions/sapphire/Sapphire/Services/Music/WaveformView.swift create mode 100644 submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/NotificationManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/TimerManager.swift create mode 100644 submissions/sapphire/Sapphire/System/PrivateAPIs.swift create mode 100644 submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift create mode 100644 submissions/sapphire/Sapphire/System/SystemHUD.swift create mode 100644 submissions/sapphire/Sapphire/Utilities/Extensions.swift create mode 100644 submissions/sapphire/Sapphire/Utilities/Helpers.swift create mode 100644 submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift create mode 100644 submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift create mode 100644 submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift create mode 100644 submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist create mode 100644 submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy create mode 100644 submissions/sapphire/Util/Data+Extensions.swift diff --git a/submissions/sapphire/Nearby/DeviceListCell.swift b/submissions/sapphire/Nearby/DeviceListCell.swift new file mode 100644 index 00000000..2393dc43 --- /dev/null +++ b/submissions/sapphire/Nearby/DeviceListCell.swift @@ -0,0 +1,26 @@ +// +// DeviceListCell.swift +// ShareExtension +// +// Created by Grishka on 20.09.2023. +// + +import Cocoa + +class DeviceListCell: NSCollectionViewItem { + public var clickHandler: (() -> Void)? + + override func viewDidLoad() { + super.viewDidLoad() + if let btn = view as? NSButton { + btn.isEnabled = true + btn.setButtonType(.momentaryPushIn) + btn.action = #selector(onClick) + btn.target = self + } + } + + @IBAction func onClick(_ sender: Any?) { + clickHandler?() + } +} diff --git a/submissions/sapphire/Nearby/InboundNearbyConnection.swift b/submissions/sapphire/Nearby/InboundNearbyConnection.swift new file mode 100644 index 00000000..92232c06 --- /dev/null +++ b/submissions/sapphire/Nearby/InboundNearbyConnection.swift @@ -0,0 +1,291 @@ +// +// InboundNearbyConnection.swift +// NearDrop +// +// Created by Grishka on 08.04.2023. +// + +import Foundation +import Network +import CryptoKit +import CommonCrypto +import System +import AppKit +import SwiftECC +import BigInt + +protocol InboundNearbyConnectionDelegate { + func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, fileURLs: [URL]) + func connection(_ connection: InboundNearbyConnection, didUpdateProgress progress: Double) + func connectionWasTerminated(connection: InboundNearbyConnection, error: Error?) +} + +class InboundNearbyConnection: NearbyConnection { + private var currentState: State = .initial + public var delegate: InboundNearbyConnectionDelegate? + private var cipherCommitment: Data? + private var textPayloadID: Int64 = 0 + private var userAction: NearDropUserAction = .save + + enum State { + case initial, receivedConnectionRequest, sentUkeyServerInit, receivedUkeyClientFinish, sentConnectionResponse, sentPairedKeyResult, receivedPairedKeyResult, waitingForUserConsent, receivingFiles, disconnecting, disconnected + } + + override init(connection: NWConnection, id: String) { + super.init(connection: connection, id: id) + } + + override func handleConnectionClosure() { + // If the connection is closed by the peer before the transfer is finished, + // and we don't have a specific error, treat it as a cancellation. + // This handles cases where the sender cancels the transfer from their device or it times out. + if (currentState == .waitingForUserConsent || currentState == .receivingFiles) && lastError == nil { + lastError = NearbyError.canceled(reason: .userCanceled) + } + + super.handleConnectionClosure() + currentState = .disconnected + do { try deletePartiallyReceivedFiles() } catch { print("Error deleting partially received files: \(error)") } + DispatchQueue.main.async { self.delegate?.connectionWasTerminated(connection: self, error: self.lastError) } + } + + override internal func processReceivedFrame(frameData: Data) { + do { + switch currentState { + case .initial: try processConnectionRequestFrame(try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)) + case .receivedConnectionRequest: let msg = try Securegcm_Ukey2Message(serializedData: frameData); ukeyClientInitMsgData = frameData; try processUkey2ClientInit(msg) + case .sentUkeyServerInit: try processUkey2ClientFinish(try Securegcm_Ukey2Message(serializedData: frameData), raw: frameData) + case .receivedUkeyClientFinish: try processConnectionResponseFrame(try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)) + default: try decryptAndProcessReceivedSecureMessage(try Securemessage_SecureMessage(serializedData: frameData)) + } + } catch { lastError = error; print("Deserialization error: \(error) in state \(currentState)"); protocolError() } + } + + override internal func processTransferSetupFrame(_ frame: Sharing_Nearby_Frame) throws { + if frame.hasV1, frame.v1.hasType, case .cancel = frame.v1.type { print("Transfer canceled"); try sendDisconnectionAndDisconnect(); return } + switch currentState { + case .sentConnectionResponse: try processPairedKeyEncryptionFrame(frame) + case .sentPairedKeyResult: try processPairedKeyResultFrame(frame) + case .receivedPairedKeyResult: try processIntroductionFrame(frame) + case .receivingFiles: break // This is expected after accepting + default: print("Unexpected connection state in processTransferSetupFrame: \(currentState)\n\(frame)") + } + } + + override func isServer() -> Bool { return true } + + override func processFileChunk(frame: Location_Nearby_Connections_PayloadTransferFrame) throws { + let id = frame.payloadHeader.id + guard let fileInfo = transferredFiles[id] else { throw NearbyError.protocolError("File payload ID \(id) is not known") } + let currentOffset = fileInfo.bytesTransferred + guard frame.payloadChunk.offset == currentOffset else { throw NearbyError.protocolError("Invalid offset") } + guard currentOffset + Int64(frame.payloadChunk.body.count) <= fileInfo.meta.size else { throw NearbyError.protocolError("File size mismatch") } + + if !frame.payloadChunk.body.isEmpty { + fileInfo.fileHandle?.write(frame.payloadChunk.body) + transferredFiles[id]!.bytesTransferred += Int64(frame.payloadChunk.body.count) + fileInfo.progress?.completedUnitCount = transferredFiles[id]!.bytesTransferred + let progress = Double(transferredFiles[id]!.bytesTransferred) / Double(fileInfo.meta.size) + DispatchQueue.main.async { + self.delegate?.connection(self, didUpdateProgress: progress) + } + } + + if (frame.payloadChunk.flags & 1) == 1 { + try fileInfo.fileHandle?.close(); transferredFiles[id]!.fileHandle = nil; fileInfo.progress?.unpublish() + + if userAction == .copy { + if let fileContents = try? String(contentsOf: fileInfo.destinationURL, encoding: .utf8) { + NSPasteboard.general.clearContents() + NSPasteboard.general.setString(fileContents, forType: .string) + } + try? FileManager.default.removeItem(at: fileInfo.destinationURL) + } + + transferredFiles.removeValue(forKey: id) + if transferredFiles.isEmpty { + currentState = .disconnecting + try sendDisconnectionAndDisconnect() + } + } + } + + override func processBytesPayload(payload: Data, id: Int64) throws -> Bool { + if id == textPayloadID { + guard let textContent = String(data: payload, encoding: .utf8) else { + if userAction != .save { print("Received non-UTF8 payload for an action other than save. Saving as binary.") } + try saveBinaryPayload(payload) + return true + } + + switch self.userAction { + case .save: + try saveTextPayload(textContent) + case .open: + if let url = extractURL(from: textContent) { NSWorkspace.shared.open(url) } + else { print("Could not extract URL to open, saving as text instead."); try saveTextPayload(textContent) } + case .copy: + let textToCopy = extractURL(from: textContent)?.absoluteString ?? textContent + NSPasteboard.general.clearContents() + NSPasteboard.general.setString(textToCopy, forType: .string) + } + + currentState = .disconnecting + try sendDisconnectionAndDisconnect() + return true + } + return false + } + + private func processConnectionRequestFrame(_ frame: Location_Nearby_Connections_OfflineFrame) throws { + guard frame.hasV1, frame.v1.hasConnectionRequest, frame.v1.connectionRequest.hasEndpointInfo, case .connectionRequest = frame.v1.type else { throw NearbyError.protocolError("Invalid connection request frame") } + let endpointInfo = frame.v1.connectionRequest.endpointInfo + guard endpointInfo.count > 17 else { throw NearbyError.protocolError("Endpoint info too short") } + let deviceNameLength = Int(endpointInfo[17]); guard endpointInfo.count >= deviceNameLength + 18 else { throw NearbyError.protocolError("Endpoint info too short for name") } + guard let deviceName = String(data: endpointInfo[18..<(18 + deviceNameLength)], encoding: .utf8) else { throw NearbyError.protocolError("Device name is not valid UTF-8") } + let rawDeviceType = Int(endpointInfo[0] & 7) >> 1 + remoteDeviceInfo = RemoteDeviceInfo(name: deviceName, type: .fromRawValue(value: rawDeviceType)) + currentState = .receivedConnectionRequest + } + + private func processUkey2ClientInit(_ msg: Securegcm_Ukey2Message) throws { + guard msg.hasMessageType, msg.hasMessageData, case .clientInit = msg.messageType else { sendUkey2Alert(type: .badMessageType); throw NearbyError.ukey2 } + let clientInit = try Securegcm_Ukey2ClientInit(serializedData: msg.messageData) + guard clientInit.version == 1 else { sendUkey2Alert(type: .badVersion); throw NearbyError.ukey2 } + guard clientInit.random.count == 32 else { sendUkey2Alert(type: .badRandom); throw NearbyError.ukey2 } + guard let commitment = clientInit.cipherCommitments.first(where: { $0.handshakeCipher == .p256Sha512 }) else { sendUkey2Alert(type: .badHandshakeCipher); throw NearbyError.ukey2 } + cipherCommitment = commitment.commitment + guard clientInit.nextProtocol == "AES_256_CBC-HMAC_SHA256" else { sendUkey2Alert(type: .badNextProtocol); throw NearbyError.ukey2 } + + let domain = Domain.instance(curve: .EC256r1); let (pubKey, privKey) = domain.makeKeyPair(); publicKey = pubKey; privateKey = privKey + var serverInit = Securegcm_Ukey2ServerInit(); serverInit.version = 1; serverInit.random = Data.randomData(length: 32); serverInit.handshakeCipher = .p256Sha512 + var pkey = Securemessage_GenericPublicKey(); pkey.type = .ecP256; pkey.ecP256PublicKey.x = Data(pubKey.w.x.asSignedBytes()); pkey.ecP256PublicKey.y = Data(pubKey.w.y.asSignedBytes()); serverInit.publicKey = try pkey.serializedData() + var serverInitMsg = Securegcm_Ukey2Message(); serverInitMsg.messageType = .serverInit; serverInitMsg.messageData = try serverInit.serializedData() + let serverInitData = try serverInitMsg.serializedData(); ukeyServerInitMsgData = serverInitData; sendFrameAsync(serverInitData); currentState = .sentUkeyServerInit + } + + private func processUkey2ClientFinish(_ msg: Securegcm_Ukey2Message, raw: Data) throws { + guard msg.hasMessageType, msg.hasMessageData, case .clientFinish = msg.messageType else { throw NearbyError.ukey2 } + var sha = SHA512(); sha.update(data: raw); guard cipherCommitment == Data(sha.finalize()) else { throw NearbyError.ukey2 } + let clientFinish = try Securegcm_Ukey2ClientFinished(serializedData: msg.messageData) + try finalizeKeyExchange(peerKey: try Securemessage_GenericPublicKey(serializedData: clientFinish.publicKey)); currentState = .receivedUkeyClientFinish + } + + private func processConnectionResponseFrame(_ frame: Location_Nearby_Connections_OfflineFrame) throws { + guard frame.hasV1, frame.v1.hasType, case .connectionResponse = frame.v1.type else { return } + var resp = Location_Nearby_Connections_OfflineFrame(); resp.version = .v1; resp.v1.type = .connectionResponse; resp.v1.connectionResponse.response = .accept; resp.v1.connectionResponse.osInfo.type = .apple; sendFrameAsync(try resp.serializedData()) + encryptionDone = true; var pairedEncryption = Sharing_Nearby_Frame(); pairedEncryption.version = .v1; pairedEncryption.v1.type = .pairedKeyEncryption + pairedEncryption.v1.pairedKeyEncryption.secretIDHash = Data.randomData(length: 6); pairedEncryption.v1.pairedKeyEncryption.signedData = Data.randomData(length: 72); try sendTransferSetupFrame(pairedEncryption); currentState = .sentConnectionResponse + } + + private func processPairedKeyEncryptionFrame(_ frame: Sharing_Nearby_Frame) throws { + guard frame.hasV1, frame.v1.hasPairedKeyEncryption else { throw NearbyError.requiredFieldMissing("shareNearbyFrame.v1.pairedKeyEncryption") } + var pairedResult = Sharing_Nearby_Frame(); pairedResult.version = .v1; pairedResult.v1.type = .pairedKeyResult; pairedResult.v1.pairedKeyResult.status = .unable; try sendTransferSetupFrame(pairedResult); currentState = .sentPairedKeyResult + } + + private func processPairedKeyResultFrame(_ frame: Sharing_Nearby_Frame) throws { + guard frame.hasV1, frame.v1.hasPairedKeyResult else { throw NearbyError.requiredFieldMissing("shareNearbyFrame.v1.pairedKeyResult") } + currentState = .receivedPairedKeyResult + } + + private func processIntroductionFrame(_ frame: Sharing_Nearby_Frame) throws { + guard frame.hasV1, frame.v1.hasIntroduction else { throw NearbyError.requiredFieldMissing("shareNearbyFrame.v1.introduction") } + currentState = .waitingForUserConsent; + var destinationURLs: [URL] = [] + let downloadsDirectory = (try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: true)).resolvingSymlinksInPath() + var textDescription: String? + + if !frame.v1.introduction.fileMetadata.isEmpty { + let files = frame.v1.introduction.fileMetadata + for file in files { + let dest = makeFileDestinationURL(downloadsDirectory.appendingPathComponent(file.name)); destinationURLs.append(dest) + let info = InternalFileInfo(meta: .init(name: file.name, size: file.size, mimeType: file.mimeType), payloadID: file.payloadID, destinationURL: dest) + transferredFiles[file.payloadID] = info + } + if files.count == 1, let firstFile = files.first, (firstFile.mimeType == "text/plain" || firstFile.name.lowercased().hasSuffix(".txt")) { + textDescription = firstFile.name + } + let metadata = TransferMetadata(files: transferredFiles.values.map { $0.meta }, id: id, pinCode: pinCode, textDescription: textDescription) + DispatchQueue.main.async { self.delegate?.obtainUserConsent(for: metadata, from: self.remoteDeviceInfo!, fileURLs: destinationURLs) } + } else if let meta = frame.v1.introduction.textMetadata.first { + textPayloadID = meta.payloadID + let metadata = TransferMetadata(files: [], id: id, pinCode: pinCode, textDescription: meta.textTitle) + DispatchQueue.main.async { self.delegate?.obtainUserConsent(for: metadata, from: self.remoteDeviceInfo!, fileURLs: []) } + } else { + rejectTransfer(with: .unsupportedAttachmentType) + } + } + + private func makeFileDestinationURL(_ initialDest: URL) -> URL { + var dest = initialDest; var counter = 1 + if FileManager.default.fileExists(atPath: dest.path) { + let ext = dest.pathExtension; let baseUrl = dest.deletingPathExtension() + repeat { dest = URL(fileURLWithPath: "\(baseUrl.path) (\(counter))\(ext.isEmpty ? "" : ".\(ext)")"); counter += 1 } while FileManager.default.fileExists(atPath: dest.path) + } + return dest + } + + func submitUserConsent(accepted: Bool, action: NearDropUserAction) { + DispatchQueue.global(qos: .utility).async { + if accepted { self.userAction = action; self.acceptTransfer() } + else { self.rejectTransfer() } + } + } + + private func acceptTransfer() { + do { + if !transferredFiles.isEmpty { + for (id, file) in transferredFiles { + FileManager.default.createFile(atPath: file.destinationURL.path, contents: nil) + let handle = try FileHandle(forWritingTo: file.destinationURL); transferredFiles[id]!.fileHandle = handle + let progress = Progress(); progress.fileURL = file.destinationURL; progress.totalUnitCount = file.meta.size; progress.kind = .file; progress.isPausable = false; progress.publish(); transferredFiles[id]!.progress = progress + } + } + var frame = Sharing_Nearby_Frame(); frame.version = .v1; frame.v1.type = .response; frame.v1.connectionResponse.status = .accept; currentState = .receivingFiles; try sendTransferSetupFrame(frame) + } catch { lastError = error; protocolError() } + } + + private func rejectTransfer(with reason: Sharing_Nearby_ConnectionResponseFrame.Status = .reject) { + var frame = Sharing_Nearby_Frame(); frame.version = .v1; frame.v1.type = .response; frame.v1.connectionResponse.status = reason + do { + try sendTransferSetupFrame(frame) + if reason == .reject { + self.lastError = NearbyError.canceled(reason: .userRejected) + } + try sendDisconnectionAndDisconnect() + } catch { + print("Error \(error)") + protocolError() + } + } + + private func extractURL(from string: String) -> URL? { + do { + let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) + if let match = detector.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) { + return match.url + } + } catch { + print("Error creating data detector: \(error.localizedDescription)") + } + return nil + } + + private func saveTextPayload(_ text: String) throws { + let downloadsDirectory = try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: true) + let dateFormatter = DateFormatter(); dateFormatter.dateFormat = "yyyy-MM-dd HH.mm.ss" + let dest = makeFileDestinationURL(downloadsDirectory.appendingPathComponent("Nearby Text \(dateFormatter.string(from: Date())).txt")) + try text.data(using: .utf8)?.write(to: dest) + } + + private func saveBinaryPayload(_ data: Data) throws { + let downloadsDirectory = try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: true) + let dateFormatter = DateFormatter(); dateFormatter.dateFormat = "yyyy-MM-dd HH.mm.ss" + let dest = makeFileDestinationURL(downloadsDirectory.appendingPathComponent("Nearby Data \(dateFormatter.string(from: Date())).bin")) + try data.write(to: dest) + } + + private func deletePartiallyReceivedFiles() throws { + for (_, file) in transferredFiles where file.created { try FileManager.default.removeItem(at: file.destinationURL) } + } +} diff --git a/submissions/sapphire/Nearby/NWConnectionProtocol.swift b/submissions/sapphire/Nearby/NWConnectionProtocol.swift new file mode 100644 index 00000000..d1f6b765 --- /dev/null +++ b/submissions/sapphire/Nearby/NWConnectionProtocol.swift @@ -0,0 +1,38 @@ +// +// NWConnectionProtocol.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-02. +// + + +import Foundation +import Network // This is the ONLY file that will contain this import. + +// Create protocols that mirror the NWConnection and NWListener APIs +// This decouples our code from the Network framework itself. + +protocol NWConnectionProtocol { + init(to: NWEndpoint, using: NWParameters) + var stateUpdateHandler: ((NWConnection.State) -> Void)? { get set } + func start(queue: DispatchQueue) + func send(content: Data?, completion: NWConnection.SendCompletion) + func receive(minimumIncompleteLength: Int, maximumLength: Int, completion: @escaping (Data?, NWConnection.ContentContext?, Bool, NWError?) -> Void) + func cancel() +} + +protocol NWListenerProtocol { + init(using: NWParameters) throws + var stateUpdateHandler: ((NWListener.State) -> Void)? { get set } + var newConnectionHandler: ((NWConnection) -> Void)? { get set } + var port: NWEndpoint.Port? { get } + func start(queue: DispatchQueue) + func cancel() +} + +// Make the real classes conform to our protocols +extension NWConnection: NWConnectionProtocol {} +extension NWListener: NWListenerProtocol {} + +// We will now use `NWConnectionProtocol` and `NWListenerProtocol` +// throughout the NearbyShare code instead of the concrete types. \ No newline at end of file diff --git a/submissions/sapphire/Nearby/NearDropDisplayState.swift b/submissions/sapphire/Nearby/NearDropDisplayState.swift new file mode 100644 index 00000000..181bc3c3 --- /dev/null +++ b/submissions/sapphire/Nearby/NearDropDisplayState.swift @@ -0,0 +1,26 @@ +// +// NearDropDisplayState.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-02. +// + +import Foundation + +/// The different states a NearDrop transfer can be in for the UI. +enum NearDropDisplayState: Equatable { + case waitingForConsent + case inProgress + case finished + case failed(String) +} + +/// A clean, decoupled data structure for displaying the NearDrop live activity. +/// It has no dependency on the NearbyShare module. +struct NearDropDisplayPayload: Identifiable, Equatable { + let id: String // The unique transfer ID + let deviceName: String + let fileInfo: String + let pinCode: String? + var state: NearDropDisplayState = .waitingForConsent +} diff --git a/submissions/sapphire/Nearby/NearbyConnection.swift b/submissions/sapphire/Nearby/NearbyConnection.swift new file mode 100644 index 00000000..da229ac3 --- /dev/null +++ b/submissions/sapphire/Nearby/NearbyConnection.swift @@ -0,0 +1,468 @@ +// +// NearbyConnection.swift +// NearDrop +// +// Created by Grishka on 09.04.2023. +// + +import Foundation +import Network +import CommonCrypto +import CryptoKit +import System + +import SwiftECC +import BigInt + +class NearbyConnection{ + internal static let SANE_FRAME_LENGTH=5*1024*1024 + private static let dispatchQueue=DispatchQueue(label: "me.grishka.NearDrop.queue", qos: .utility) // FIFO (non-concurrent) queue to avoid those exciting concurrency bugs + + internal let connection:NWConnection + internal var remoteDeviceInfo:RemoteDeviceInfo? + private var payloadBuffers:[Int64:NSMutableData]=[:] + internal var encryptionDone:Bool=false + internal var transferredFiles:[Int64:InternalFileInfo]=[:] + public let id:String + internal var lastError:Error? + private var connectionClosed:Bool=false + + // UKEY2-related state + internal var publicKey:ECPublicKey? + internal var privateKey:ECPrivateKey? + internal var ukeyClientInitMsgData:Data? + internal var ukeyServerInitMsgData:Data? + + // SecureMessage encryption keys + internal var decryptKey:[UInt8]? + internal var encryptKey:[UInt8]? + internal var recvHmacKey:SymmetricKey? + internal var sendHmacKey:SymmetricKey? + + // SecureMessage sequence numbers + private var serverSeq:Int32=0 + private var clientSeq:Int32=0 + + private(set) var pinCode:String? + + init(connection:NWConnection, id:String) { + self.connection=connection + self.id=id + } + + func start(){ + connection.stateUpdateHandler={state in + if case .ready = state { + self.connectionReady() + self.receiveFrameAsync() + } else if case .failed(let err) = state { + self.lastError=err + print("Error opening socket: \(err)") + self.handleConnectionClosure() + } + } + //connection.start(queue: .global(qos: .utility)) + connection.start(queue: NearbyConnection.dispatchQueue) + } + + func connectionReady(){} + + internal func handleConnectionClosure(){ + print("Connection closed") + } + + internal func protocolError(){ + disconnect() + } + + internal func processReceivedFrame(frameData:Data){ + fatalError() + } + + internal func processTransferSetupFrame(_ frame:Sharing_Nearby_Frame) throws{ + fatalError() + } + + internal func isServer() -> Bool{ + fatalError() + } + + internal func processFileChunk(frame:Location_Nearby_Connections_PayloadTransferFrame) throws{ + protocolError() + } + + internal func processBytesPayload(payload:Data, id:Int64)throws ->Bool{ + return false + } + + private func receiveFrameAsync(){ + connection.receive(minimumIncompleteLength: 4, maximumLength: 4) { content, contentContext, isComplete, error in + if self.connectionClosed{ + return + } + if isComplete{ + self.handleConnectionClosure() + return + } + if !(error==nil){ + self.lastError=error + self.protocolError() + return + } + guard let content=content else { + assertionFailure() + return + } + let frameLength:UInt32=UInt32(content[0]) << 24 | UInt32(content[1]) << 16 | UInt32(content[2]) << 8 | UInt32(content[3]) + guard frameLengthVoid)?=nil){ + if connectionClosed{ + return + } + var lengthPrefixedData=Data(capacity: frame.count+4) + let length:Int=frame.count + lengthPrefixedData.append(contentsOf: [ + UInt8(truncatingIfNeeded: length >> 24), + UInt8(truncatingIfNeeded: length >> 16), + UInt8(truncatingIfNeeded: length >> 8), + UInt8(truncatingIfNeeded: length) + ]) + lengthPrefixedData.append(frame) + connection.send(content: lengthPrefixedData, completion: .contentProcessed({ error in + if let completion=completion{ + completion() + } + })) + } + + internal func encryptAndSendOfflineFrame(_ frame:Location_Nearby_Connections_OfflineFrame, completion:(()->Void)?=nil) throws{ + var d2dMsg=Securegcm_DeviceToDeviceMessage() + serverSeq+=1 + d2dMsg.sequenceNumber=serverSeq + d2dMsg.message=try frame.serializedData() + + let serializedMsg=[UInt8](try d2dMsg.serializedData()) + let iv=Data.randomData(length: 16) + var encryptedData=Data(count: serializedMsg.count+16) + var encryptedLength:size_t=0 + encryptedData.withUnsafeMutableBytes({ + let status=CCCrypt( + CCOperation(kCCEncrypt), + CCAlgorithm(kCCAlgorithmAES128), + CCOptions(kCCOptionPKCS7Padding), + encryptKey, kCCKeySizeAES256, + [UInt8](iv), + serializedMsg, serializedMsg.count, + $0.baseAddress, $0.count, + &encryptedLength + ) + guard status==kCCSuccess else { fatalError("CCCrypt error: \(status)") } + }) + + var hb=Securemessage_HeaderAndBody() + hb.body=encryptedData.prefix(encryptedLength) + hb.header=Securemessage_Header() + hb.header.encryptionScheme = .aes256Cbc + hb.header.signatureScheme = .hmacSha256 + hb.header.iv=iv + var md=Securegcm_GcmMetadata() + md.type = .deviceToDeviceMessage + md.version=1 + hb.header.publicMetadata=try md.serializedData() + + var smsg=Securemessage_SecureMessage() + smsg.headerAndBody=try hb.serializedData() + smsg.signature=Data(HMAC.authenticationCode(for: smsg.headerAndBody, using: sendHmacKey!)) + sendFrameAsync(try smsg.serializedData(), completion: completion) + } + + internal func sendTransferSetupFrame(_ frame:Sharing_Nearby_Frame) throws{ + try sendBytesPayload(data: try frame.serializedData(), id: Int64.random(in: Int64.min...Int64.max)) + } + + internal func sendBytesPayload(data:Data, id:Int64) throws{ + var transfer=Location_Nearby_Connections_PayloadTransferFrame() + transfer.packetType = .data + transfer.payloadChunk.offset=0 + transfer.payloadChunk.flags=0 + transfer.payloadChunk.body=data + transfer.payloadHeader.id=id + transfer.payloadHeader.type = .bytes + transfer.payloadHeader.totalSize=Int64(transfer.payloadChunk.body.count) + transfer.payloadHeader.isSensitive=false + + var wrapper=Location_Nearby_Connections_OfflineFrame() + wrapper.version = .v1 + wrapper.v1=Location_Nearby_Connections_V1Frame() + wrapper.v1.type = .payloadTransfer + wrapper.v1.payloadTransfer=transfer + try encryptAndSendOfflineFrame(wrapper) + + transfer.payloadChunk.flags=1 // .lastChunk + transfer.payloadChunk.offset=Int64(transfer.payloadChunk.body.count) + transfer.payloadChunk.clearBody() + wrapper.v1.payloadTransfer=transfer + try encryptAndSendOfflineFrame(wrapper) + } + + internal func decryptAndProcessReceivedSecureMessage(_ smsg:Securemessage_SecureMessage) throws{ + guard smsg.hasSignature, smsg.hasHeaderAndBody else { throw NearbyError.requiredFieldMissing("secureMessage.signature|headerAndBody") } + let hmac=Data(HMAC.authenticationCode(for: smsg.headerAndBody, using: recvHmacKey!)) + guard hmac==smsg.signature else { throw NearbyError.protocolError("hmac!=signature") } + let headerAndBody=try Securemessage_HeaderAndBody(serializedData: smsg.headerAndBody) + var decryptedData=Data(count: headerAndBody.body.count) + + var decryptedLength:Int=0 + decryptedData.withUnsafeMutableBytes({ + let status=CCCrypt( + CCOperation(kCCDecrypt), + CCAlgorithm(kCCAlgorithmAES128), + CCOptions(kCCOptionPKCS7Padding), + decryptKey, kCCKeySizeAES256, + [UInt8](headerAndBody.header.iv), + [UInt8](headerAndBody.body), headerAndBody.body.count, + $0.baseAddress, $0.count, + &decryptedLength + ) + guard status==kCCSuccess else { fatalError("CCCrypt error: \(status)") } + }) + decryptedData=decryptedData.prefix(decryptedLength) + let d2dMsg=try Securegcm_DeviceToDeviceMessage(serializedData: decryptedData) + guard d2dMsg.hasMessage, d2dMsg.hasSequenceNumber else { throw NearbyError.requiredFieldMissing("d2dMessage.message|sequenceNumber") } + clientSeq+=1 + guard d2dMsg.sequenceNumber==clientSeq else { throw NearbyError.protocolError("Wrong sequence number. Expected \(clientSeq), got \(d2dMsg.sequenceNumber)") } + let offlineFrame=try Location_Nearby_Connections_OfflineFrame(serializedData: d2dMsg.message) + + if offlineFrame.hasV1 && offlineFrame.v1.hasType, case .payloadTransfer = offlineFrame.v1.type { + guard offlineFrame.v1.hasPayloadTransfer else { throw NearbyError.requiredFieldMissing("offlineFrame.v1.payloadTransfer") } + let payloadTransfer=offlineFrame.v1.payloadTransfer + let header=payloadTransfer.payloadHeader; + let chunk=payloadTransfer.payloadChunk; + guard header.hasType, header.hasID else { throw NearbyError.requiredFieldMissing("payloadHeader.type|id") } + guard payloadTransfer.hasPayloadChunk, chunk.hasOffset, chunk.hasFlags else { throw NearbyError.requiredFieldMissing("payloadTransfer.payloadChunk|offset|flags") } + if case .bytes = header.type{ + let payloadID=header.id + if header.totalSize > InboundNearbyConnection.SANE_FRAME_LENGTH { + payloadBuffers.removeValue(forKey: payloadID) + throw NearbyError.protocolError("Payload too large (\(header.totalSize) bytes)") + } + if payloadBuffers[payloadID]==nil { + payloadBuffers[payloadID]=NSMutableData(capacity: Int(header.totalSize)) + } + let buffer=payloadBuffers[payloadID]! + guard chunk.offset==buffer.count else { + payloadBuffers.removeValue(forKey: payloadID) + throw NearbyError.protocolError("Unexpected chunk offset \(chunk.offset), expected \(buffer.count)") + } + if chunk.hasBody { + buffer.append(chunk.body) + } + + if let inbound = self as? InboundNearbyConnection, header.totalSize > 0 { + let progress = Double(buffer.count) / Double(header.totalSize) + DispatchQueue.main.async { + inbound.delegate?.connection(inbound, didUpdateProgress: progress) + } + } + + if (chunk.flags & 1)==1 { + payloadBuffers.removeValue(forKey: payloadID) + if !(try processBytesPayload(payload: Data(buffer), id: payloadID)){ + let innerFrame=try Sharing_Nearby_Frame(serializedData: buffer as Data) + try processTransferSetupFrame(innerFrame) + } + } + }else if case .file = header.type{ + try processFileChunk(frame: payloadTransfer) + } + }else if offlineFrame.hasV1 && offlineFrame.v1.hasType, case .keepAlive = offlineFrame.v1.type{ + #if DEBUG + print("Sent keep-alive") + #endif + sendKeepAlive(ack: true) + }else{ + print("Unhandled offline frame encrypted: \(offlineFrame)") + } + } + + internal static func pinCodeFromAuthKey(_ key:SymmetricKey) -> String{ + var hash:Int=0 + var multiplier:Int=1 + let keyBytes:[UInt8]=key.withUnsafeBytes({ + return [UInt8]($0) + }) + + for _byte in keyBytes { + let byte=Int(Int8(bitPattern: _byte)) + hash=(hash+byte*multiplier)%9973 + multiplier=(multiplier*31)%9973 + } + + return String(format: "%04d", abs(hash)) + } + + internal static func hkdfExtract(salt:Data, ikm:Data) -> Data{ + return HMAC.authenticationCode(for: ikm, using: SymmetricKey(data: salt)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)}) + } + + internal static func hkdfExpand(prk:Data, info:Data, length:Int) -> Data{ + var okm=Data() + var t=Data() + var i=0 + while okm.count.authenticationCode(for: toDigest, using: SymmetricKey(data: prk)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)}) + okm=okm+t + } + return okm.subdata(in: 0.. SymmetricKey{ + if #available(macOS 11.0, *){ + return HKDF.deriveKey(inputKeyMaterial: inputKeyMaterial, salt: salt, info: info, outputByteCount: outputByteCount) + }else{ + return SymmetricKey(data: hkdfExpand(prk: hkdfExtract(salt: salt, ikm: inputKeyMaterial.withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})), info: info, length: outputByteCount)) + } + } + + internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{ + guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") } + + let domain=Domain.instance(curve: .EC256r1) + var clientX=peerKey.ecP256PublicKey.x + var clientY=peerKey.ecP256PublicKey.y + if clientX.count>32{ + clientX=clientX.suffix(32) + } + if clientY.count>32{ + clientY=clientY.suffix(32) + } + let key=try ECPublicKey(domain: domain, w: Point(BInt(magnitude: [UInt8](clientX)), BInt(magnitude: [UInt8](clientY)))) + + let dhs=(try privateKey?.domain.multiplyPoint(key.w, privateKey!.s).x.asMagnitudeBytes())! + var sha=SHA256() + sha.update(data: dhs) + let derivedSecretKey=Data(sha.finalize()) + + var ukeyInfo=Data() + ukeyInfo.append(ukeyClientInitMsgData!) + ukeyInfo.append(ukeyServerInitMsgData!) + let authString=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32) + let nextSecret=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32) + + pinCode=NearbyConnection.pinCodeFromAuthKey(authString) + + let salt:Data=Data([0x82, 0xAA, 0x55, 0xA0, 0xD3, 0x97, 0xF8, 0x83, 0x46, 0xCA, 0x1C, + 0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D, + 0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10]) + + let d2dClientKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32) + let d2dServerKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32) + + sha=SHA256() + sha.update(data: "SecureMessage".data(using: .utf8)!) + let smsgSalt=Data(sha.finalize()) + + let clientKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)}) + let clientHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32) + let serverKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)}) + let serverHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32) + + if isServer(){ + decryptKey=clientKey + recvHmacKey=clientHmacKey + encryptKey=serverKey + sendHmacKey=serverHmacKey + }else{ + decryptKey=serverKey + recvHmacKey=serverHmacKey + encryptKey=clientKey + sendHmacKey=clientHmacKey + } + } + + internal func disconnect(){ + connection.send(content: nil, isComplete: true, completion: .contentProcessed({ error in + self.handleConnectionClosure() + })) + connectionClosed=true + } + + internal func sendDisconnectionAndDisconnect() throws{ + var offlineFrame=Location_Nearby_Connections_OfflineFrame() + offlineFrame.version = .v1 + offlineFrame.v1.type = .disconnection + offlineFrame.v1.disconnection=Location_Nearby_Connections_DisconnectionFrame() + + if encryptionDone{ + try encryptAndSendOfflineFrame(offlineFrame) + }else{ + sendFrameAsync(try offlineFrame.serializedData()) + } + disconnect() + } + + internal func sendUkey2Alert(type:Securegcm_Ukey2Alert.AlertType){ + var alert=Securegcm_Ukey2Alert() + alert.type=type + var msg=Securegcm_Ukey2Message() + msg.messageType = .alert + msg.messageData = try! alert.serializedData() + sendFrameAsync(try! msg.serializedData()) + disconnect() + } + + internal func sendKeepAlive(ack:Bool){ + var offlineFrame=Location_Nearby_Connections_OfflineFrame() + offlineFrame.version = .v1 + offlineFrame.v1.type = .keepAlive + offlineFrame.v1.keepAlive.ack=ack + + do{ + if encryptionDone{ + try encryptAndSendOfflineFrame(offlineFrame) + }else{ + sendFrameAsync(try offlineFrame.serializedData()) + } + }catch{ + print("Error sending KEEP_ALIVE: \(error)") + } + } +} + +struct InternalFileInfo{ + let meta:FileMetadata + let payloadID:Int64 + let destinationURL:URL + var bytesTransferred:Int64=0 + var fileHandle:FileHandle? + var progress:Progress? + var created:Bool=false +} diff --git a/submissions/sapphire/Nearby/NearbyConnectionManager.swift b/submissions/sapphire/Nearby/NearbyConnectionManager.swift new file mode 100644 index 00000000..84e503e1 --- /dev/null +++ b/submissions/sapphire/Nearby/NearbyConnectionManager.swift @@ -0,0 +1,536 @@ +// +// NearbyConnectionManager.swift +// NearDrop +// +// Created by Grishka on 08.04.2023. +// + +import Foundation +import Network +import System +import Combine + +public enum NearDropUserAction { + case save + case open + case copy +} + +public struct RemoteDeviceInfo{ + public let name:String + public let type:DeviceType + public var id:String? + + init(name: String, type: DeviceType, id: String? = nil) { + self.name = name + self.type = type + self.id = id + } + + init(info:EndpointInfo){ + self.name=info.name + self.type=info.deviceType + } + + public enum DeviceType:Int32{ + case unknown=0 + case phone + case tablet + case computer + + public static func fromRawValue(value:Int) -> DeviceType{ + switch value { + case 0: + return .unknown + case 1: + return .phone + case 2: + return .tablet + case 3: + return .computer + default: + return .unknown + } + } + } +} + + +public enum NearbyError:Error{ + case protocolError(_ message:String) + case requiredFieldMissing(_ message:String) + case ukey2 + case inputOutput + case canceled(reason:CancellationReason) + + public enum CancellationReason{ + case userRejected, userCanceled, notEnoughSpace, unsupportedType, timedOut + } +} + +public struct TransferMetadata{ + public let files:[FileMetadata] + public let id:String + public let pinCode:String? + public let textDescription:String? + + init(files: [FileMetadata], id: String, pinCode: String?, textDescription: String?=nil){ + self.files = files + self.id = id + self.pinCode = pinCode + self.textDescription = textDescription + } +} + +public struct FileMetadata{ + public let name:String + public let size:Int64 + public let mimeType:String +} + +struct FoundServiceInfo{ + let service:NWBrowser.Result + var device:RemoteDeviceInfo? +} + +struct OutgoingTransferInfo{ + let service:NWBrowser.Result + let device:RemoteDeviceInfo + let connection:OutboundNearbyConnection + let delegate:ShareExtensionDelegate +} + +struct EndpointInfo{ + let name:String + let deviceType:RemoteDeviceInfo.DeviceType + + init(name: String, deviceType: RemoteDeviceInfo.DeviceType){ + self.name = name + self.deviceType = deviceType + } + + init?(data:Data){ + guard data.count>17 else {return nil} + let deviceNameLength=Int(data[17]) + guard data.count>=deviceNameLength+18 else {return nil} + guard let deviceName=String(data: data[18..<(18+deviceNameLength)], encoding: .utf8) else {return nil} + let rawDeviceType:Int=Int(data[0] & 7) >> 1 + self.name=deviceName + self.deviceType=RemoteDeviceInfo.DeviceType.fromRawValue(value: rawDeviceType) + } + + func serialize()->Data{ + var endpointInfo:[UInt8]=[UInt8(deviceType.rawValue << 1)] + for _ in 0...15{ + endpointInfo.append(UInt8.random(in: 0...255)) + } + var nameChars=[UInt8](name.utf8) + if nameChars.count>255{ + nameChars=[UInt8](nameChars[0..<255]) + } + endpointInfo.append(UInt8(nameChars.count)) + for ch in nameChars{ + endpointInfo.append(UInt8(ch)) + } + return Data(endpointInfo) + } +} + +public protocol ShareExtensionDelegate:AnyObject{ + func addDevice(device:RemoteDeviceInfo) + func removeDevice(id:String) + func connectionWasEstablished(pinCode:String) + func connectionFailed(with error:Error) + func transferAccepted() + func transferProgress(progress:Double) + func transferFinished() +} + +public protocol MainAppDelegate { + func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, fileURLs: [URL]) + func incomingTransfer(id: String, didUpdateProgress progress: Double) + func incomingTransfer(id: String, didFinishWith error: Error?) +} + +// A lightweight struct to decode only the settings we need. +fileprivate struct NeardropFrameworkSettings: Decodable { + let neardropEnabled: Bool + let neardropDeviceDisplayName: String +} + +public class NearbyConnectionManager: NSObject, ObservableObject, NetServiceDelegate, InboundNearbyConnectionDelegate, OutboundNearbyConnectionDelegate { + + private var tcpListener: NWListener; + public let endpointID: [UInt8] = generateEndpointID() + private var mdnsService: NetService? + private var activeConnections: [String: InboundNearbyConnection] = [:] + private var foundServices: [String: FoundServiceInfo] = [:] + private var shareExtensionDelegates: [ShareExtensionDelegate] = [] + private var outgoingTransfers: [String: OutgoingTransferInfo] = [:] + public var mainAppDelegate: (any MainAppDelegate)? + private var discoveryRefCount = 0 + private var browser: NWBrowser? + + @Published public var transfers: [TransferProgressInfo] = [] + @Published public var pendingTransfers: [String: TransferProgressInfo] = [:] + private var cleanupTimers: [String: Timer] = [:] + + private let sharedDefaults: UserDefaults + + public static let shared = NearbyConnectionManager() + + override init() { + let appGroupID = "group.com.shariq.sapphire.shared" + self.sharedDefaults = UserDefaults(suiteName: appGroupID) ?? .standard + tcpListener = try! NWListener(using: NWParameters(tls: .none)) + super.init() + NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: sharedDefaults) + } + + @objc private func userDefaultsDidChange() { + DispatchQueue.main.async { + self.updateServiceFromSettings() + } + } + + private func loadSettings() -> NeardropFrameworkSettings { + if let data = sharedDefaults.data(forKey: "appSettings"), + let settings = try? JSONDecoder().decode(NeardropFrameworkSettings.self, from: data) { + return settings + } + return NeardropFrameworkSettings(neardropEnabled: true, neardropDeviceDisplayName: Host.current().localizedName ?? "My Mac") + } + + public func becomeVisible() { + print("[NCM] Attempting to become visible...") + updateServiceFromSettings() + } + + private func updateServiceFromSettings() { + let settings = loadSettings() + print("[NCM] Updating service based on settings. Neardrop Enabled: \(settings.neardropEnabled)") + + if settings.neardropEnabled { + if tcpListener.port == nil { + print("[NCM] TCP Listener not running. Starting now.") + startTCPListener() + } + } else { + if mdnsService != nil { + print("[NCM] Neardrop is disabled. Stopping MDNS service.") + mdnsService?.stop() + mdnsService = nil + } + } + } + + private func startTCPListener() { + tcpListener.stateUpdateHandler = { [weak self] state in + guard let self = self else { return } + + switch state { + case .ready: + if let port = self.tcpListener.port, port.rawValue > 0 { + print("[NCM] TCP Listener is ready on port \(port.rawValue). Initializing MDNS.") + self.initMDNS(on: port) + } else { + print("❌ [NCM] TCP Listener is ready, but the port is invalid (0 or nil). Cannot start MDNS broadcast.") + } + case .failed(let error): + print("❌ [NCM] TCP Listener failed to start: \(error.localizedDescription)") + self.mdnsService?.stop() + self.mdnsService = nil + default: + break + } + } + + tcpListener.newConnectionHandler = { [weak self] connection in + let id = UUID().uuidString + let conn = InboundNearbyConnection(connection: connection, id: id) + self?.activeConnections[id] = conn + conn.delegate = self + conn.start() + } + + tcpListener.start(queue: .global(qos: .utility)) + } + + private static func generateEndpointID() -> [UInt8] { + var id: [UInt8] = []; let alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".compactMap { UInt8($0.asciiValue!) } + for _ in 0...3 { id.append(alphabet[Int.random(in: 0..= 0) + if discoveryRefCount == 0 { browser?.cancel(); browser = nil } + } + + public func addShareExtensionDelegate(_ delegate: ShareExtensionDelegate) { + shareExtensionDelegates.append(delegate) + for service in foundServices.values { if let device = service.device { delegate.addDevice(device: device) } } + } + + public func removeShareExtensionDelegate(_ delegate: ShareExtensionDelegate) { shareExtensionDelegates.removeAll { $0 === delegate } } + public func cancelOutgoingTransfer(id: String) { + outgoingTransfers[id]?.connection.cancel() + } + + private func endpointID(for service: NWBrowser.Result) -> String? { + guard case let .service(name: serviceName, _, _, _) = service.endpoint, let nameData = Data.dataFromUrlSafeBase64(serviceName), nameData.count >= 10, + nameData[0] == 0x23, nameData.subdata(in: 5..<8) == Data([0xFC, 0x9F, 0x5E]) else { return nil } + return String(data: nameData.subdata(in: 1..<5), encoding: .ascii) + } + + private func maybeAddFoundDevice(service: NWBrowser.Result) { + if service.interfaces.contains(where: { $0.type == .loopback }) { return } + guard let endpointID = endpointID(for: service) else { return } + var foundService = FoundServiceInfo(service: service) + guard case let .bonjour(txtRecord) = service.metadata, let infoEncoded = txtRecord.dictionary["n"], let infoData = Data.dataFromUrlSafeBase64(infoEncoded), infoData.count >= 19 else { return } + let nameLength = Int(infoData[17]); guard infoData.count >= nameLength + 18, let name = String(data: infoData.subdata(in: 18..<(18 + nameLength)), encoding: .utf8) else { return } + let type = RemoteDeviceInfo.DeviceType.fromRawValue(value: (Int(infoData[0]) >> 1) & 7) + let deviceInfo = RemoteDeviceInfo(name: name, type: type, id: endpointID) + foundService.device = deviceInfo; foundServices[endpointID] = foundService + for delegate in shareExtensionDelegates { delegate.addDevice(device: deviceInfo) } + } + + private func maybeRemoveFoundDevice(service: NWBrowser.Result) { + guard let endpointID = endpointID(for: service), foundServices.removeValue(forKey: endpointID) != nil else { return } + for delegate in shareExtensionDelegates { delegate.removeDevice(id: endpointID) } + } + + public func startOutgoingTransfer(deviceID: String, delegate: ShareExtensionDelegate, urls: [URL]) { + guard let info = foundServices[deviceID] else { return } + let tcp = NWProtocolTCP.Options(); tcp.noDelay = true + let nwconn = NWConnection(to: info.service.endpoint, using: NWParameters(tls: .none, tcp: tcp)) + let conn = OutboundNearbyConnection(connection: nwconn, id: deviceID, urlsToSend: urls) + conn.delegate = self + outgoingTransfers[deviceID] = OutgoingTransferInfo(service: info.service, device: info.device!, connection: conn, delegate: delegate) + + let transferInfo = TransferProgressInfo( + id: deviceID, + deviceName: info.device!.name, + fileDescription: urls.count == 1 ? urls[0].lastPathComponent : "\(urls.count) files", + direction: .outgoing, + iconName: "arrow.up.doc" + ) + DispatchQueue.main.async { + self.transfers.insert(transferInfo, at: 0) + } + + conn.start() + } + + func outboundConnectionWasEstablished(connection: OutboundNearbyConnection) { + if let transfer = outgoingTransfers[connection.id] { + DispatchQueue.main.async { transfer.delegate.connectionWasEstablished(pinCode: connection.pinCode!) } + } + } + + func outboundConnectionTransferAccepted(connection: OutboundNearbyConnection) { + if let transfer = outgoingTransfers[connection.id] { + DispatchQueue.main.async { + transfer.delegate.transferAccepted() + if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { + self.transfers[index].state = .inProgress + } + } + } + } + + func outboundConnection(connection: OutboundNearbyConnection, transferProgress: Double) { + if let transfer = outgoingTransfers[connection.id] { + DispatchQueue.main.async { + transfer.delegate.transferProgress(progress: transferProgress) + if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { + self.transfers[index].progress = transferProgress + } + } + } + } + + func outboundConnection(connection: OutboundNearbyConnection, failedWithError: Error) { + if let transfer = outgoingTransfers.removeValue(forKey: connection.id) { + DispatchQueue.main.async { + transfer.delegate.connectionFailed(with: failedWithError) + if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { + self.transfers[index].state = .failed + self.scheduleCleanup(for: connection.id) + } + } + } + } + + func outboundConnectionTransferFinished(connection: OutboundNearbyConnection) { + if let transfer = outgoingTransfers.removeValue(forKey: connection.id) { + DispatchQueue.main.async { + transfer.delegate.transferFinished() + if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { + self.transfers[index].state = .finished + self.scheduleCleanup(for: connection.id) + } + } + } + } + + // MARK: - Helpers & Delegate Methods + + public func netServiceDidPublish(_ sender: NetService) { + print("✅ [NCM - NetService] Successfully published service: \(sender.name) on port \(sender.port)") + } + + public func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]) { + print("❌ [NCM - NetService] FAILED to publish service: \(sender.name). Error: \(errorDict)") + } + + private func scheduleCleanup(for transferID: String) { + cleanupTimers[transferID]?.invalidate() + let timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { [weak self] _ in + DispatchQueue.main.async { + guard let self = self else { return } + self.transfers.removeAll { $0.id == transferID } + self.cleanupTimers.removeValue(forKey: transferID) + } + } + cleanupTimers[transferID] = timer + } + + private func fileDescription(for transfer: TransferMetadata) -> String { + if let text = transfer.textDescription { return text } + if transfer.files.count == 1 { return transfer.files[0].name } + return "\(transfer.files.count) files" + } + + private func iconName(for transfer: TransferMetadata) -> String { + if let desc = transfer.textDescription { + if let _ = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue).firstMatch(in: desc, options: [], range: NSRange(location: 0, length: desc.utf16.count)) { + return "link" + } + return "text.quote" + } + guard let firstFile = transfer.files.first else { return "questionmark" } + if transfer.files.count > 1 { return "doc.on.doc.fill" } + + let mimeType = firstFile.mimeType.lowercased() + if mimeType.starts(with: "image/") { return "photo" } + if mimeType.starts(with: "video/") { return "video.fill" } + if mimeType.starts(with: "audio/") { return "music.note" } + if mimeType.contains("pdf") { return "doc.richtext.fill" } + if mimeType.contains("zip") || mimeType.contains("archive") { return "archivebox.fill" } + + return "doc.fill" + } +} diff --git a/submissions/sapphire/Nearby/OutboundNearbyConnection.swift b/submissions/sapphire/Nearby/OutboundNearbyConnection.swift new file mode 100644 index 00000000..8000a201 --- /dev/null +++ b/submissions/sapphire/Nearby/OutboundNearbyConnection.swift @@ -0,0 +1,449 @@ +// +// OutboundNearbyConnection.swift +// NearbyShare +// +// Created by Grishka on 23.09.2023. +// + +import Foundation +import Network +import CryptoKit +import CommonCrypto +import System +import UniformTypeIdentifiers + +import SwiftECC +import BigInt + +class OutboundNearbyConnection:NearbyConnection{ + private var currentState:State = .initial + private let urlsToSend:[URL] + private var ukeyClientFinishMsgData:Data? + private var queue:[OutgoingFileTransfer]=[] + private var currentTransfer:OutgoingFileTransfer? + public var delegate:OutboundNearbyConnectionDelegate? + private var totalBytesToSend:Int64=0 + private var totalBytesSent:Int64=0 + private var cancelled:Bool=false + private var textPayloadID:Int64=0 + + enum State{ + case initial, sentUkeyClientInit, sentUkeyClientFinish, sentPairedKeyEncryption, sentPairedKeyResult, sentIntroduction, sendingFiles + } + + init(connection: NWConnection, id: String, urlsToSend:[URL]){ + self.urlsToSend=urlsToSend + super.init(connection: connection, id: id) + if urlsToSend.count==1 && !urlsToSend[0].isFileURL{ + textPayloadID=Int64.random(in: Int64.min...Int64.max) + } + } + + deinit { + if let transfer=currentTransfer, let handle=transfer.handle{ + try? handle.close() + } + for transfer in queue{ + if let handle=transfer.handle{ + try? handle.close() + } + } + } + + public func cancel(){ + cancelled=true + if encryptionDone{ + var cancel=Sharing_Nearby_Frame() + cancel.version = .v1 + cancel.v1=Sharing_Nearby_V1Frame() + cancel.v1.type = .cancel + try? sendTransferSetupFrame(cancel) + } + try? sendDisconnectionAndDisconnect() + } + + override func connectionReady() { + super.connectionReady() + do{ + try sendConnectionRequest() + try sendUkey2ClientInit() + }catch{ + lastError=error + protocolError() + } + } + + override func isServer() -> Bool { + return false + } + + override func processReceivedFrame(frameData: Data) { + do{ + #if DEBUG + print("received \(frameData), state is \(currentState)") + #endif + switch currentState { + case .initial: + protocolError() + case .sentUkeyClientInit: + try processUkey2ServerInit(frame: try Securegcm_Ukey2Message(serializedData: frameData), raw: frameData) + case .sentUkeyClientFinish: + try processConnectionResponse(frame: try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)) + default: + let smsg=try Securemessage_SecureMessage(serializedData: frameData) + try decryptAndProcessReceivedSecureMessage(smsg) + } + }catch{ + if case NearbyError.ukey2=error{ + }else if currentState == .sentUkeyClientInit{ + sendUkey2Alert(type: .badMessage) + } + lastError=error + protocolError() + } + } + + override func processTransferSetupFrame(_ frame: Sharing_Nearby_Frame) throws { + if frame.hasV1 && frame.v1.hasType, case .cancel = frame.v1.type { + print("Transfer canceled") + try sendDisconnectionAndDisconnect() + delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .userCanceled)) + return + } + print(frame) + switch currentState{ + case .sentPairedKeyEncryption: + try processPairedKeyEncryption(frame: frame) + case .sentPairedKeyResult: + try processPairedKeyResult(frame: frame) + case .sentIntroduction: + try processConsent(frame: frame) + case .sendingFiles: + break + default: + assertionFailure("Unexpected state \(currentState)") + } + } + + override func protocolError() { + super.protocolError() + delegate?.outboundConnection(connection: self, failedWithError: lastError!) + } + + private func sendConnectionRequest() throws { + var frame=Location_Nearby_Connections_OfflineFrame() + frame.version = .v1 + frame.v1=Location_Nearby_Connections_V1Frame() + frame.v1.type = .connectionRequest + frame.v1.connectionRequest=Location_Nearby_Connections_ConnectionRequestFrame() + frame.v1.connectionRequest.endpointID=String(bytes: NearbyConnectionManager.shared.endpointID, encoding: .ascii)! + frame.v1.connectionRequest.endpointName=Host.current().localizedName! + let endpointInfo=EndpointInfo(name: Host.current().localizedName!, deviceType: .computer) + frame.v1.connectionRequest.endpointInfo=endpointInfo.serialize() + frame.v1.connectionRequest.mediums=[.wifiLan] + sendFrameAsync(try frame.serializedData()) + } + + private func sendUkey2ClientInit() throws { + let domain=Domain.instance(curve: .EC256r1) + let (pubKey, privKey)=domain.makeKeyPair() + publicKey=pubKey + privateKey=privKey + + var finishFrame=Securegcm_Ukey2Message() + finishFrame.messageType = .clientFinish + var finish=Securegcm_Ukey2ClientFinished() + var pkey=Securemessage_GenericPublicKey() + pkey.type = .ecP256 + pkey.ecP256PublicKey=Securemessage_EcP256PublicKey() + pkey.ecP256PublicKey.x=Data(pubKey.w.x.asSignedBytes()) + pkey.ecP256PublicKey.y=Data(pubKey.w.y.asSignedBytes()) + finish.publicKey=try pkey.serializedData() + finishFrame.messageData=try finish.serializedData() + ukeyClientFinishMsgData=try finishFrame.serializedData() + + var frame=Securegcm_Ukey2Message() + frame.messageType = .clientInit + + var clientInit=Securegcm_Ukey2ClientInit() + clientInit.version=1 + clientInit.random=Data.randomData(length: 32) + clientInit.nextProtocol="AES_256_CBC-HMAC_SHA256" + var sha=SHA512() + sha.update(data: ukeyClientFinishMsgData!) + var commitment=Securegcm_Ukey2ClientInit.CipherCommitment() + commitment.commitment=Data(sha.finalize()) + commitment.handshakeCipher = .p256Sha512 + clientInit.cipherCommitments.append(commitment) + frame.messageData=try clientInit.serializedData() + + ukeyClientInitMsgData=try frame.serializedData() + sendFrameAsync(ukeyClientInitMsgData!) + currentState = .sentUkeyClientInit + } + + private func processUkey2ServerInit(frame:Securegcm_Ukey2Message, raw:Data) throws{ + ukeyServerInitMsgData=raw + guard frame.messageType == .serverInit else{ + sendUkey2Alert(type: .badMessageType) + throw NearbyError.ukey2 + } + let serverInit=try Securegcm_Ukey2ServerInit(serializedData: frame.messageData) + guard serverInit.version==1 else{ + sendUkey2Alert(type: .badVersion) + throw NearbyError.ukey2 + } + guard serverInit.random.count==32 else{ + sendUkey2Alert(type: .badRandom) + throw NearbyError.ukey2 + } + guard serverInit.handshakeCipher == .p256Sha512 else{ + sendUkey2Alert(type: .badHandshakeCipher) + throw NearbyError.ukey2 + } + + let serverKey=try Securemessage_GenericPublicKey(serializedData: serverInit.publicKey) + try finalizeKeyExchange(peerKey: serverKey) + sendFrameAsync(ukeyClientFinishMsgData!) + currentState = .sentUkeyClientFinish + + var resp=Location_Nearby_Connections_OfflineFrame() + resp.version = .v1 + resp.v1=Location_Nearby_Connections_V1Frame() + resp.v1.type = .connectionResponse + resp.v1.connectionResponse=Location_Nearby_Connections_ConnectionResponseFrame() + resp.v1.connectionResponse.response = .accept + resp.v1.connectionResponse.status=0 + resp.v1.connectionResponse.osInfo=Location_Nearby_Connections_OsInfo() + resp.v1.connectionResponse.osInfo.type = .apple + sendFrameAsync(try resp.serializedData()) + + encryptionDone=true + delegate?.outboundConnectionWasEstablished(connection: self) + } + + private func processConnectionResponse(frame:Location_Nearby_Connections_OfflineFrame) throws{ + #if DEBUG + print("connection response: \(frame)") + #endif + guard frame.version == .v1 else {throw NearbyError.protocolError("Unexpected offline frame version \(frame.version)")} + guard frame.v1.type == .connectionResponse else {throw NearbyError.protocolError("Unexpected frame type \(frame.v1.type)")} + guard frame.v1.connectionResponse.response == .accept else {throw NearbyError.protocolError("Connection was rejected by recipient")} + + var pairedEncryption=Sharing_Nearby_Frame() + pairedEncryption.version = .v1 + pairedEncryption.v1=Sharing_Nearby_V1Frame() + pairedEncryption.v1.type = .pairedKeyEncryption + pairedEncryption.v1.pairedKeyEncryption=Sharing_Nearby_PairedKeyEncryptionFrame() + pairedEncryption.v1.pairedKeyEncryption.secretIDHash=Data.randomData(length: 6) + pairedEncryption.v1.pairedKeyEncryption.signedData=Data.randomData(length: 72) + try sendTransferSetupFrame(pairedEncryption) + + currentState = .sentPairedKeyEncryption + } + + private func processPairedKeyEncryption(frame:Sharing_Nearby_Frame) throws{ + guard frame.hasV1, frame.v1.hasPairedKeyEncryption else { throw NearbyError.requiredFieldMissing("sharingNearbyFrame.v1.pairedKeyEncryption") } + var pairedResult=Sharing_Nearby_Frame() + pairedResult.version = .v1 + pairedResult.v1=Sharing_Nearby_V1Frame() + pairedResult.v1.type = .pairedKeyResult + pairedResult.v1.pairedKeyResult=Sharing_Nearby_PairedKeyResultFrame() + pairedResult.v1.pairedKeyResult.status = .unable + try sendTransferSetupFrame(pairedResult) + currentState = .sentPairedKeyResult + } + + private func processPairedKeyResult(frame:Sharing_Nearby_Frame) throws{ + guard frame.hasV1, frame.v1.hasPairedKeyResult else { throw NearbyError.requiredFieldMissing("sharingNearbyFrame.v1.pairedKeyResult") } + + var introduction=Sharing_Nearby_Frame() + introduction.version = .v1 + introduction.v1.type = .introduction + if urlsToSend.count==1 && !urlsToSend[0].isFileURL{ + var meta=Sharing_Nearby_TextMetadata() + meta.type = .url + meta.textTitle=urlsToSend[0].host ?? "URL" + meta.size=Int64(urlsToSend[0].absoluteString.utf8.count) + meta.payloadID=textPayloadID + introduction.v1.introduction.textMetadata.append(meta) + }else{ + for url in urlsToSend{ + guard url.isFileURL else {continue} + var meta=Sharing_Nearby_FileMetadata() + meta.name=OutboundNearbyConnection.sanitizeFileName(name: url.lastPathComponent) + let attrs=try FileManager.default.attributesOfItem(atPath: url.path) + meta.size=(attrs[FileAttributeKey.size] as! NSNumber).int64Value + let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier + meta.mimeType="application/octet-stream" + if let typeID=typeID{ + if #available(macOS 11.0, *){ + let type=UTType(typeID) + if let type=type, let mimeType=type.preferredMIMEType{ + meta.mimeType=mimeType + } + }else{ + if let mimeType=UTTypeCopyPreferredTagWithClass(typeID as CFString, kUTTagClassMIMEType){ + meta.mimeType=(mimeType.takeRetainedValue() as NSString) as String + } + } + } + if meta.mimeType.starts(with: "image/"){ + meta.type = .image + }else if meta.mimeType.starts(with: "video/"){ + meta.type = .video + }else if(meta.mimeType.starts(with: "audio/")){ + meta.type = .audio + }else if(url.pathExtension.lowercased()=="apk"){ + meta.type = .app + }else{ + meta.type = .unknown + } + meta.payloadID=Int64.random(in: Int64.min...Int64.max) + queue.append(OutgoingFileTransfer(url: url, payloadID: meta.payloadID, handle: try FileHandle(forReadingFrom: url), totalBytes: meta.size, currentOffset: 0)) + introduction.v1.introduction.fileMetadata.append(meta) + totalBytesToSend+=meta.size + } + } + #if DEBUG + print("sent introduction: \(introduction)") + #endif + try sendTransferSetupFrame(introduction) + + currentState = .sentIntroduction + } + + private func processConsent(frame:Sharing_Nearby_Frame) throws{ + guard frame.version == .v1, frame.v1.type == .response else {throw NearbyError.requiredFieldMissing("sharingNearbyFrame.v1.type==response")} + switch frame.v1.connectionResponse.status{ + case .accept: + currentState = .sendingFiles + delegate?.outboundConnectionTransferAccepted(connection: self) + if urlsToSend.count==1 && !urlsToSend[0].isFileURL{ + try sendURL() + }else{ + try sendNextFileChunk() + } + case .reject, .unknown: + delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .userRejected)) + try sendDisconnectionAndDisconnect() + case .notEnoughSpace: + delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .notEnoughSpace)) + try sendDisconnectionAndDisconnect() + case .timedOut: + delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .timedOut)) + try sendDisconnectionAndDisconnect() + case .unsupportedAttachmentType: + delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .unsupportedType)) + try sendDisconnectionAndDisconnect() + } + } + + private func sendURL() throws{ + try sendBytesPayload(data: Data(urlsToSend[0].absoluteString.utf8), id: textPayloadID) + delegate?.outboundConnectionTransferFinished(connection: self) + try sendDisconnectionAndDisconnect() + } + + private func sendNextFileChunk() throws{ + if cancelled{ + return + } + if currentTransfer==nil || currentTransfer?.currentOffset==currentTransfer?.totalBytes{ + if currentTransfer != nil && currentTransfer?.handle != nil{ + try currentTransfer?.handle?.close() + } + if queue.isEmpty{ + #if DEBUG + print("Disconnecting because all files have been transferred") + #endif + try sendDisconnectionAndDisconnect() + delegate?.outboundConnectionTransferFinished(connection: self) + return + } + currentTransfer=queue.removeFirst() + } + + let fileBuffer:Data + if #available(macOS 10.15.4, *) { + guard let _fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{ + throw NearbyError.inputOutput + } + fileBuffer=_fileBuffer + } else { + fileBuffer=currentTransfer!.handle!.readData(ofLength: 512*1024) + } + + var transfer=Location_Nearby_Connections_PayloadTransferFrame() + transfer.packetType = .data + transfer.payloadChunk.offset=currentTransfer!.currentOffset + transfer.payloadChunk.flags=0 + transfer.payloadChunk.body=fileBuffer + transfer.payloadHeader.id=currentTransfer!.payloadID + transfer.payloadHeader.type = .file + transfer.payloadHeader.totalSize=Int64(currentTransfer!.totalBytes) + transfer.payloadHeader.isSensitive=false + currentTransfer!.currentOffset+=Int64(fileBuffer.count) + + var wrapper=Location_Nearby_Connections_OfflineFrame() + wrapper.version = .v1 + wrapper.v1=Location_Nearby_Connections_V1Frame() + wrapper.v1.type = .payloadTransfer + wrapper.v1.payloadTransfer=transfer + try encryptAndSendOfflineFrame(wrapper, completion: { + do{ + try self.sendNextFileChunk() + }catch{ + self.lastError=error + self.protocolError() + } + }) + #if DEBUG + print("sent file chunk, current transfer: \(String(describing: currentTransfer))") + #endif + totalBytesSent+=Int64(fileBuffer.count) + delegate?.outboundConnection(connection: self, transferProgress: Double(totalBytesSent)/Double(totalBytesToSend)) + + if currentTransfer!.currentOffset==currentTransfer!.totalBytes{ + // Signal end of file (yes, all this for one bit) + var transfer=Location_Nearby_Connections_PayloadTransferFrame() + transfer.packetType = .data + transfer.payloadChunk.offset=currentTransfer!.currentOffset + transfer.payloadChunk.flags=1 // <- this one here + transfer.payloadHeader.id=currentTransfer!.payloadID + transfer.payloadHeader.type = .file + transfer.payloadHeader.totalSize=Int64(currentTransfer!.totalBytes) + transfer.payloadHeader.isSensitive=false + + var wrapper=Location_Nearby_Connections_OfflineFrame() + wrapper.version = .v1 + wrapper.v1=Location_Nearby_Connections_V1Frame() + wrapper.v1.type = .payloadTransfer + wrapper.v1.payloadTransfer=transfer + try encryptAndSendOfflineFrame(wrapper) + #if DEBUG + print("sent EOF, current transfer: \(String(describing: currentTransfer))") + #endif + } + } + + private static func sanitizeFileName(name:String)->String{ + return name.replacingOccurrences(of: "[\\/\\\\?%\\*:\\|\"<>=]", with: "_", options: .regularExpression) + } +} + +fileprivate struct OutgoingFileTransfer{ + let url:URL + let payloadID:Int64 + let handle:FileHandle? + let totalBytes:Int64 + var currentOffset:Int64 +} + +protocol OutboundNearbyConnectionDelegate{ + func outboundConnectionWasEstablished(connection:OutboundNearbyConnection) + func outboundConnection(connection:OutboundNearbyConnection, transferProgress:Double) + func outboundConnectionTransferAccepted(connection:OutboundNearbyConnection) + func outboundConnection(connection:OutboundNearbyConnection, failedWithError:Error) + func outboundConnectionTransferFinished(connection:OutboundNearbyConnection) +} diff --git a/submissions/sapphire/Nearby/ShareViewController.swift b/submissions/sapphire/Nearby/ShareViewController.swift new file mode 100644 index 00000000..ff3682d1 --- /dev/null +++ b/submissions/sapphire/Nearby/ShareViewController.swift @@ -0,0 +1,262 @@ +// +// ShareViewController.swift +// ShareExtension +// +// Created by Grishka on 12.09.2023. +// + +import Foundation +import Cocoa +import NearbyShare +import QuickLookThumbnailing // <-- IMPORT ADDED + +class ShareViewController: NSViewController, ShareExtensionDelegate { + + private var urls: [URL] = [] + private var foundDevices: [RemoteDeviceInfo] = [] + private var chosenDevice: RemoteDeviceInfo? + private var lastError: Error? + + @IBOutlet var filesIcon: NSImageView? + @IBOutlet var filesLabel: NSTextField? + @IBOutlet var loadingOverlay: NSStackView? + @IBOutlet var largeProgress: NSProgressIndicator? + @IBOutlet var listView: NSCollectionView? + @IBOutlet var listViewWrapper: NSView? + @IBOutlet var contentWrap: NSView? + @IBOutlet var progressView: NSView? + @IBOutlet var progressDeviceIcon: NSImageView? + @IBOutlet var progressDeviceName: NSTextField? + @IBOutlet var progressProgressBar: NSProgressIndicator? + @IBOutlet var progressState: NSTextField? + @IBOutlet var progressDeviceIconWrap: NSView? + @IBOutlet var progressDeviceSecondaryIcon: NSImageView? + + override var nibName: NSNib.Name? { + return NSNib.Name("ShareViewController") + } + + override func loadView() { + super.loadView() + + let item = self.extensionContext!.inputItems[0] as! NSExtensionItem + if let attachments = item.attachments { + for attachment in attachments as NSArray { + let provider = attachment as! NSItemProvider + // Use public.url and public.file-url for broader compatibility + let typeURL = "public.url" + let typeFileURL = "public.file-url" + + provider.loadItem(forTypeIdentifier: typeURL, options: nil) { data, err in + self.handleAttachment(data: data, error: err, total: attachments.count) + } + provider.loadItem(forTypeIdentifier: typeFileURL, options: nil) { data, err in + self.handleAttachment(data: data, error: err, total: attachments.count) + } + } + } else { + cancelRequest() + return + } + + contentWrap!.addSubview(listViewWrapper!) + contentWrap!.addSubview(loadingOverlay!) + contentWrap!.addSubview(progressView!) + progressView!.isHidden = true + + listViewWrapper!.translatesAutoresizingMaskIntoConstraints = false + loadingOverlay!.translatesAutoresizingMaskIntoConstraints = false + progressView!.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + listViewWrapper!.widthAnchor.constraint(equalTo: contentWrap!.widthAnchor), + listViewWrapper!.heightAnchor.constraint(equalTo: contentWrap!.heightAnchor), + loadingOverlay!.widthAnchor.constraint(equalTo: contentWrap!.widthAnchor), + loadingOverlay!.centerYAnchor.constraint(equalTo: contentWrap!.centerYAnchor), + progressView!.widthAnchor.constraint(equalTo: contentWrap!.widthAnchor), + progressView!.centerYAnchor.constraint(equalTo: contentWrap!.centerYAnchor) + ]) + + largeProgress!.startAnimation(nil) + let flowLayout = NSCollectionViewFlowLayout() + flowLayout.itemSize = NSSize(width: 75, height: 90) + flowLayout.sectionInset = NSEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) + flowLayout.minimumInteritemSpacing = 10 + flowLayout.minimumLineSpacing = 10 + listView!.collectionViewLayout = flowLayout + listView!.dataSource = self + + progressDeviceIconWrap!.wantsLayer = true + progressDeviceIconWrap!.layer!.masksToBounds = false + } + + private func handleAttachment(data: NSSecureCoding?, error: Error?, total: Int) { + if let url = data as? URL { + DispatchQueue.main.async { + if !self.urls.contains(url) { + self.urls.append(url) + if self.urls.count == total { + self.urlsReady() + } + } + } + } + } + + override func viewDidLoad() { + super.viewDidLoad() + NearbyConnectionManager.shared.startDeviceDiscovery() + NearbyConnectionManager.shared.addShareExtensionDelegate(self) + } + + override func viewWillDisappear() { + if chosenDevice == nil { + NearbyConnectionManager.shared.stopDeviceDiscovery() + } + NearbyConnectionManager.shared.removeShareExtensionDelegate(self) + } + + @IBAction func cancel(_ sender: AnyObject?) { + if let device = chosenDevice { + NearbyConnectionManager.shared.cancelOutgoingTransfer(id: device.id!) + } + cancelRequest() + } + + private func cancelRequest() { + let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) + self.extensionContext!.cancelRequest(withError: cancelError) + } + + private func urlsReady() { + for url in urls { + if url.isFileURL { + var isDirectory: ObjCBool = false + if FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory) && isDirectory.boolValue { + cancelRequest() + return + } + } + } + + if urls.count == 1 { + let url = urls[0] + if url.isFileURL { + filesLabel!.stringValue = url.lastPathComponent + generateThumbnail(for: url) { [weak self] image in + self?.filesIcon?.image = image ?? NSWorkspace.shared.icon(forFile: url.path) + } + } else if ["http", "https"].contains(url.scheme) { + filesLabel!.stringValue = url.absoluteString + filesIcon!.image = NSImage(named: NSImage.networkName) + } + } else { + filesLabel!.stringValue = String.localizedStringWithFormat(NSLocalizedString("NFiles", value: "%d files", comment: ""), urls.count) + filesIcon!.image = NSImage(named: NSImage.multipleDocumentsName) + } + } + + /// Generates a thumbnail for a given file URL. + private func generateThumbnail(for url: URL, completion: @escaping (NSImage?) -> Void) { + let size = CGSize(width: 128, height: 128) + let request = QLThumbnailGenerator.Request(fileAt: url, size: size, scale: view.window?.backingScaleFactor ?? 2.0, representationTypes: .all) + + QLThumbnailGenerator.shared.generateBestRepresentation(for: request) { thumbnail, error in + DispatchQueue.main.async { + completion(thumbnail?.nsImage) + } + } + } + + func addDevice(device: RemoteDeviceInfo) { + if foundDevices.isEmpty { loadingOverlay?.animator().isHidden = true } + foundDevices.append(device) + listView?.animator().insertItems(at: [[0, foundDevices.count - 1]]) + } + + func removeDevice(id: String) { + if chosenDevice != nil { return } + if let i = foundDevices.firstIndex(where: { $0.id == id }) { + foundDevices.remove(at: i) + listView?.animator().deleteItems(at: [[0, i]]) + } + if foundDevices.isEmpty { loadingOverlay?.animator().isHidden = false } + } + + func connectionWasEstablished(pinCode: String) { + progressState?.stringValue = String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [pinCode]) + progressProgressBar?.isIndeterminate = false + progressProgressBar?.maxValue = 1000 + progressProgressBar?.doubleValue = 0 + } + + func connectionFailed(with error: Error) { + progressProgressBar?.isIndeterminate = false; progressProgressBar?.maxValue = 1000; progressProgressBar?.doubleValue = 0 + lastError = error + if let ne = (error as? NearbyError), case let .canceled(reason) = ne { + switch reason { + case .userRejected: progressState?.stringValue = NSLocalizedString("TransferDeclined", value: "Declined", comment: "") + case .userCanceled: progressState?.stringValue = NSLocalizedString("TransferCanceled", value: "Canceled", comment: "") + case .notEnoughSpace: progressState?.stringValue = NSLocalizedString("NotEnoughSpace", value: "Not enough disk space", comment: "") + case .unsupportedType: progressState?.stringValue = NSLocalizedString("UnsupportedType", value: "Attachment type not supported", comment: "") + case .timedOut: progressState?.stringValue = NSLocalizedString("TransferTimedOut", value: "Timed out", comment: "") + } + progressDeviceSecondaryIcon?.isHidden = false + dismissDelayed() + } else { + let alert = NSAlert(error: error) + alert.beginSheetModal(for: view.window!) { _ in self.extensionContext!.cancelRequest(withError: error) } + } + } + + func transferAccepted() { progressState?.stringValue = NSLocalizedString("Sending", value: "Sending...", comment: "") } + func transferProgress(progress: Double) { progressProgressBar!.doubleValue = progress * progressProgressBar!.maxValue } + + func transferFinished() { + progressState?.stringValue = NSLocalizedString("TransferFinished", value: "Transfer finished", comment: "") + dismissDelayed() + } + + func selectDevice(device: RemoteDeviceInfo) { + NearbyConnectionManager.shared.stopDeviceDiscovery() + listViewWrapper?.animator().isHidden = true + progressView?.animator().isHidden = false + progressDeviceName?.stringValue = device.name + progressDeviceIcon?.image = imageForDeviceType(type: device.type) + progressProgressBar?.startAnimation(nil) + progressState?.stringValue = NSLocalizedString("Connecting", value: "Connecting...", comment: "") + chosenDevice = device + NearbyConnectionManager.shared.startOutgoingTransfer(deviceID: device.id!, delegate: self, urls: urls) + } + + private func dismissDelayed() { + DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { + if let error = self.lastError { self.extensionContext!.cancelRequest(withError: error) } + else { self.extensionContext!.completeRequest(returningItems: nil, completionHandler: nil) } + } + } +} + +fileprivate func imageForDeviceType(type: RemoteDeviceInfo.DeviceType) -> NSImage { + let imageName: String + switch type { + case .tablet: imageName = "com.apple.ipad" + case .computer: imageName = "com.apple.macbookpro-13-unibody" + default: imageName = "com.apple.iphone" + } + return NSImage(contentsOfFile: "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/\(imageName).icns")! +} + +extension ShareViewController: NSCollectionViewDataSource { + func numberOfSections(in collectionView: NSCollectionView) -> Int { return 1 } + func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { return foundDevices.count } + + func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { + let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DeviceListCell"), for: indexPath) + guard let collectionViewItem = item as? DeviceListCell else { return item } + let device = foundDevices[indexPath.item] + collectionViewItem.textField?.stringValue = device.name + collectionViewItem.imageView?.image = imageForDeviceType(type: device.type) + collectionViewItem.clickHandler = { self.selectDevice(device: device) } + return collectionViewItem + } +} diff --git a/submissions/sapphire/Nearby/TransferDirection.swift b/submissions/sapphire/Nearby/TransferDirection.swift new file mode 100644 index 00000000..4108a936 --- /dev/null +++ b/submissions/sapphire/Nearby/TransferDirection.swift @@ -0,0 +1,26 @@ +// +// TransferDirection.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-03. +// + +import Foundation + +public enum TransferDirection { + case incoming, outgoing +} + +public enum TransferState { + case waiting, inProgress, finished, failed, canceled +} + +public struct TransferProgressInfo: Identifiable, Equatable { + public let id: String + public var deviceName: String + public var fileDescription: String + public var direction: TransferDirection + public var state: TransferState = .waiting + public var progress: Double = 0.0 + public var iconName: String = "doc" +} diff --git a/submissions/sapphire/ObjC/Bridging-Header.h b/submissions/sapphire/ObjC/Bridging-Header.h new file mode 100644 index 00000000..8d8e26a6 --- /dev/null +++ b/submissions/sapphire/ObjC/Bridging-Header.h @@ -0,0 +1,11 @@ +// +// Bridging-Header.h +// Sapphire +// +// Created by Shariq Charolia on 2025-07-02. +// + +#import "NDNotificationCenterHackery.h" +#import +int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness); +int DisplayServicesSetBrightness(CGDirectDisplayID display, float brightness); diff --git a/submissions/sapphire/ObjC/NDNotificationCenterHackery.h b/submissions/sapphire/ObjC/NDNotificationCenterHackery.h new file mode 100644 index 00000000..0e264717 --- /dev/null +++ b/submissions/sapphire/ObjC/NDNotificationCenterHackery.h @@ -0,0 +1,24 @@ +// +// UNMutableNotificationContent.h +// Sapphire +// +// Created by Shariq Charolia on 2025-06-30. +// + + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UNMutableNotificationContent (NDPrivateAPIs) +@property BOOL hasDefaultAction; +@end + +@interface NDNotificationCenterHackery : NSObject + ++ (void)removeDefaultAction:(UNMutableNotificationContent*) content; + +@end + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/submissions/sapphire/ObjC/NDNotificationCenterHackery.m b/submissions/sapphire/ObjC/NDNotificationCenterHackery.m new file mode 100644 index 00000000..33ec2743 --- /dev/null +++ b/submissions/sapphire/ObjC/NDNotificationCenterHackery.m @@ -0,0 +1,18 @@ +// +// NDNotificationCenterHackery.m +// Sapphire +// +// Created by Shariq Charolia on 2025-06-30. +// + + +#import +#import "NDNotificationCenterHackery.h" + +@implementation NDNotificationCenterHackery + ++ (void)removeDefaultAction:(UNMutableNotificationContent*) content{ + content.hasDefaultAction = NO; +} + +@end \ No newline at end of file diff --git a/submissions/sapphire/ObjC/PrivateAPI.h b/submissions/sapphire/ObjC/PrivateAPI.h new file mode 100644 index 00000000..754c27e1 --- /dev/null +++ b/submissions/sapphire/ObjC/PrivateAPI.h @@ -0,0 +1,20 @@ +// +// PrivateAPI.h +// DynamicNotch +// + +#ifndef PrivateAPI_h +#define PrivateAPI_h + +#import +#import + +// This is the private function to disable the native macOS bezel HUDs +// for volume, brightness, etc. +void CGSSetBezelHUDEnabled(bool enabled); + +// These are private functions for getting and setting the keyboard backlight brightness. +void HIDPostRequest(uint32_t a, uint32_t b, uint32_t c); +uint32_t HIDGetRequest(uint32_t a, uint32_t b); + +#endif /* PrivateAPI_h */ diff --git a/submissions/sapphire/Protobuf-Inputs.xcfilelist b/submissions/sapphire/Protobuf-Inputs.xcfilelist new file mode 100644 index 00000000..f75fe5a8 --- /dev/null +++ b/submissions/sapphire/Protobuf-Inputs.xcfilelist @@ -0,0 +1,6 @@ +${SRCROOT}/Packages/NearbyShare/ProtobufSource/device_to_device_messages.proto +${SRCROOT}/Packages/NearbyShare/ProtobufSource/offline_wire_formats.proto +${SRCROOT}/Packages/NearbyShare/ProtobufSource/securegcm.proto +${SRCROOT}/Packages/NearbyShare/ProtobufSource/securemessage.proto +${SRCROOT}/Packages/NearbyShare/ProtobufSource/ukey.proto +${SRCROOT}/Packages/NearbyShare/ProtobufSource/wire_format.proto diff --git a/submissions/sapphire/Protobuf-Outputs.xcfilelist b/submissions/sapphire/Protobuf-Outputs.xcfilelist new file mode 100644 index 00000000..28fd0d5f --- /dev/null +++ b/submissions/sapphire/Protobuf-Outputs.xcfilelist @@ -0,0 +1,6 @@ +${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/device_to_device_messages.pb.swift +${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/offline_wire_formats.pb.swift +${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/securegcm.pb.swift +${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/securemessage.pb.swift +${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/ukey.pb.swift +${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/wire_format.pb.swift diff --git a/submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift b/submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift new file mode 100644 index 00000000..61ccd84b --- /dev/null +++ b/submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift @@ -0,0 +1,540 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: device_to_device_messages.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// Type of curve +enum Securegcm_Curve: SwiftProtobuf.Enum { + typealias RawValue = Int + case ed25519 // = 1 + + init() { + self = .ed25519 + } + + init?(rawValue: Int) { + switch rawValue { + case 1: self = .ed25519 + default: return nil + } + } + + var rawValue: Int { + switch self { + case .ed25519: return 1 + } + } + +} + +#if swift(>=4.2) + +extension Securegcm_Curve: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// Used by protocols between devices +struct Securegcm_DeviceToDeviceMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// the payload of the message + var message: Data { + get {return _message ?? Data()} + set {_message = newValue} + } + /// Returns true if `message` has been explicitly set. + var hasMessage: Bool {return self._message != nil} + /// Clears the value of `message`. Subsequent reads from it will return its default value. + mutating func clearMessage() {self._message = nil} + + /// the sequence number of the message - must be increasing. + var sequenceNumber: Int32 { + get {return _sequenceNumber ?? 0} + set {_sequenceNumber = newValue} + } + /// Returns true if `sequenceNumber` has been explicitly set. + var hasSequenceNumber: Bool {return self._sequenceNumber != nil} + /// Clears the value of `sequenceNumber`. Subsequent reads from it will return its default value. + mutating func clearSequenceNumber() {self._sequenceNumber = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _message: Data? = nil + fileprivate var _sequenceNumber: Int32? = nil +} + +/// sent as the first message from initiator to responder +/// in an unauthenticated Diffie-Hellman Key Exchange +struct Securegcm_InitiatorHello { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The session public key to send to the responder + var publicDhKey: Securemessage_GenericPublicKey { + get {return _publicDhKey ?? Securemessage_GenericPublicKey()} + set {_publicDhKey = newValue} + } + /// Returns true if `publicDhKey` has been explicitly set. + var hasPublicDhKey: Bool {return self._publicDhKey != nil} + /// Clears the value of `publicDhKey`. Subsequent reads from it will return its default value. + mutating func clearPublicDhKey() {self._publicDhKey = nil} + + /// The protocol version + var protocolVersion: Int32 { + get {return _protocolVersion ?? 0} + set {_protocolVersion = newValue} + } + /// Returns true if `protocolVersion` has been explicitly set. + var hasProtocolVersion: Bool {return self._protocolVersion != nil} + /// Clears the value of `protocolVersion`. Subsequent reads from it will return its default value. + mutating func clearProtocolVersion() {self._protocolVersion = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _publicDhKey: Securemessage_GenericPublicKey? = nil + fileprivate var _protocolVersion: Int32? = nil +} + +/// sent inside the header of the first message from the responder to the +/// initiator in an unauthenticated Diffie-Hellman Key Exchange +struct Securegcm_ResponderHello { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The session public key to send to the initiator + var publicDhKey: Securemessage_GenericPublicKey { + get {return _publicDhKey ?? Securemessage_GenericPublicKey()} + set {_publicDhKey = newValue} + } + /// Returns true if `publicDhKey` has been explicitly set. + var hasPublicDhKey: Bool {return self._publicDhKey != nil} + /// Clears the value of `publicDhKey`. Subsequent reads from it will return its default value. + mutating func clearPublicDhKey() {self._publicDhKey = nil} + + /// The protocol version + var protocolVersion: Int32 { + get {return _protocolVersion ?? 0} + set {_protocolVersion = newValue} + } + /// Returns true if `protocolVersion` has been explicitly set. + var hasProtocolVersion: Bool {return self._protocolVersion != nil} + /// Clears the value of `protocolVersion`. Subsequent reads from it will return its default value. + mutating func clearProtocolVersion() {self._protocolVersion = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _publicDhKey: Securemessage_GenericPublicKey? = nil + fileprivate var _protocolVersion: Int32? = nil +} + +/// A convenience proto for encoding curve points in affine representation +struct Securegcm_EcPoint { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var curve: Securegcm_Curve { + get {return _curve ?? .ed25519} + set {_curve = newValue} + } + /// Returns true if `curve` has been explicitly set. + var hasCurve: Bool {return self._curve != nil} + /// Clears the value of `curve`. Subsequent reads from it will return its default value. + mutating func clearCurve() {self._curve = nil} + + /// x and y are encoded in big-endian two's complement + /// client MUST verify (x,y) is a valid point on the specified curve + var x: Data { + get {return _x ?? Data()} + set {_x = newValue} + } + /// Returns true if `x` has been explicitly set. + var hasX: Bool {return self._x != nil} + /// Clears the value of `x`. Subsequent reads from it will return its default value. + mutating func clearX() {self._x = nil} + + var y: Data { + get {return _y ?? Data()} + set {_y = newValue} + } + /// Returns true if `y` has been explicitly set. + var hasY: Bool {return self._y != nil} + /// Clears the value of `y`. Subsequent reads from it will return its default value. + mutating func clearY() {self._y = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _curve: Securegcm_Curve? = nil + fileprivate var _x: Data? = nil + fileprivate var _y: Data? = nil +} + +struct Securegcm_SpakeHandshakeMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Each flow in the protocol bumps this counter + var flowNumber: Int32 { + get {return _flowNumber ?? 0} + set {_flowNumber = newValue} + } + /// Returns true if `flowNumber` has been explicitly set. + var hasFlowNumber: Bool {return self._flowNumber != nil} + /// Clears the value of `flowNumber`. Subsequent reads from it will return its default value. + mutating func clearFlowNumber() {self._flowNumber = nil} + + /// Some (but not all) SPAKE flows send a point on an elliptic curve + var ecPoint: Securegcm_EcPoint { + get {return _ecPoint ?? Securegcm_EcPoint()} + set {_ecPoint = newValue} + } + /// Returns true if `ecPoint` has been explicitly set. + var hasEcPoint: Bool {return self._ecPoint != nil} + /// Clears the value of `ecPoint`. Subsequent reads from it will return its default value. + mutating func clearEcPoint() {self._ecPoint = nil} + + /// Some (but not all) SPAKE flows send a hash value + var hashValue_p: Data { + get {return _hashValue_p ?? Data()} + set {_hashValue_p = newValue} + } + /// Returns true if `hashValue_p` has been explicitly set. + var hasHashValue_p: Bool {return self._hashValue_p != nil} + /// Clears the value of `hashValue_p`. Subsequent reads from it will return its default value. + mutating func clearHashValue_p() {self._hashValue_p = nil} + + /// The last flow of a SPAKE protocol can send an optional payload, + /// since the key exchange is already complete on the sender's side. + var payload: Data { + get {return _payload ?? Data()} + set {_payload = newValue} + } + /// Returns true if `payload` has been explicitly set. + var hasPayload: Bool {return self._payload != nil} + /// Clears the value of `payload`. Subsequent reads from it will return its default value. + mutating func clearPayload() {self._payload = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _flowNumber: Int32? = nil + fileprivate var _ecPoint: Securegcm_EcPoint? = nil + fileprivate var _hashValue_p: Data? = nil + fileprivate var _payload: Data? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Securegcm_Curve: @unchecked Sendable {} +extension Securegcm_DeviceToDeviceMessage: @unchecked Sendable {} +extension Securegcm_InitiatorHello: @unchecked Sendable {} +extension Securegcm_ResponderHello: @unchecked Sendable {} +extension Securegcm_EcPoint: @unchecked Sendable {} +extension Securegcm_SpakeHandshakeMessage: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "securegcm" + +extension Securegcm_Curve: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "ED_25519"), + ] +} + +extension Securegcm_DeviceToDeviceMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".DeviceToDeviceMessage" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "message"), + 2: .standard(proto: "sequence_number"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._message) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._sequenceNumber) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._message { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._sequenceNumber { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_DeviceToDeviceMessage, rhs: Securegcm_DeviceToDeviceMessage) -> Bool { + if lhs._message != rhs._message {return false} + if lhs._sequenceNumber != rhs._sequenceNumber {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_InitiatorHello: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".InitiatorHello" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "public_dh_key"), + 2: .standard(proto: "protocol_version"), + ] + + public var isInitialized: Bool { + if let v = self._publicDhKey, !v.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._publicDhKey) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._protocolVersion) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._publicDhKey { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = self._protocolVersion { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_InitiatorHello, rhs: Securegcm_InitiatorHello) -> Bool { + if lhs._publicDhKey != rhs._publicDhKey {return false} + if lhs._protocolVersion != rhs._protocolVersion {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_ResponderHello: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".ResponderHello" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "public_dh_key"), + 2: .standard(proto: "protocol_version"), + ] + + public var isInitialized: Bool { + if let v = self._publicDhKey, !v.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._publicDhKey) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._protocolVersion) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._publicDhKey { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = self._protocolVersion { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_ResponderHello, rhs: Securegcm_ResponderHello) -> Bool { + if lhs._publicDhKey != rhs._publicDhKey {return false} + if lhs._protocolVersion != rhs._protocolVersion {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_EcPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".EcPoint" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "curve"), + 2: .same(proto: "x"), + 3: .same(proto: "y"), + ] + + public var isInitialized: Bool { + if self._curve == nil {return false} + if self._x == nil {return false} + if self._y == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._curve) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._x) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._y) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._curve { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._x { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try { if let v = self._y { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_EcPoint, rhs: Securegcm_EcPoint) -> Bool { + if lhs._curve != rhs._curve {return false} + if lhs._x != rhs._x {return false} + if lhs._y != rhs._y {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_SpakeHandshakeMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".SpakeHandshakeMessage" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "flow_number"), + 2: .standard(proto: "ec_point"), + 3: .standard(proto: "hash_value"), + 4: .same(proto: "payload"), + ] + + public var isInitialized: Bool { + if let v = self._ecPoint, !v.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._flowNumber) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._ecPoint) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._hashValue_p) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self._payload) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._flowNumber { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._ecPoint { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = self._hashValue_p { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try { if let v = self._payload { + try visitor.visitSingularBytesField(value: v, fieldNumber: 4) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_SpakeHandshakeMessage, rhs: Securegcm_SpakeHandshakeMessage) -> Bool { + if lhs._flowNumber != rhs._flowNumber {return false} + if lhs._ecPoint != rhs._ecPoint {return false} + if lhs._hashValue_p != rhs._hashValue_p {return false} + if lhs._payload != rhs._payload {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift b/submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift new file mode 100644 index 00000000..7524b1ce --- /dev/null +++ b/submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift @@ -0,0 +1,3653 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: offline_wire_formats.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +struct Location_Nearby_Connections_OfflineFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var version: Location_Nearby_Connections_OfflineFrame.Version { + get {return _version ?? .unknownVersion} + set {_version = newValue} + } + /// Returns true if `version` has been explicitly set. + var hasVersion: Bool {return self._version != nil} + /// Clears the value of `version`. Subsequent reads from it will return its default value. + mutating func clearVersion() {self._version = nil} + + /// Right now there's only 1 version, but if there are more, exactly one of + /// the following fields will be set. + var v1: Location_Nearby_Connections_V1Frame { + get {return _v1 ?? Location_Nearby_Connections_V1Frame()} + set {_v1 = newValue} + } + /// Returns true if `v1` has been explicitly set. + var hasV1: Bool {return self._v1 != nil} + /// Clears the value of `v1`. Subsequent reads from it will return its default value. + mutating func clearV1() {self._v1 = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum Version: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownVersion // = 0 + case v1 // = 1 + + init() { + self = .unknownVersion + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownVersion + case 1: self = .v1 + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownVersion: return 0 + case .v1: return 1 + } + } + + } + + init() {} + + fileprivate var _version: Location_Nearby_Connections_OfflineFrame.Version? = nil + fileprivate var _v1: Location_Nearby_Connections_V1Frame? = nil +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_OfflineFrame.Version: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Location_Nearby_Connections_V1Frame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var type: Location_Nearby_Connections_V1Frame.FrameType { + get {return _storage._type ?? .unknownFrameType} + set {_uniqueStorage()._type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return _storage._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {_uniqueStorage()._type = nil} + + /// Exactly one of the following fields will be set. + var connectionRequest: Location_Nearby_Connections_ConnectionRequestFrame { + get {return _storage._connectionRequest ?? Location_Nearby_Connections_ConnectionRequestFrame()} + set {_uniqueStorage()._connectionRequest = newValue} + } + /// Returns true if `connectionRequest` has been explicitly set. + var hasConnectionRequest: Bool {return _storage._connectionRequest != nil} + /// Clears the value of `connectionRequest`. Subsequent reads from it will return its default value. + mutating func clearConnectionRequest() {_uniqueStorage()._connectionRequest = nil} + + var connectionResponse: Location_Nearby_Connections_ConnectionResponseFrame { + get {return _storage._connectionResponse ?? Location_Nearby_Connections_ConnectionResponseFrame()} + set {_uniqueStorage()._connectionResponse = newValue} + } + /// Returns true if `connectionResponse` has been explicitly set. + var hasConnectionResponse: Bool {return _storage._connectionResponse != nil} + /// Clears the value of `connectionResponse`. Subsequent reads from it will return its default value. + mutating func clearConnectionResponse() {_uniqueStorage()._connectionResponse = nil} + + var payloadTransfer: Location_Nearby_Connections_PayloadTransferFrame { + get {return _storage._payloadTransfer ?? Location_Nearby_Connections_PayloadTransferFrame()} + set {_uniqueStorage()._payloadTransfer = newValue} + } + /// Returns true if `payloadTransfer` has been explicitly set. + var hasPayloadTransfer: Bool {return _storage._payloadTransfer != nil} + /// Clears the value of `payloadTransfer`. Subsequent reads from it will return its default value. + mutating func clearPayloadTransfer() {_uniqueStorage()._payloadTransfer = nil} + + var bandwidthUpgradeNegotiation: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame { + get {return _storage._bandwidthUpgradeNegotiation ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame()} + set {_uniqueStorage()._bandwidthUpgradeNegotiation = newValue} + } + /// Returns true if `bandwidthUpgradeNegotiation` has been explicitly set. + var hasBandwidthUpgradeNegotiation: Bool {return _storage._bandwidthUpgradeNegotiation != nil} + /// Clears the value of `bandwidthUpgradeNegotiation`. Subsequent reads from it will return its default value. + mutating func clearBandwidthUpgradeNegotiation() {_uniqueStorage()._bandwidthUpgradeNegotiation = nil} + + var keepAlive: Location_Nearby_Connections_KeepAliveFrame { + get {return _storage._keepAlive ?? Location_Nearby_Connections_KeepAliveFrame()} + set {_uniqueStorage()._keepAlive = newValue} + } + /// Returns true if `keepAlive` has been explicitly set. + var hasKeepAlive: Bool {return _storage._keepAlive != nil} + /// Clears the value of `keepAlive`. Subsequent reads from it will return its default value. + mutating func clearKeepAlive() {_uniqueStorage()._keepAlive = nil} + + var disconnection: Location_Nearby_Connections_DisconnectionFrame { + get {return _storage._disconnection ?? Location_Nearby_Connections_DisconnectionFrame()} + set {_uniqueStorage()._disconnection = newValue} + } + /// Returns true if `disconnection` has been explicitly set. + var hasDisconnection: Bool {return _storage._disconnection != nil} + /// Clears the value of `disconnection`. Subsequent reads from it will return its default value. + mutating func clearDisconnection() {_uniqueStorage()._disconnection = nil} + + var pairedKeyEncryption: Location_Nearby_Connections_PairedKeyEncryptionFrame { + get {return _storage._pairedKeyEncryption ?? Location_Nearby_Connections_PairedKeyEncryptionFrame()} + set {_uniqueStorage()._pairedKeyEncryption = newValue} + } + /// Returns true if `pairedKeyEncryption` has been explicitly set. + var hasPairedKeyEncryption: Bool {return _storage._pairedKeyEncryption != nil} + /// Clears the value of `pairedKeyEncryption`. Subsequent reads from it will return its default value. + mutating func clearPairedKeyEncryption() {_uniqueStorage()._pairedKeyEncryption = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum FrameType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownFrameType // = 0 + case connectionRequest // = 1 + case connectionResponse // = 2 + case payloadTransfer // = 3 + case bandwidthUpgradeNegotiation // = 4 + case keepAlive // = 5 + case disconnection // = 6 + case pairedKeyEncryption // = 7 + + init() { + self = .unknownFrameType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownFrameType + case 1: self = .connectionRequest + case 2: self = .connectionResponse + case 3: self = .payloadTransfer + case 4: self = .bandwidthUpgradeNegotiation + case 5: self = .keepAlive + case 6: self = .disconnection + case 7: self = .pairedKeyEncryption + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownFrameType: return 0 + case .connectionRequest: return 1 + case .connectionResponse: return 2 + case .payloadTransfer: return 3 + case .bandwidthUpgradeNegotiation: return 4 + case .keepAlive: return 5 + case .disconnection: return 6 + case .pairedKeyEncryption: return 7 + } + } + + } + + init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_V1Frame.FrameType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Location_Nearby_Connections_ConnectionRequestFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var endpointID: String { + get {return _storage._endpointID ?? String()} + set {_uniqueStorage()._endpointID = newValue} + } + /// Returns true if `endpointID` has been explicitly set. + var hasEndpointID: Bool {return _storage._endpointID != nil} + /// Clears the value of `endpointID`. Subsequent reads from it will return its default value. + mutating func clearEndpointID() {_uniqueStorage()._endpointID = nil} + + var endpointName: String { + get {return _storage._endpointName ?? String()} + set {_uniqueStorage()._endpointName = newValue} + } + /// Returns true if `endpointName` has been explicitly set. + var hasEndpointName: Bool {return _storage._endpointName != nil} + /// Clears the value of `endpointName`. Subsequent reads from it will return its default value. + mutating func clearEndpointName() {_uniqueStorage()._endpointName = nil} + + var handshakeData: Data { + get {return _storage._handshakeData ?? Data()} + set {_uniqueStorage()._handshakeData = newValue} + } + /// Returns true if `handshakeData` has been explicitly set. + var hasHandshakeData: Bool {return _storage._handshakeData != nil} + /// Clears the value of `handshakeData`. Subsequent reads from it will return its default value. + mutating func clearHandshakeData() {_uniqueStorage()._handshakeData = nil} + + /// A random number generated for each outgoing connection that is presently + /// used to act as a tiebreaker when 2 devices connect to each other + /// simultaneously; this can also be used for other initialization-scoped + /// things in the future. + var nonce: Int32 { + get {return _storage._nonce ?? 0} + set {_uniqueStorage()._nonce = newValue} + } + /// Returns true if `nonce` has been explicitly set. + var hasNonce: Bool {return _storage._nonce != nil} + /// Clears the value of `nonce`. Subsequent reads from it will return its default value. + mutating func clearNonce() {_uniqueStorage()._nonce = nil} + + /// The mediums this device supports upgrading to. This list should be filtered + /// by both the strategy and this device's individual limitations. + var mediums: [Location_Nearby_Connections_ConnectionRequestFrame.Medium] { + get {return _storage._mediums} + set {_uniqueStorage()._mediums = newValue} + } + + var endpointInfo: Data { + get {return _storage._endpointInfo ?? Data()} + set {_uniqueStorage()._endpointInfo = newValue} + } + /// Returns true if `endpointInfo` has been explicitly set. + var hasEndpointInfo: Bool {return _storage._endpointInfo != nil} + /// Clears the value of `endpointInfo`. Subsequent reads from it will return its default value. + mutating func clearEndpointInfo() {_uniqueStorage()._endpointInfo = nil} + + var mediumMetadata: Location_Nearby_Connections_MediumMetadata { + get {return _storage._mediumMetadata ?? Location_Nearby_Connections_MediumMetadata()} + set {_uniqueStorage()._mediumMetadata = newValue} + } + /// Returns true if `mediumMetadata` has been explicitly set. + var hasMediumMetadata: Bool {return _storage._mediumMetadata != nil} + /// Clears the value of `mediumMetadata`. Subsequent reads from it will return its default value. + mutating func clearMediumMetadata() {_uniqueStorage()._mediumMetadata = nil} + + var keepAliveIntervalMillis: Int32 { + get {return _storage._keepAliveIntervalMillis ?? 0} + set {_uniqueStorage()._keepAliveIntervalMillis = newValue} + } + /// Returns true if `keepAliveIntervalMillis` has been explicitly set. + var hasKeepAliveIntervalMillis: Bool {return _storage._keepAliveIntervalMillis != nil} + /// Clears the value of `keepAliveIntervalMillis`. Subsequent reads from it will return its default value. + mutating func clearKeepAliveIntervalMillis() {_uniqueStorage()._keepAliveIntervalMillis = nil} + + var keepAliveTimeoutMillis: Int32 { + get {return _storage._keepAliveTimeoutMillis ?? 0} + set {_uniqueStorage()._keepAliveTimeoutMillis = newValue} + } + /// Returns true if `keepAliveTimeoutMillis` has been explicitly set. + var hasKeepAliveTimeoutMillis: Bool {return _storage._keepAliveTimeoutMillis != nil} + /// Clears the value of `keepAliveTimeoutMillis`. Subsequent reads from it will return its default value. + mutating func clearKeepAliveTimeoutMillis() {_uniqueStorage()._keepAliveTimeoutMillis = nil} + + /// The type of {@link Device} object. + var deviceType: Int32 { + get {return _storage._deviceType ?? 0} + set {_uniqueStorage()._deviceType = newValue} + } + /// Returns true if `deviceType` has been explicitly set. + var hasDeviceType: Bool {return _storage._deviceType != nil} + /// Clears the value of `deviceType`. Subsequent reads from it will return its default value. + mutating func clearDeviceType() {_uniqueStorage()._deviceType = nil} + + /// The bytes of serialized {@link Device} object. + var deviceInfo: Data { + get {return _storage._deviceInfo ?? Data()} + set {_uniqueStorage()._deviceInfo = newValue} + } + /// Returns true if `deviceInfo` has been explicitly set. + var hasDeviceInfo: Bool {return _storage._deviceInfo != nil} + /// Clears the value of `deviceInfo`. Subsequent reads from it will return its default value. + mutating func clearDeviceInfo() {_uniqueStorage()._deviceInfo = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Should always match cs/symbol:location.nearby.proto.connections.Medium + /// LINT.IfChange + enum Medium: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownMedium // = 0 + case mdns // = 1 + case bluetooth // = 2 + case wifiHotspot // = 3 + case ble // = 4 + case wifiLan // = 5 + case wifiAware // = 6 + case nfc // = 7 + case wifiDirect // = 8 + case webRtc // = 9 + case bleL2Cap // = 10 + case usb // = 11 + + init() { + self = .unknownMedium + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownMedium + case 1: self = .mdns + case 2: self = .bluetooth + case 3: self = .wifiHotspot + case 4: self = .ble + case 5: self = .wifiLan + case 6: self = .wifiAware + case 7: self = .nfc + case 8: self = .wifiDirect + case 9: self = .webRtc + case 10: self = .bleL2Cap + case 11: self = .usb + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownMedium: return 0 + case .mdns: return 1 + case .bluetooth: return 2 + case .wifiHotspot: return 3 + case .ble: return 4 + case .wifiLan: return 5 + case .wifiAware: return 6 + case .nfc: return 7 + case .wifiDirect: return 8 + case .webRtc: return 9 + case .bleL2Cap: return 10 + case .usb: return 11 + } + } + + } + + init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_ConnectionRequestFrame.Medium: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// This doesn't need to send back endpoint_id and endpoint_name (like +/// the ConnectionRequestFrame does) because those have already been +/// transmitted out-of-band, at the time this endpoint was discovered. +struct Location_Nearby_Connections_ConnectionResponseFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// One of: + /// + /// - ConnectionsStatusCodes.STATUS_OK + /// - ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED. + var status: Int32 { + get {return _status ?? 0} + set {_status = newValue} + } + /// Returns true if `status` has been explicitly set. + var hasStatus: Bool {return self._status != nil} + /// Clears the value of `status`. Subsequent reads from it will return its default value. + mutating func clearStatus() {self._status = nil} + + var handshakeData: Data { + get {return _handshakeData ?? Data()} + set {_handshakeData = newValue} + } + /// Returns true if `handshakeData` has been explicitly set. + var hasHandshakeData: Bool {return self._handshakeData != nil} + /// Clears the value of `handshakeData`. Subsequent reads from it will return its default value. + mutating func clearHandshakeData() {self._handshakeData = nil} + + var response: Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus { + get {return _response ?? .unknownResponseStatus} + set {_response = newValue} + } + /// Returns true if `response` has been explicitly set. + var hasResponse: Bool {return self._response != nil} + /// Clears the value of `response`. Subsequent reads from it will return its default value. + mutating func clearResponse() {self._response = nil} + + var osInfo: Location_Nearby_Connections_OsInfo { + get {return _osInfo ?? Location_Nearby_Connections_OsInfo()} + set {_osInfo = newValue} + } + /// Returns true if `osInfo` has been explicitly set. + var hasOsInfo: Bool {return self._osInfo != nil} + /// Clears the value of `osInfo`. Subsequent reads from it will return its default value. + mutating func clearOsInfo() {self._osInfo = nil} + + /// A bitmask value to indicate which medium supports Multiplex transmission + /// feature. Each supporting medium could utilize one bit starting from the + /// least significant bit in this field. eq. BT utilizes the LSB bit which 0x01 + /// means bt supports multiplex while 0x00 means not. Refer to ClientProxy.java + /// for the bit usages. + var multiplexSocketBitmask: Int32 { + get {return _multiplexSocketBitmask ?? 0} + set {_multiplexSocketBitmask = newValue} + } + /// Returns true if `multiplexSocketBitmask` has been explicitly set. + var hasMultiplexSocketBitmask: Bool {return self._multiplexSocketBitmask != nil} + /// Clears the value of `multiplexSocketBitmask`. Subsequent reads from it will return its default value. + mutating func clearMultiplexSocketBitmask() {self._multiplexSocketBitmask = nil} + + var nearbyConnectionsVersion: Int32 { + get {return _nearbyConnectionsVersion ?? 0} + set {_nearbyConnectionsVersion = newValue} + } + /// Returns true if `nearbyConnectionsVersion` has been explicitly set. + var hasNearbyConnectionsVersion: Bool {return self._nearbyConnectionsVersion != nil} + /// Clears the value of `nearbyConnectionsVersion`. Subsequent reads from it will return its default value. + mutating func clearNearbyConnectionsVersion() {self._nearbyConnectionsVersion = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Used to replace the status integer parameter with a meaningful enum item. + /// Map ConnectionsStatusCodes.STATUS_OK to ACCEPT and + /// ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED to REJECT. + /// Flag: connection_replace_status_with_response_connectionResponseFrame + enum ResponseStatus: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownResponseStatus // = 0 + case accept // = 1 + case reject // = 2 + + init() { + self = .unknownResponseStatus + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownResponseStatus + case 1: self = .accept + case 2: self = .reject + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownResponseStatus: return 0 + case .accept: return 1 + case .reject: return 2 + } + } + + } + + init() {} + + fileprivate var _status: Int32? = nil + fileprivate var _handshakeData: Data? = nil + fileprivate var _response: Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus? = nil + fileprivate var _osInfo: Location_Nearby_Connections_OsInfo? = nil + fileprivate var _multiplexSocketBitmask: Int32? = nil + fileprivate var _nearbyConnectionsVersion: Int32? = nil +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Location_Nearby_Connections_PayloadTransferFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var packetType: Location_Nearby_Connections_PayloadTransferFrame.PacketType { + get {return _packetType ?? .unknownPacketType} + set {_packetType = newValue} + } + /// Returns true if `packetType` has been explicitly set. + var hasPacketType: Bool {return self._packetType != nil} + /// Clears the value of `packetType`. Subsequent reads from it will return its default value. + mutating func clearPacketType() {self._packetType = nil} + + var payloadHeader: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader { + get {return _payloadHeader ?? Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader()} + set {_payloadHeader = newValue} + } + /// Returns true if `payloadHeader` has been explicitly set. + var hasPayloadHeader: Bool {return self._payloadHeader != nil} + /// Clears the value of `payloadHeader`. Subsequent reads from it will return its default value. + mutating func clearPayloadHeader() {self._payloadHeader = nil} + + /// Exactly one of the following fields will be set, depending on the type. + var payloadChunk: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk { + get {return _payloadChunk ?? Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk()} + set {_payloadChunk = newValue} + } + /// Returns true if `payloadChunk` has been explicitly set. + var hasPayloadChunk: Bool {return self._payloadChunk != nil} + /// Clears the value of `payloadChunk`. Subsequent reads from it will return its default value. + mutating func clearPayloadChunk() {self._payloadChunk = nil} + + var controlMessage: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage { + get {return _controlMessage ?? Location_Nearby_Connections_PayloadTransferFrame.ControlMessage()} + set {_controlMessage = newValue} + } + /// Returns true if `controlMessage` has been explicitly set. + var hasControlMessage: Bool {return self._controlMessage != nil} + /// Clears the value of `controlMessage`. Subsequent reads from it will return its default value. + mutating func clearControlMessage() {self._controlMessage = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum PacketType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownPacketType // = 0 + case data // = 1 + case control // = 2 + + init() { + self = .unknownPacketType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownPacketType + case 1: self = .data + case 2: self = .control + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownPacketType: return 0 + case .data: return 1 + case .control: return 2 + } + } + + } + + struct PayloadHeader { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var id: Int64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + var type: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType { + get {return _type ?? .unknownPayloadType} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + var totalSize: Int64 { + get {return _totalSize ?? 0} + set {_totalSize = newValue} + } + /// Returns true if `totalSize` has been explicitly set. + var hasTotalSize: Bool {return self._totalSize != nil} + /// Clears the value of `totalSize`. Subsequent reads from it will return its default value. + mutating func clearTotalSize() {self._totalSize = nil} + + var isSensitive: Bool { + get {return _isSensitive ?? false} + set {_isSensitive = newValue} + } + /// Returns true if `isSensitive` has been explicitly set. + var hasIsSensitive: Bool {return self._isSensitive != nil} + /// Clears the value of `isSensitive`. Subsequent reads from it will return its default value. + mutating func clearIsSensitive() {self._isSensitive = nil} + + var fileName: String { + get {return _fileName ?? String()} + set {_fileName = newValue} + } + /// Returns true if `fileName` has been explicitly set. + var hasFileName: Bool {return self._fileName != nil} + /// Clears the value of `fileName`. Subsequent reads from it will return its default value. + mutating func clearFileName() {self._fileName = nil} + + var parentFolder: String { + get {return _parentFolder ?? String()} + set {_parentFolder = newValue} + } + /// Returns true if `parentFolder` has been explicitly set. + var hasParentFolder: Bool {return self._parentFolder != nil} + /// Clears the value of `parentFolder`. Subsequent reads from it will return its default value. + mutating func clearParentFolder() {self._parentFolder = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum PayloadType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownPayloadType // = 0 + case bytes // = 1 + case file // = 2 + case stream // = 3 + + init() { + self = .unknownPayloadType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownPayloadType + case 1: self = .bytes + case 2: self = .file + case 3: self = .stream + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownPayloadType: return 0 + case .bytes: return 1 + case .file: return 2 + case .stream: return 3 + } + } + + } + + init() {} + + fileprivate var _id: Int64? = nil + fileprivate var _type: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType? = nil + fileprivate var _totalSize: Int64? = nil + fileprivate var _isSensitive: Bool? = nil + fileprivate var _fileName: String? = nil + fileprivate var _parentFolder: String? = nil + } + + /// Accompanies DATA packets. + struct PayloadChunk { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var flags: Int32 { + get {return _flags ?? 0} + set {_flags = newValue} + } + /// Returns true if `flags` has been explicitly set. + var hasFlags: Bool {return self._flags != nil} + /// Clears the value of `flags`. Subsequent reads from it will return its default value. + mutating func clearFlags() {self._flags = nil} + + var offset: Int64 { + get {return _offset ?? 0} + set {_offset = newValue} + } + /// Returns true if `offset` has been explicitly set. + var hasOffset: Bool {return self._offset != nil} + /// Clears the value of `offset`. Subsequent reads from it will return its default value. + mutating func clearOffset() {self._offset = nil} + + var body: Data { + get {return _body ?? Data()} + set {_body = newValue} + } + /// Returns true if `body` has been explicitly set. + var hasBody: Bool {return self._body != nil} + /// Clears the value of `body`. Subsequent reads from it will return its default value. + mutating func clearBody() {self._body = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum Flags: SwiftProtobuf.Enum { + typealias RawValue = Int + case lastChunk // = 1 + + init() { + self = .lastChunk + } + + init?(rawValue: Int) { + switch rawValue { + case 1: self = .lastChunk + default: return nil + } + } + + var rawValue: Int { + switch self { + case .lastChunk: return 1 + } + } + + } + + init() {} + + fileprivate var _flags: Int32? = nil + fileprivate var _offset: Int64? = nil + fileprivate var _body: Data? = nil + } + + /// Accompanies CONTROL packets. + struct ControlMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var event: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType { + get {return _event ?? .unknownEventType} + set {_event = newValue} + } + /// Returns true if `event` has been explicitly set. + var hasEvent: Bool {return self._event != nil} + /// Clears the value of `event`. Subsequent reads from it will return its default value. + mutating func clearEvent() {self._event = nil} + + var offset: Int64 { + get {return _offset ?? 0} + set {_offset = newValue} + } + /// Returns true if `offset` has been explicitly set. + var hasOffset: Bool {return self._offset != nil} + /// Clears the value of `offset`. Subsequent reads from it will return its default value. + mutating func clearOffset() {self._offset = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum EventType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownEventType // = 0 + case payloadError // = 1 + case payloadCanceled // = 2 + case payloadReceivedAck // = 3 + + init() { + self = .unknownEventType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownEventType + case 1: self = .payloadError + case 2: self = .payloadCanceled + case 3: self = .payloadReceivedAck + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownEventType: return 0 + case .payloadError: return 1 + case .payloadCanceled: return 2 + case .payloadReceivedAck: return 3 + } + } + + } + + init() {} + + fileprivate var _event: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType? = nil + fileprivate var _offset: Int64? = nil + } + + init() {} + + fileprivate var _packetType: Location_Nearby_Connections_PayloadTransferFrame.PacketType? = nil + fileprivate var _payloadHeader: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader? = nil + fileprivate var _payloadChunk: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk? = nil + fileprivate var _controlMessage: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage? = nil +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_PayloadTransferFrame.PacketType: CaseIterable { + // Support synthesized by the compiler. +} + +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType: CaseIterable { + // Support synthesized by the compiler. +} + +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk.Flags: CaseIterable { + // Support synthesized by the compiler. +} + +extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var eventType: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType { + get {return _eventType ?? .unknownEventType} + set {_eventType = newValue} + } + /// Returns true if `eventType` has been explicitly set. + var hasEventType: Bool {return self._eventType != nil} + /// Clears the value of `eventType`. Subsequent reads from it will return its default value. + mutating func clearEventType() {self._eventType = nil} + + /// Exactly one of the following fields will be set. + var upgradePathInfo: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo { + get {return _upgradePathInfo ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo()} + set {_upgradePathInfo = newValue} + } + /// Returns true if `upgradePathInfo` has been explicitly set. + var hasUpgradePathInfo: Bool {return self._upgradePathInfo != nil} + /// Clears the value of `upgradePathInfo`. Subsequent reads from it will return its default value. + mutating func clearUpgradePathInfo() {self._upgradePathInfo = nil} + + var clientIntroduction: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction { + get {return _clientIntroduction ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction()} + set {_clientIntroduction = newValue} + } + /// Returns true if `clientIntroduction` has been explicitly set. + var hasClientIntroduction: Bool {return self._clientIntroduction != nil} + /// Clears the value of `clientIntroduction`. Subsequent reads from it will return its default value. + mutating func clearClientIntroduction() {self._clientIntroduction = nil} + + var clientIntroductionAck: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck { + get {return _clientIntroductionAck ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck()} + set {_clientIntroductionAck = newValue} + } + /// Returns true if `clientIntroductionAck` has been explicitly set. + var hasClientIntroductionAck: Bool {return self._clientIntroductionAck != nil} + /// Clears the value of `clientIntroductionAck`. Subsequent reads from it will return its default value. + mutating func clearClientIntroductionAck() {self._clientIntroductionAck = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum EventType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownEventType // = 0 + case upgradePathAvailable // = 1 + case lastWriteToPriorChannel // = 2 + case safeToClosePriorChannel // = 3 + case clientIntroduction // = 4 + case upgradeFailure // = 5 + case clientIntroductionAck // = 6 + + init() { + self = .unknownEventType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownEventType + case 1: self = .upgradePathAvailable + case 2: self = .lastWriteToPriorChannel + case 3: self = .safeToClosePriorChannel + case 4: self = .clientIntroduction + case 5: self = .upgradeFailure + case 6: self = .clientIntroductionAck + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownEventType: return 0 + case .upgradePathAvailable: return 1 + case .lastWriteToPriorChannel: return 2 + case .safeToClosePriorChannel: return 3 + case .clientIntroduction: return 4 + case .upgradeFailure: return 5 + case .clientIntroductionAck: return 6 + } + } + + } + + /// Accompanies UPGRADE_PATH_AVAILABLE and UPGRADE_FAILURE events. + struct UpgradePathInfo { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var medium: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium { + get {return _storage._medium ?? .unknownMedium} + set {_uniqueStorage()._medium = newValue} + } + /// Returns true if `medium` has been explicitly set. + var hasMedium: Bool {return _storage._medium != nil} + /// Clears the value of `medium`. Subsequent reads from it will return its default value. + mutating func clearMedium() {_uniqueStorage()._medium = nil} + + /// Exactly one of the following fields will be set. + var wifiHotspotCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials { + get {return _storage._wifiHotspotCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials()} + set {_uniqueStorage()._wifiHotspotCredentials = newValue} + } + /// Returns true if `wifiHotspotCredentials` has been explicitly set. + var hasWifiHotspotCredentials: Bool {return _storage._wifiHotspotCredentials != nil} + /// Clears the value of `wifiHotspotCredentials`. Subsequent reads from it will return its default value. + mutating func clearWifiHotspotCredentials() {_uniqueStorage()._wifiHotspotCredentials = nil} + + var wifiLanSocket: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket { + get {return _storage._wifiLanSocket ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket()} + set {_uniqueStorage()._wifiLanSocket = newValue} + } + /// Returns true if `wifiLanSocket` has been explicitly set. + var hasWifiLanSocket: Bool {return _storage._wifiLanSocket != nil} + /// Clears the value of `wifiLanSocket`. Subsequent reads from it will return its default value. + mutating func clearWifiLanSocket() {_uniqueStorage()._wifiLanSocket = nil} + + var bluetoothCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials { + get {return _storage._bluetoothCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials()} + set {_uniqueStorage()._bluetoothCredentials = newValue} + } + /// Returns true if `bluetoothCredentials` has been explicitly set. + var hasBluetoothCredentials: Bool {return _storage._bluetoothCredentials != nil} + /// Clears the value of `bluetoothCredentials`. Subsequent reads from it will return its default value. + mutating func clearBluetoothCredentials() {_uniqueStorage()._bluetoothCredentials = nil} + + var wifiAwareCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials { + get {return _storage._wifiAwareCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials()} + set {_uniqueStorage()._wifiAwareCredentials = newValue} + } + /// Returns true if `wifiAwareCredentials` has been explicitly set. + var hasWifiAwareCredentials: Bool {return _storage._wifiAwareCredentials != nil} + /// Clears the value of `wifiAwareCredentials`. Subsequent reads from it will return its default value. + mutating func clearWifiAwareCredentials() {_uniqueStorage()._wifiAwareCredentials = nil} + + var wifiDirectCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials { + get {return _storage._wifiDirectCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials()} + set {_uniqueStorage()._wifiDirectCredentials = newValue} + } + /// Returns true if `wifiDirectCredentials` has been explicitly set. + var hasWifiDirectCredentials: Bool {return _storage._wifiDirectCredentials != nil} + /// Clears the value of `wifiDirectCredentials`. Subsequent reads from it will return its default value. + mutating func clearWifiDirectCredentials() {_uniqueStorage()._wifiDirectCredentials = nil} + + var webRtcCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials { + get {return _storage._webRtcCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials()} + set {_uniqueStorage()._webRtcCredentials = newValue} + } + /// Returns true if `webRtcCredentials` has been explicitly set. + var hasWebRtcCredentials: Bool {return _storage._webRtcCredentials != nil} + /// Clears the value of `webRtcCredentials`. Subsequent reads from it will return its default value. + mutating func clearWebRtcCredentials() {_uniqueStorage()._webRtcCredentials = nil} + + /// Disable Encryption for this upgrade medium to improve throughput. + var supportsDisablingEncryption: Bool { + get {return _storage._supportsDisablingEncryption ?? false} + set {_uniqueStorage()._supportsDisablingEncryption = newValue} + } + /// Returns true if `supportsDisablingEncryption` has been explicitly set. + var hasSupportsDisablingEncryption: Bool {return _storage._supportsDisablingEncryption != nil} + /// Clears the value of `supportsDisablingEncryption`. Subsequent reads from it will return its default value. + mutating func clearSupportsDisablingEncryption() {_uniqueStorage()._supportsDisablingEncryption = nil} + + /// An ack will be sent after the CLIENT_INTRODUCTION frame. + var supportsClientIntroductionAck: Bool { + get {return _storage._supportsClientIntroductionAck ?? false} + set {_uniqueStorage()._supportsClientIntroductionAck = newValue} + } + /// Returns true if `supportsClientIntroductionAck` has been explicitly set. + var hasSupportsClientIntroductionAck: Bool {return _storage._supportsClientIntroductionAck != nil} + /// Clears the value of `supportsClientIntroductionAck`. Subsequent reads from it will return its default value. + mutating func clearSupportsClientIntroductionAck() {_uniqueStorage()._supportsClientIntroductionAck = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// Should always match cs/symbol:location.nearby.proto.connections.Medium + enum Medium: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownMedium // = 0 + case mdns // = 1 + case bluetooth // = 2 + case wifiHotspot // = 3 + case ble // = 4 + case wifiLan // = 5 + case wifiAware // = 6 + case nfc // = 7 + case wifiDirect // = 8 + case webRtc // = 9 + + /// 10 is reserved. + case usb // = 11 + + init() { + self = .unknownMedium + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownMedium + case 1: self = .mdns + case 2: self = .bluetooth + case 3: self = .wifiHotspot + case 4: self = .ble + case 5: self = .wifiLan + case 6: self = .wifiAware + case 7: self = .nfc + case 8: self = .wifiDirect + case 9: self = .webRtc + case 11: self = .usb + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownMedium: return 0 + case .mdns: return 1 + case .bluetooth: return 2 + case .wifiHotspot: return 3 + case .ble: return 4 + case .wifiLan: return 5 + case .wifiAware: return 6 + case .nfc: return 7 + case .wifiDirect: return 8 + case .webRtc: return 9 + case .usb: return 11 + } + } + + } + + /// Accompanies Medium.WIFI_HOTSPOT. + struct WifiHotspotCredentials { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var ssid: String { + get {return _ssid ?? String()} + set {_ssid = newValue} + } + /// Returns true if `ssid` has been explicitly set. + var hasSsid: Bool {return self._ssid != nil} + /// Clears the value of `ssid`. Subsequent reads from it will return its default value. + mutating func clearSsid() {self._ssid = nil} + + var password: String { + get {return _password ?? String()} + set {_password = newValue} + } + /// Returns true if `password` has been explicitly set. + var hasPassword: Bool {return self._password != nil} + /// Clears the value of `password`. Subsequent reads from it will return its default value. + mutating func clearPassword() {self._password = nil} + + var port: Int32 { + get {return _port ?? 0} + set {_port = newValue} + } + /// Returns true if `port` has been explicitly set. + var hasPort: Bool {return self._port != nil} + /// Clears the value of `port`. Subsequent reads from it will return its default value. + mutating func clearPort() {self._port = nil} + + var gateway: String { + get {return _gateway ?? "0.0.0.0"} + set {_gateway = newValue} + } + /// Returns true if `gateway` has been explicitly set. + var hasGateway: Bool {return self._gateway != nil} + /// Clears the value of `gateway`. Subsequent reads from it will return its default value. + mutating func clearGateway() {self._gateway = nil} + + /// This field can be a band or frequency + var frequency: Int32 { + get {return _frequency ?? -1} + set {_frequency = newValue} + } + /// Returns true if `frequency` has been explicitly set. + var hasFrequency: Bool {return self._frequency != nil} + /// Clears the value of `frequency`. Subsequent reads from it will return its default value. + mutating func clearFrequency() {self._frequency = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _ssid: String? = nil + fileprivate var _password: String? = nil + fileprivate var _port: Int32? = nil + fileprivate var _gateway: String? = nil + fileprivate var _frequency: Int32? = nil + } + + /// Accompanies Medium.WIFI_LAN. + struct WifiLanSocket { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var ipAddress: Data { + get {return _ipAddress ?? Data()} + set {_ipAddress = newValue} + } + /// Returns true if `ipAddress` has been explicitly set. + var hasIpAddress: Bool {return self._ipAddress != nil} + /// Clears the value of `ipAddress`. Subsequent reads from it will return its default value. + mutating func clearIpAddress() {self._ipAddress = nil} + + var wifiPort: Int32 { + get {return _wifiPort ?? 0} + set {_wifiPort = newValue} + } + /// Returns true if `wifiPort` has been explicitly set. + var hasWifiPort: Bool {return self._wifiPort != nil} + /// Clears the value of `wifiPort`. Subsequent reads from it will return its default value. + mutating func clearWifiPort() {self._wifiPort = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _ipAddress: Data? = nil + fileprivate var _wifiPort: Int32? = nil + } + + /// Accompanies Medium.BLUETOOTH. + struct BluetoothCredentials { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var serviceName: String { + get {return _serviceName ?? String()} + set {_serviceName = newValue} + } + /// Returns true if `serviceName` has been explicitly set. + var hasServiceName: Bool {return self._serviceName != nil} + /// Clears the value of `serviceName`. Subsequent reads from it will return its default value. + mutating func clearServiceName() {self._serviceName = nil} + + var macAddress: String { + get {return _macAddress ?? String()} + set {_macAddress = newValue} + } + /// Returns true if `macAddress` has been explicitly set. + var hasMacAddress: Bool {return self._macAddress != nil} + /// Clears the value of `macAddress`. Subsequent reads from it will return its default value. + mutating func clearMacAddress() {self._macAddress = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _serviceName: String? = nil + fileprivate var _macAddress: String? = nil + } + + /// Accompanies Medium.WIFI_AWARE. + struct WifiAwareCredentials { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var serviceID: String { + get {return _serviceID ?? String()} + set {_serviceID = newValue} + } + /// Returns true if `serviceID` has been explicitly set. + var hasServiceID: Bool {return self._serviceID != nil} + /// Clears the value of `serviceID`. Subsequent reads from it will return its default value. + mutating func clearServiceID() {self._serviceID = nil} + + var serviceInfo: Data { + get {return _serviceInfo ?? Data()} + set {_serviceInfo = newValue} + } + /// Returns true if `serviceInfo` has been explicitly set. + var hasServiceInfo: Bool {return self._serviceInfo != nil} + /// Clears the value of `serviceInfo`. Subsequent reads from it will return its default value. + mutating func clearServiceInfo() {self._serviceInfo = nil} + + var password: String { + get {return _password ?? String()} + set {_password = newValue} + } + /// Returns true if `password` has been explicitly set. + var hasPassword: Bool {return self._password != nil} + /// Clears the value of `password`. Subsequent reads from it will return its default value. + mutating func clearPassword() {self._password = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _serviceID: String? = nil + fileprivate var _serviceInfo: Data? = nil + fileprivate var _password: String? = nil + } + + /// Accompanies Medium.WIFI_DIRECT. + struct WifiDirectCredentials { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var ssid: String { + get {return _ssid ?? String()} + set {_ssid = newValue} + } + /// Returns true if `ssid` has been explicitly set. + var hasSsid: Bool {return self._ssid != nil} + /// Clears the value of `ssid`. Subsequent reads from it will return its default value. + mutating func clearSsid() {self._ssid = nil} + + var password: String { + get {return _password ?? String()} + set {_password = newValue} + } + /// Returns true if `password` has been explicitly set. + var hasPassword: Bool {return self._password != nil} + /// Clears the value of `password`. Subsequent reads from it will return its default value. + mutating func clearPassword() {self._password = nil} + + var port: Int32 { + get {return _port ?? 0} + set {_port = newValue} + } + /// Returns true if `port` has been explicitly set. + var hasPort: Bool {return self._port != nil} + /// Clears the value of `port`. Subsequent reads from it will return its default value. + mutating func clearPort() {self._port = nil} + + var frequency: Int32 { + get {return _frequency ?? 0} + set {_frequency = newValue} + } + /// Returns true if `frequency` has been explicitly set. + var hasFrequency: Bool {return self._frequency != nil} + /// Clears the value of `frequency`. Subsequent reads from it will return its default value. + mutating func clearFrequency() {self._frequency = nil} + + var gateway: String { + get {return _gateway ?? "0.0.0.0"} + set {_gateway = newValue} + } + /// Returns true if `gateway` has been explicitly set. + var hasGateway: Bool {return self._gateway != nil} + /// Clears the value of `gateway`. Subsequent reads from it will return its default value. + mutating func clearGateway() {self._gateway = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _ssid: String? = nil + fileprivate var _password: String? = nil + fileprivate var _port: Int32? = nil + fileprivate var _frequency: Int32? = nil + fileprivate var _gateway: String? = nil + } + + /// Accompanies Medium.WEB_RTC + struct WebRtcCredentials { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var peerID: String { + get {return _peerID ?? String()} + set {_peerID = newValue} + } + /// Returns true if `peerID` has been explicitly set. + var hasPeerID: Bool {return self._peerID != nil} + /// Clears the value of `peerID`. Subsequent reads from it will return its default value. + mutating func clearPeerID() {self._peerID = nil} + + var locationHint: Location_Nearby_Connections_LocationHint { + get {return _locationHint ?? Location_Nearby_Connections_LocationHint()} + set {_locationHint = newValue} + } + /// Returns true if `locationHint` has been explicitly set. + var hasLocationHint: Bool {return self._locationHint != nil} + /// Clears the value of `locationHint`. Subsequent reads from it will return its default value. + mutating func clearLocationHint() {self._locationHint = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _peerID: String? = nil + fileprivate var _locationHint: Location_Nearby_Connections_LocationHint? = nil + } + + init() {} + + fileprivate var _storage = _StorageClass.defaultInstance + } + + /// Accompanies CLIENT_INTRODUCTION events. + struct ClientIntroduction { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var endpointID: String { + get {return _endpointID ?? String()} + set {_endpointID = newValue} + } + /// Returns true if `endpointID` has been explicitly set. + var hasEndpointID: Bool {return self._endpointID != nil} + /// Clears the value of `endpointID`. Subsequent reads from it will return its default value. + mutating func clearEndpointID() {self._endpointID = nil} + + var supportsDisablingEncryption: Bool { + get {return _supportsDisablingEncryption ?? false} + set {_supportsDisablingEncryption = newValue} + } + /// Returns true if `supportsDisablingEncryption` has been explicitly set. + var hasSupportsDisablingEncryption: Bool {return self._supportsDisablingEncryption != nil} + /// Clears the value of `supportsDisablingEncryption`. Subsequent reads from it will return its default value. + mutating func clearSupportsDisablingEncryption() {self._supportsDisablingEncryption = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _endpointID: String? = nil + fileprivate var _supportsDisablingEncryption: Bool? = nil + } + + /// Accompanies CLIENT_INTRODUCTION_ACK events. + struct ClientIntroductionAck { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + } + + init() {} + + fileprivate var _eventType: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType? = nil + fileprivate var _upgradePathInfo: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo? = nil + fileprivate var _clientIntroduction: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction? = nil + fileprivate var _clientIntroductionAck: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck? = nil +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType: CaseIterable { + // Support synthesized by the compiler. +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Location_Nearby_Connections_KeepAliveFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// And ack will be sent after receiving KEEP_ALIVE frame. + var ack: Bool { + get {return _ack ?? false} + set {_ack = newValue} + } + /// Returns true if `ack` has been explicitly set. + var hasAck: Bool {return self._ack != nil} + /// Clears the value of `ack`. Subsequent reads from it will return its default value. + mutating func clearAck() {self._ack = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _ack: Bool? = nil +} + +/// Informs the remote side to immediately severe the socket connection. +/// Used in bandwidth upgrades to get around a race condition, but may be used +/// in other situations to trigger a faster disconnection event than waiting for +/// socket closed on the remote side. +struct Location_Nearby_Connections_DisconnectionFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Apply safe-to-disconnect protocol if true. + var requestSafeToDisconnect: Bool { + get {return _requestSafeToDisconnect ?? false} + set {_requestSafeToDisconnect = newValue} + } + /// Returns true if `requestSafeToDisconnect` has been explicitly set. + var hasRequestSafeToDisconnect: Bool {return self._requestSafeToDisconnect != nil} + /// Clears the value of `requestSafeToDisconnect`. Subsequent reads from it will return its default value. + mutating func clearRequestSafeToDisconnect() {self._requestSafeToDisconnect = nil} + + /// Ack of receiving Disconnection frame will be sent to the sender + /// frame. + var ackSafeToDisconnect: Bool { + get {return _ackSafeToDisconnect ?? false} + set {_ackSafeToDisconnect = newValue} + } + /// Returns true if `ackSafeToDisconnect` has been explicitly set. + var hasAckSafeToDisconnect: Bool {return self._ackSafeToDisconnect != nil} + /// Clears the value of `ackSafeToDisconnect`. Subsequent reads from it will return its default value. + mutating func clearAckSafeToDisconnect() {self._ackSafeToDisconnect = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _requestSafeToDisconnect: Bool? = nil + fileprivate var _ackSafeToDisconnect: Bool? = nil +} + +/// A paired key encryption packet sent between devices, contains signed data. +struct Location_Nearby_Connections_PairedKeyEncryptionFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The encrypted data (raw authentication token for the established + /// connection) in byte array format. + var signedData: Data { + get {return _signedData ?? Data()} + set {_signedData = newValue} + } + /// Returns true if `signedData` has been explicitly set. + var hasSignedData: Bool {return self._signedData != nil} + /// Clears the value of `signedData`. Subsequent reads from it will return its default value. + mutating func clearSignedData() {self._signedData = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _signedData: Data? = nil +} + +struct Location_Nearby_Connections_MediumMetadata { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// True if local device supports 5GHz. + var supports5Ghz: Bool { + get {return _supports5Ghz ?? false} + set {_supports5Ghz = newValue} + } + /// Returns true if `supports5Ghz` has been explicitly set. + var hasSupports5Ghz: Bool {return self._supports5Ghz != nil} + /// Clears the value of `supports5Ghz`. Subsequent reads from it will return its default value. + mutating func clearSupports5Ghz() {self._supports5Ghz = nil} + + /// WiFi LAN BSSID, in the form of a six-byte MAC address: XX:XX:XX:XX:XX:XX + var bssid: String { + get {return _bssid ?? String()} + set {_bssid = newValue} + } + /// Returns true if `bssid` has been explicitly set. + var hasBssid: Bool {return self._bssid != nil} + /// Clears the value of `bssid`. Subsequent reads from it will return its default value. + mutating func clearBssid() {self._bssid = nil} + + /// IP address, in network byte order: the highest order byte of the address is + /// in byte[0]. + var ipAddress: Data { + get {return _ipAddress ?? Data()} + set {_ipAddress = newValue} + } + /// Returns true if `ipAddress` has been explicitly set. + var hasIpAddress: Bool {return self._ipAddress != nil} + /// Clears the value of `ipAddress`. Subsequent reads from it will return its default value. + mutating func clearIpAddress() {self._ipAddress = nil} + + /// True if local device supports 6GHz. + var supports6Ghz: Bool { + get {return _supports6Ghz ?? false} + set {_supports6Ghz = newValue} + } + /// Returns true if `supports6Ghz` has been explicitly set. + var hasSupports6Ghz: Bool {return self._supports6Ghz != nil} + /// Clears the value of `supports6Ghz`. Subsequent reads from it will return its default value. + mutating func clearSupports6Ghz() {self._supports6Ghz = nil} + + /// True if local device has mobile radio. + var mobileRadio: Bool { + get {return _mobileRadio ?? false} + set {_mobileRadio = newValue} + } + /// Returns true if `mobileRadio` has been explicitly set. + var hasMobileRadio: Bool {return self._mobileRadio != nil} + /// Clears the value of `mobileRadio`. Subsequent reads from it will return its default value. + mutating func clearMobileRadio() {self._mobileRadio = nil} + + /// The frequency of the WiFi LAN AP(in MHz). Or -1 is not associated with an + /// AP over WiFi, -2 represents the active network uses an Ethernet transport. + var apFrequency: Int32 { + get {return _apFrequency ?? -1} + set {_apFrequency = newValue} + } + /// Returns true if `apFrequency` has been explicitly set. + var hasApFrequency: Bool {return self._apFrequency != nil} + /// Clears the value of `apFrequency`. Subsequent reads from it will return its default value. + mutating func clearApFrequency() {self._apFrequency = nil} + + /// Available channels on the local device. + var availableChannels: Location_Nearby_Connections_AvailableChannels { + get {return _availableChannels ?? Location_Nearby_Connections_AvailableChannels()} + set {_availableChannels = newValue} + } + /// Returns true if `availableChannels` has been explicitly set. + var hasAvailableChannels: Bool {return self._availableChannels != nil} + /// Clears the value of `availableChannels`. Subsequent reads from it will return its default value. + mutating func clearAvailableChannels() {self._availableChannels = nil} + + /// Usable WiFi Direct client channels on the local device. + var wifiDirectCliUsableChannels: Location_Nearby_Connections_WifiDirectCliUsableChannels { + get {return _wifiDirectCliUsableChannels ?? Location_Nearby_Connections_WifiDirectCliUsableChannels()} + set {_wifiDirectCliUsableChannels = newValue} + } + /// Returns true if `wifiDirectCliUsableChannels` has been explicitly set. + var hasWifiDirectCliUsableChannels: Bool {return self._wifiDirectCliUsableChannels != nil} + /// Clears the value of `wifiDirectCliUsableChannels`. Subsequent reads from it will return its default value. + mutating func clearWifiDirectCliUsableChannels() {self._wifiDirectCliUsableChannels = nil} + + /// Usable WiFi LAN channels on the local device. + var wifiLanUsableChannels: Location_Nearby_Connections_WifiLanUsableChannels { + get {return _wifiLanUsableChannels ?? Location_Nearby_Connections_WifiLanUsableChannels()} + set {_wifiLanUsableChannels = newValue} + } + /// Returns true if `wifiLanUsableChannels` has been explicitly set. + var hasWifiLanUsableChannels: Bool {return self._wifiLanUsableChannels != nil} + /// Clears the value of `wifiLanUsableChannels`. Subsequent reads from it will return its default value. + mutating func clearWifiLanUsableChannels() {self._wifiLanUsableChannels = nil} + + /// Usable WiFi Aware channels on the local device. + var wifiAwareUsableChannels: Location_Nearby_Connections_WifiAwareUsableChannels { + get {return _wifiAwareUsableChannels ?? Location_Nearby_Connections_WifiAwareUsableChannels()} + set {_wifiAwareUsableChannels = newValue} + } + /// Returns true if `wifiAwareUsableChannels` has been explicitly set. + var hasWifiAwareUsableChannels: Bool {return self._wifiAwareUsableChannels != nil} + /// Clears the value of `wifiAwareUsableChannels`. Subsequent reads from it will return its default value. + mutating func clearWifiAwareUsableChannels() {self._wifiAwareUsableChannels = nil} + + /// Usable WiFi Hotspot STA channels on the local device. + var wifiHotspotStaUsableChannels: Location_Nearby_Connections_WifiHotspotStaUsableChannels { + get {return _wifiHotspotStaUsableChannels ?? Location_Nearby_Connections_WifiHotspotStaUsableChannels()} + set {_wifiHotspotStaUsableChannels = newValue} + } + /// Returns true if `wifiHotspotStaUsableChannels` has been explicitly set. + var hasWifiHotspotStaUsableChannels: Bool {return self._wifiHotspotStaUsableChannels != nil} + /// Clears the value of `wifiHotspotStaUsableChannels`. Subsequent reads from it will return its default value. + mutating func clearWifiHotspotStaUsableChannels() {self._wifiHotspotStaUsableChannels = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _supports5Ghz: Bool? = nil + fileprivate var _bssid: String? = nil + fileprivate var _ipAddress: Data? = nil + fileprivate var _supports6Ghz: Bool? = nil + fileprivate var _mobileRadio: Bool? = nil + fileprivate var _apFrequency: Int32? = nil + fileprivate var _availableChannels: Location_Nearby_Connections_AvailableChannels? = nil + fileprivate var _wifiDirectCliUsableChannels: Location_Nearby_Connections_WifiDirectCliUsableChannels? = nil + fileprivate var _wifiLanUsableChannels: Location_Nearby_Connections_WifiLanUsableChannels? = nil + fileprivate var _wifiAwareUsableChannels: Location_Nearby_Connections_WifiAwareUsableChannels? = nil + fileprivate var _wifiHotspotStaUsableChannels: Location_Nearby_Connections_WifiHotspotStaUsableChannels? = nil +} + +/// Available channels on the local device. +struct Location_Nearby_Connections_AvailableChannels { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var channels: [Int32] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// Usable WiFi Direct client channels on the local device. +struct Location_Nearby_Connections_WifiDirectCliUsableChannels { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var channels: [Int32] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// Usable WiFi LAN channels on the local device. +struct Location_Nearby_Connections_WifiLanUsableChannels { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var channels: [Int32] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// Usable WiFi Aware channels on the local device. +struct Location_Nearby_Connections_WifiAwareUsableChannels { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var channels: [Int32] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// Usable WiFi Hotspot STA channels on the local device. +struct Location_Nearby_Connections_WifiHotspotStaUsableChannels { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var channels: [Int32] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// LocationHint is used to specify a location as well as format. +struct Location_Nearby_Connections_LocationHint { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Location is the location, provided in the format specified by format. + var location: String { + get {return _location ?? String()} + set {_location = newValue} + } + /// Returns true if `location` has been explicitly set. + var hasLocation: Bool {return self._location != nil} + /// Clears the value of `location`. Subsequent reads from it will return its default value. + mutating func clearLocation() {self._location = nil} + + /// the format of location. + var format: Location_Nearby_Connections_LocationStandard.Format { + get {return _format ?? .unknown} + set {_format = newValue} + } + /// Returns true if `format` has been explicitly set. + var hasFormat: Bool {return self._format != nil} + /// Clears the value of `format`. Subsequent reads from it will return its default value. + mutating func clearFormat() {self._format = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _location: String? = nil + fileprivate var _format: Location_Nearby_Connections_LocationStandard.Format? = nil +} + +struct Location_Nearby_Connections_LocationStandard { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum Format: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknown // = 0 + + /// E164 country codes: + /// https://en.wikipedia.org/wiki/List_of_country_calling_codes + /// e.g. +1 for USA + case e164Calling // = 1 + + /// ISO 3166-1 alpha-2 country codes: + /// https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + case iso31661Alpha2 // = 2 + + init() { + self = .unknown + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .e164Calling + case 2: self = .iso31661Alpha2 + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknown: return 0 + case .e164Calling: return 1 + case .iso31661Alpha2: return 2 + } + } + + } + + init() {} +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_LocationStandard.Format: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// Device capability for OS information. +struct Location_Nearby_Connections_OsInfo { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var type: Location_Nearby_Connections_OsInfo.OsType { + get {return _type ?? .unknownOsType} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum OsType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownOsType // = 0 + case android // = 1 + case chromeOs // = 2 + case windows // = 3 + case apple // = 4 + + /// g3 test environment + case linux // = 100 + + init() { + self = .unknownOsType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownOsType + case 1: self = .android + case 2: self = .chromeOs + case 3: self = .windows + case 4: self = .apple + case 100: self = .linux + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownOsType: return 0 + case .android: return 1 + case .chromeOs: return 2 + case .windows: return 3 + case .apple: return 4 + case .linux: return 100 + } + } + + } + + init() {} + + fileprivate var _type: Location_Nearby_Connections_OsInfo.OsType? = nil +} + +#if swift(>=4.2) + +extension Location_Nearby_Connections_OsInfo.OsType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +#if swift(>=5.5) && canImport(_Concurrency) +extension Location_Nearby_Connections_OfflineFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_OfflineFrame.Version: @unchecked Sendable {} +extension Location_Nearby_Connections_V1Frame: @unchecked Sendable {} +extension Location_Nearby_Connections_V1Frame.FrameType: @unchecked Sendable {} +extension Location_Nearby_Connections_ConnectionRequestFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_ConnectionRequestFrame.Medium: @unchecked Sendable {} +extension Location_Nearby_Connections_ConnectionResponseFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame.PacketType: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk.Flags: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage: @unchecked Sendable {} +extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction: @unchecked Sendable {} +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck: @unchecked Sendable {} +extension Location_Nearby_Connections_KeepAliveFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_DisconnectionFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_PairedKeyEncryptionFrame: @unchecked Sendable {} +extension Location_Nearby_Connections_MediumMetadata: @unchecked Sendable {} +extension Location_Nearby_Connections_AvailableChannels: @unchecked Sendable {} +extension Location_Nearby_Connections_WifiDirectCliUsableChannels: @unchecked Sendable {} +extension Location_Nearby_Connections_WifiLanUsableChannels: @unchecked Sendable {} +extension Location_Nearby_Connections_WifiAwareUsableChannels: @unchecked Sendable {} +extension Location_Nearby_Connections_WifiHotspotStaUsableChannels: @unchecked Sendable {} +extension Location_Nearby_Connections_LocationHint: @unchecked Sendable {} +extension Location_Nearby_Connections_LocationStandard: @unchecked Sendable {} +extension Location_Nearby_Connections_LocationStandard.Format: @unchecked Sendable {} +extension Location_Nearby_Connections_OsInfo: @unchecked Sendable {} +extension Location_Nearby_Connections_OsInfo.OsType: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "location.nearby.connections" + +extension Location_Nearby_Connections_OfflineFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".OfflineFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "version"), + 2: .same(proto: "v1"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._version) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._v1) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._version { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._v1 { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_OfflineFrame, rhs: Location_Nearby_Connections_OfflineFrame) -> Bool { + if lhs._version != rhs._version {return false} + if lhs._v1 != rhs._v1 {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_OfflineFrame.Version: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_VERSION"), + 1: .same(proto: "V1"), + ] +} + +extension Location_Nearby_Connections_V1Frame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".V1Frame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .standard(proto: "connection_request"), + 3: .standard(proto: "connection_response"), + 4: .standard(proto: "payload_transfer"), + 5: .standard(proto: "bandwidth_upgrade_negotiation"), + 6: .standard(proto: "keep_alive"), + 7: .same(proto: "disconnection"), + 8: .standard(proto: "paired_key_encryption"), + ] + + fileprivate class _StorageClass { + var _type: Location_Nearby_Connections_V1Frame.FrameType? = nil + var _connectionRequest: Location_Nearby_Connections_ConnectionRequestFrame? = nil + var _connectionResponse: Location_Nearby_Connections_ConnectionResponseFrame? = nil + var _payloadTransfer: Location_Nearby_Connections_PayloadTransferFrame? = nil + var _bandwidthUpgradeNegotiation: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame? = nil + var _keepAlive: Location_Nearby_Connections_KeepAliveFrame? = nil + var _disconnection: Location_Nearby_Connections_DisconnectionFrame? = nil + var _pairedKeyEncryption: Location_Nearby_Connections_PairedKeyEncryptionFrame? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _type = source._type + _connectionRequest = source._connectionRequest + _connectionResponse = source._connectionResponse + _payloadTransfer = source._payloadTransfer + _bandwidthUpgradeNegotiation = source._bandwidthUpgradeNegotiation + _keepAlive = source._keepAlive + _disconnection = source._disconnection + _pairedKeyEncryption = source._pairedKeyEncryption + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &_storage._type) }() + case 2: try { try decoder.decodeSingularMessageField(value: &_storage._connectionRequest) }() + case 3: try { try decoder.decodeSingularMessageField(value: &_storage._connectionResponse) }() + case 4: try { try decoder.decodeSingularMessageField(value: &_storage._payloadTransfer) }() + case 5: try { try decoder.decodeSingularMessageField(value: &_storage._bandwidthUpgradeNegotiation) }() + case 6: try { try decoder.decodeSingularMessageField(value: &_storage._keepAlive) }() + case 7: try { try decoder.decodeSingularMessageField(value: &_storage._disconnection) }() + case 8: try { try decoder.decodeSingularMessageField(value: &_storage._pairedKeyEncryption) }() + default: break + } + } + } + } + + func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = _storage._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = _storage._connectionRequest { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = _storage._connectionResponse { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try { if let v = _storage._payloadTransfer { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try { if let v = _storage._bandwidthUpgradeNegotiation { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } }() + try { if let v = _storage._keepAlive { + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + } }() + try { if let v = _storage._disconnection { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + try { if let v = _storage._pairedKeyEncryption { + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_V1Frame, rhs: Location_Nearby_Connections_V1Frame) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._type != rhs_storage._type {return false} + if _storage._connectionRequest != rhs_storage._connectionRequest {return false} + if _storage._connectionResponse != rhs_storage._connectionResponse {return false} + if _storage._payloadTransfer != rhs_storage._payloadTransfer {return false} + if _storage._bandwidthUpgradeNegotiation != rhs_storage._bandwidthUpgradeNegotiation {return false} + if _storage._keepAlive != rhs_storage._keepAlive {return false} + if _storage._disconnection != rhs_storage._disconnection {return false} + if _storage._pairedKeyEncryption != rhs_storage._pairedKeyEncryption {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_V1Frame.FrameType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_FRAME_TYPE"), + 1: .same(proto: "CONNECTION_REQUEST"), + 2: .same(proto: "CONNECTION_RESPONSE"), + 3: .same(proto: "PAYLOAD_TRANSFER"), + 4: .same(proto: "BANDWIDTH_UPGRADE_NEGOTIATION"), + 5: .same(proto: "KEEP_ALIVE"), + 6: .same(proto: "DISCONNECTION"), + 7: .same(proto: "PAIRED_KEY_ENCRYPTION"), + ] +} + +extension Location_Nearby_Connections_ConnectionRequestFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".ConnectionRequestFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "endpoint_id"), + 2: .standard(proto: "endpoint_name"), + 3: .standard(proto: "handshake_data"), + 4: .same(proto: "nonce"), + 5: .same(proto: "mediums"), + 6: .standard(proto: "endpoint_info"), + 7: .standard(proto: "medium_metadata"), + 8: .standard(proto: "keep_alive_interval_millis"), + 9: .standard(proto: "keep_alive_timeout_millis"), + 10: .standard(proto: "device_type"), + 11: .standard(proto: "device_info"), + ] + + fileprivate class _StorageClass { + var _endpointID: String? = nil + var _endpointName: String? = nil + var _handshakeData: Data? = nil + var _nonce: Int32? = nil + var _mediums: [Location_Nearby_Connections_ConnectionRequestFrame.Medium] = [] + var _endpointInfo: Data? = nil + var _mediumMetadata: Location_Nearby_Connections_MediumMetadata? = nil + var _keepAliveIntervalMillis: Int32? = nil + var _keepAliveTimeoutMillis: Int32? = nil + var _deviceType: Int32? = nil + var _deviceInfo: Data? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _endpointID = source._endpointID + _endpointName = source._endpointName + _handshakeData = source._handshakeData + _nonce = source._nonce + _mediums = source._mediums + _endpointInfo = source._endpointInfo + _mediumMetadata = source._mediumMetadata + _keepAliveIntervalMillis = source._keepAliveIntervalMillis + _keepAliveTimeoutMillis = source._keepAliveTimeoutMillis + _deviceType = source._deviceType + _deviceInfo = source._deviceInfo + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &_storage._endpointID) }() + case 2: try { try decoder.decodeSingularStringField(value: &_storage._endpointName) }() + case 3: try { try decoder.decodeSingularBytesField(value: &_storage._handshakeData) }() + case 4: try { try decoder.decodeSingularInt32Field(value: &_storage._nonce) }() + case 5: try { try decoder.decodeRepeatedEnumField(value: &_storage._mediums) }() + case 6: try { try decoder.decodeSingularBytesField(value: &_storage._endpointInfo) }() + case 7: try { try decoder.decodeSingularMessageField(value: &_storage._mediumMetadata) }() + case 8: try { try decoder.decodeSingularInt32Field(value: &_storage._keepAliveIntervalMillis) }() + case 9: try { try decoder.decodeSingularInt32Field(value: &_storage._keepAliveTimeoutMillis) }() + case 10: try { try decoder.decodeSingularInt32Field(value: &_storage._deviceType) }() + case 11: try { try decoder.decodeSingularBytesField(value: &_storage._deviceInfo) }() + default: break + } + } + } + } + + func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = _storage._endpointID { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = _storage._endpointName { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = _storage._handshakeData { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try { if let v = _storage._nonce { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 4) + } }() + if !_storage._mediums.isEmpty { + try visitor.visitRepeatedEnumField(value: _storage._mediums, fieldNumber: 5) + } + try { if let v = _storage._endpointInfo { + try visitor.visitSingularBytesField(value: v, fieldNumber: 6) + } }() + try { if let v = _storage._mediumMetadata { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + try { if let v = _storage._keepAliveIntervalMillis { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 8) + } }() + try { if let v = _storage._keepAliveTimeoutMillis { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 9) + } }() + try { if let v = _storage._deviceType { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 10) + } }() + try { if let v = _storage._deviceInfo { + try visitor.visitSingularBytesField(value: v, fieldNumber: 11) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_ConnectionRequestFrame, rhs: Location_Nearby_Connections_ConnectionRequestFrame) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._endpointID != rhs_storage._endpointID {return false} + if _storage._endpointName != rhs_storage._endpointName {return false} + if _storage._handshakeData != rhs_storage._handshakeData {return false} + if _storage._nonce != rhs_storage._nonce {return false} + if _storage._mediums != rhs_storage._mediums {return false} + if _storage._endpointInfo != rhs_storage._endpointInfo {return false} + if _storage._mediumMetadata != rhs_storage._mediumMetadata {return false} + if _storage._keepAliveIntervalMillis != rhs_storage._keepAliveIntervalMillis {return false} + if _storage._keepAliveTimeoutMillis != rhs_storage._keepAliveTimeoutMillis {return false} + if _storage._deviceType != rhs_storage._deviceType {return false} + if _storage._deviceInfo != rhs_storage._deviceInfo {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_ConnectionRequestFrame.Medium: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_MEDIUM"), + 1: .same(proto: "MDNS"), + 2: .same(proto: "BLUETOOTH"), + 3: .same(proto: "WIFI_HOTSPOT"), + 4: .same(proto: "BLE"), + 5: .same(proto: "WIFI_LAN"), + 6: .same(proto: "WIFI_AWARE"), + 7: .same(proto: "NFC"), + 8: .same(proto: "WIFI_DIRECT"), + 9: .same(proto: "WEB_RTC"), + 10: .same(proto: "BLE_L2CAP"), + 11: .same(proto: "USB"), + ] +} + +extension Location_Nearby_Connections_ConnectionResponseFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".ConnectionResponseFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "status"), + 2: .standard(proto: "handshake_data"), + 3: .same(proto: "response"), + 4: .standard(proto: "os_info"), + 5: .standard(proto: "multiplex_socket_bitmask"), + 6: .standard(proto: "nearby_connections_version"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._status) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._handshakeData) }() + case 3: try { try decoder.decodeSingularEnumField(value: &self._response) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._osInfo) }() + case 5: try { try decoder.decodeSingularInt32Field(value: &self._multiplexSocketBitmask) }() + case 6: try { try decoder.decodeSingularInt32Field(value: &self._nearbyConnectionsVersion) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._status { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._handshakeData { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try { if let v = self._response { + try visitor.visitSingularEnumField(value: v, fieldNumber: 3) + } }() + try { if let v = self._osInfo { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try { if let v = self._multiplexSocketBitmask { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 5) + } }() + try { if let v = self._nearbyConnectionsVersion { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_ConnectionResponseFrame, rhs: Location_Nearby_Connections_ConnectionResponseFrame) -> Bool { + if lhs._status != rhs._status {return false} + if lhs._handshakeData != rhs._handshakeData {return false} + if lhs._response != rhs._response {return false} + if lhs._osInfo != rhs._osInfo {return false} + if lhs._multiplexSocketBitmask != rhs._multiplexSocketBitmask {return false} + if lhs._nearbyConnectionsVersion != rhs._nearbyConnectionsVersion {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_RESPONSE_STATUS"), + 1: .same(proto: "ACCEPT"), + 2: .same(proto: "REJECT"), + ] +} + +extension Location_Nearby_Connections_PayloadTransferFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".PayloadTransferFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "packet_type"), + 2: .standard(proto: "payload_header"), + 3: .standard(proto: "payload_chunk"), + 4: .standard(proto: "control_message"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._packetType) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._payloadHeader) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._payloadChunk) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._controlMessage) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._packetType { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._payloadHeader { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = self._payloadChunk { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try { if let v = self._controlMessage { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame, rhs: Location_Nearby_Connections_PayloadTransferFrame) -> Bool { + if lhs._packetType != rhs._packetType {return false} + if lhs._payloadHeader != rhs._payloadHeader {return false} + if lhs._payloadChunk != rhs._payloadChunk {return false} + if lhs._controlMessage != rhs._controlMessage {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_PayloadTransferFrame.PacketType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_PACKET_TYPE"), + 1: .same(proto: "DATA"), + 2: .same(proto: "CONTROL"), + ] +} + +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_PayloadTransferFrame.protoMessageName + ".PayloadHeader" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "id"), + 2: .same(proto: "type"), + 3: .standard(proto: "total_size"), + 4: .standard(proto: "is_sensitive"), + 5: .standard(proto: "file_name"), + 6: .standard(proto: "parent_folder"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt64Field(value: &self._id) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 3: try { try decoder.decodeSingularInt64Field(value: &self._totalSize) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self._isSensitive) }() + case 5: try { try decoder.decodeSingularStringField(value: &self._fileName) }() + case 6: try { try decoder.decodeSingularStringField(value: &self._parentFolder) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._id { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 2) + } }() + try { if let v = self._totalSize { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 3) + } }() + try { if let v = self._isSensitive { + try visitor.visitSingularBoolField(value: v, fieldNumber: 4) + } }() + try { if let v = self._fileName { + try visitor.visitSingularStringField(value: v, fieldNumber: 5) + } }() + try { if let v = self._parentFolder { + try visitor.visitSingularStringField(value: v, fieldNumber: 6) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader, rhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader) -> Bool { + if lhs._id != rhs._id {return false} + if lhs._type != rhs._type {return false} + if lhs._totalSize != rhs._totalSize {return false} + if lhs._isSensitive != rhs._isSensitive {return false} + if lhs._fileName != rhs._fileName {return false} + if lhs._parentFolder != rhs._parentFolder {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_PAYLOAD_TYPE"), + 1: .same(proto: "BYTES"), + 2: .same(proto: "FILE"), + 3: .same(proto: "STREAM"), + ] +} + +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_PayloadTransferFrame.protoMessageName + ".PayloadChunk" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "flags"), + 2: .same(proto: "offset"), + 3: .same(proto: "body"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._flags) }() + case 2: try { try decoder.decodeSingularInt64Field(value: &self._offset) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._body) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._flags { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._offset { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 2) + } }() + try { if let v = self._body { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk, rhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk) -> Bool { + if lhs._flags != rhs._flags {return false} + if lhs._offset != rhs._offset {return false} + if lhs._body != rhs._body {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk.Flags: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "LAST_CHUNK"), + ] +} + +extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_PayloadTransferFrame.protoMessageName + ".ControlMessage" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "event"), + 2: .same(proto: "offset"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._event) }() + case 2: try { try decoder.decodeSingularInt64Field(value: &self._offset) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._event { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._offset { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage, rhs: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage) -> Bool { + if lhs._event != rhs._event {return false} + if lhs._offset != rhs._offset {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_EVENT_TYPE"), + 1: .same(proto: "PAYLOAD_ERROR"), + 2: .same(proto: "PAYLOAD_CANCELED"), + 3: .same(proto: "PAYLOAD_RECEIVED_ACK"), + ] +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".BandwidthUpgradeNegotiationFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "event_type"), + 2: .standard(proto: "upgrade_path_info"), + 3: .standard(proto: "client_introduction"), + 4: .standard(proto: "client_introduction_ack"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._eventType) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._upgradePathInfo) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._clientIntroduction) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._clientIntroductionAck) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._eventType { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._upgradePathInfo { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = self._clientIntroduction { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try { if let v = self._clientIntroductionAck { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame) -> Bool { + if lhs._eventType != rhs._eventType {return false} + if lhs._upgradePathInfo != rhs._upgradePathInfo {return false} + if lhs._clientIntroduction != rhs._clientIntroduction {return false} + if lhs._clientIntroductionAck != rhs._clientIntroductionAck {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_EVENT_TYPE"), + 1: .same(proto: "UPGRADE_PATH_AVAILABLE"), + 2: .same(proto: "LAST_WRITE_TO_PRIOR_CHANNEL"), + 3: .same(proto: "SAFE_TO_CLOSE_PRIOR_CHANNEL"), + 4: .same(proto: "CLIENT_INTRODUCTION"), + 5: .same(proto: "UPGRADE_FAILURE"), + 6: .same(proto: "CLIENT_INTRODUCTION_ACK"), + ] +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.protoMessageName + ".UpgradePathInfo" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "medium"), + 2: .standard(proto: "wifi_hotspot_credentials"), + 3: .standard(proto: "wifi_lan_socket"), + 4: .standard(proto: "bluetooth_credentials"), + 5: .standard(proto: "wifi_aware_credentials"), + 6: .standard(proto: "wifi_direct_credentials"), + 8: .standard(proto: "web_rtc_credentials"), + 7: .standard(proto: "supports_disabling_encryption"), + 9: .standard(proto: "supports_client_introduction_ack"), + ] + + fileprivate class _StorageClass { + var _medium: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium? = nil + var _wifiHotspotCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials? = nil + var _wifiLanSocket: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket? = nil + var _bluetoothCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials? = nil + var _wifiAwareCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials? = nil + var _wifiDirectCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials? = nil + var _webRtcCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials? = nil + var _supportsDisablingEncryption: Bool? = nil + var _supportsClientIntroductionAck: Bool? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _medium = source._medium + _wifiHotspotCredentials = source._wifiHotspotCredentials + _wifiLanSocket = source._wifiLanSocket + _bluetoothCredentials = source._bluetoothCredentials + _wifiAwareCredentials = source._wifiAwareCredentials + _wifiDirectCredentials = source._wifiDirectCredentials + _webRtcCredentials = source._webRtcCredentials + _supportsDisablingEncryption = source._supportsDisablingEncryption + _supportsClientIntroductionAck = source._supportsClientIntroductionAck + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &_storage._medium) }() + case 2: try { try decoder.decodeSingularMessageField(value: &_storage._wifiHotspotCredentials) }() + case 3: try { try decoder.decodeSingularMessageField(value: &_storage._wifiLanSocket) }() + case 4: try { try decoder.decodeSingularMessageField(value: &_storage._bluetoothCredentials) }() + case 5: try { try decoder.decodeSingularMessageField(value: &_storage._wifiAwareCredentials) }() + case 6: try { try decoder.decodeSingularMessageField(value: &_storage._wifiDirectCredentials) }() + case 7: try { try decoder.decodeSingularBoolField(value: &_storage._supportsDisablingEncryption) }() + case 8: try { try decoder.decodeSingularMessageField(value: &_storage._webRtcCredentials) }() + case 9: try { try decoder.decodeSingularBoolField(value: &_storage._supportsClientIntroductionAck) }() + default: break + } + } + } + } + + func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = _storage._medium { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = _storage._wifiHotspotCredentials { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = _storage._wifiLanSocket { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try { if let v = _storage._bluetoothCredentials { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try { if let v = _storage._wifiAwareCredentials { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } }() + try { if let v = _storage._wifiDirectCredentials { + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + } }() + try { if let v = _storage._supportsDisablingEncryption { + try visitor.visitSingularBoolField(value: v, fieldNumber: 7) + } }() + try { if let v = _storage._webRtcCredentials { + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + } }() + try { if let v = _storage._supportsClientIntroductionAck { + try visitor.visitSingularBoolField(value: v, fieldNumber: 9) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._medium != rhs_storage._medium {return false} + if _storage._wifiHotspotCredentials != rhs_storage._wifiHotspotCredentials {return false} + if _storage._wifiLanSocket != rhs_storage._wifiLanSocket {return false} + if _storage._bluetoothCredentials != rhs_storage._bluetoothCredentials {return false} + if _storage._wifiAwareCredentials != rhs_storage._wifiAwareCredentials {return false} + if _storage._wifiDirectCredentials != rhs_storage._wifiDirectCredentials {return false} + if _storage._webRtcCredentials != rhs_storage._webRtcCredentials {return false} + if _storage._supportsDisablingEncryption != rhs_storage._supportsDisablingEncryption {return false} + if _storage._supportsClientIntroductionAck != rhs_storage._supportsClientIntroductionAck {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_MEDIUM"), + 1: .same(proto: "MDNS"), + 2: .same(proto: "BLUETOOTH"), + 3: .same(proto: "WIFI_HOTSPOT"), + 4: .same(proto: "BLE"), + 5: .same(proto: "WIFI_LAN"), + 6: .same(proto: "WIFI_AWARE"), + 7: .same(proto: "NFC"), + 8: .same(proto: "WIFI_DIRECT"), + 9: .same(proto: "WEB_RTC"), + 11: .same(proto: "USB"), + ] +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiHotspotCredentials" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "ssid"), + 2: .same(proto: "password"), + 3: .same(proto: "port"), + 4: .same(proto: "gateway"), + 5: .same(proto: "frequency"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._ssid) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._password) }() + case 3: try { try decoder.decodeSingularInt32Field(value: &self._port) }() + case 4: try { try decoder.decodeSingularStringField(value: &self._gateway) }() + case 5: try { try decoder.decodeSingularInt32Field(value: &self._frequency) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._ssid { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._password { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = self._port { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 3) + } }() + try { if let v = self._gateway { + try visitor.visitSingularStringField(value: v, fieldNumber: 4) + } }() + try { if let v = self._frequency { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 5) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials) -> Bool { + if lhs._ssid != rhs._ssid {return false} + if lhs._password != rhs._password {return false} + if lhs._port != rhs._port {return false} + if lhs._gateway != rhs._gateway {return false} + if lhs._frequency != rhs._frequency {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiLanSocket" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "ip_address"), + 2: .standard(proto: "wifi_port"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._ipAddress) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._wifiPort) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._ipAddress { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._wifiPort { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket) -> Bool { + if lhs._ipAddress != rhs._ipAddress {return false} + if lhs._wifiPort != rhs._wifiPort {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".BluetoothCredentials" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "service_name"), + 2: .standard(proto: "mac_address"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._serviceName) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._macAddress) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._serviceName { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._macAddress { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials) -> Bool { + if lhs._serviceName != rhs._serviceName {return false} + if lhs._macAddress != rhs._macAddress {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiAwareCredentials" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "service_id"), + 2: .standard(proto: "service_info"), + 3: .same(proto: "password"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._serviceID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._serviceInfo) }() + case 3: try { try decoder.decodeSingularStringField(value: &self._password) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._serviceID { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._serviceInfo { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try { if let v = self._password { + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials) -> Bool { + if lhs._serviceID != rhs._serviceID {return false} + if lhs._serviceInfo != rhs._serviceInfo {return false} + if lhs._password != rhs._password {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiDirectCredentials" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "ssid"), + 2: .same(proto: "password"), + 3: .same(proto: "port"), + 4: .same(proto: "frequency"), + 5: .same(proto: "gateway"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._ssid) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._password) }() + case 3: try { try decoder.decodeSingularInt32Field(value: &self._port) }() + case 4: try { try decoder.decodeSingularInt32Field(value: &self._frequency) }() + case 5: try { try decoder.decodeSingularStringField(value: &self._gateway) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._ssid { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._password { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = self._port { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 3) + } }() + try { if let v = self._frequency { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 4) + } }() + try { if let v = self._gateway { + try visitor.visitSingularStringField(value: v, fieldNumber: 5) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials) -> Bool { + if lhs._ssid != rhs._ssid {return false} + if lhs._password != rhs._password {return false} + if lhs._port != rhs._port {return false} + if lhs._frequency != rhs._frequency {return false} + if lhs._gateway != rhs._gateway {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WebRtcCredentials" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "peer_id"), + 2: .standard(proto: "location_hint"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._peerID) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._locationHint) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._peerID { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._locationHint { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials) -> Bool { + if lhs._peerID != rhs._peerID {return false} + if lhs._locationHint != rhs._locationHint {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.protoMessageName + ".ClientIntroduction" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "endpoint_id"), + 2: .standard(proto: "supports_disabling_encryption"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._endpointID) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self._supportsDisablingEncryption) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._endpointID { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._supportsDisablingEncryption { + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction) -> Bool { + if lhs._endpointID != rhs._endpointID {return false} + if lhs._supportsDisablingEncryption != rhs._supportsDisablingEncryption {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.protoMessageName + ".ClientIntroductionAck" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_KeepAliveFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".KeepAliveFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "ack"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self._ack) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._ack { + try visitor.visitSingularBoolField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_KeepAliveFrame, rhs: Location_Nearby_Connections_KeepAliveFrame) -> Bool { + if lhs._ack != rhs._ack {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_DisconnectionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".DisconnectionFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "request_safe_to_disconnect"), + 2: .standard(proto: "ack_safe_to_disconnect"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self._requestSafeToDisconnect) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self._ackSafeToDisconnect) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._requestSafeToDisconnect { + try visitor.visitSingularBoolField(value: v, fieldNumber: 1) + } }() + try { if let v = self._ackSafeToDisconnect { + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_DisconnectionFrame, rhs: Location_Nearby_Connections_DisconnectionFrame) -> Bool { + if lhs._requestSafeToDisconnect != rhs._requestSafeToDisconnect {return false} + if lhs._ackSafeToDisconnect != rhs._ackSafeToDisconnect {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_PairedKeyEncryptionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".PairedKeyEncryptionFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "signed_data"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._signedData) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._signedData { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_PairedKeyEncryptionFrame, rhs: Location_Nearby_Connections_PairedKeyEncryptionFrame) -> Bool { + if lhs._signedData != rhs._signedData {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_MediumMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".MediumMetadata" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "supports_5_ghz"), + 2: .same(proto: "bssid"), + 3: .standard(proto: "ip_address"), + 4: .standard(proto: "supports_6_ghz"), + 5: .standard(proto: "mobile_radio"), + 6: .standard(proto: "ap_frequency"), + 7: .standard(proto: "available_channels"), + 8: .standard(proto: "wifi_direct_cli_usable_channels"), + 9: .standard(proto: "wifi_lan_usable_channels"), + 10: .standard(proto: "wifi_aware_usable_channels"), + 11: .standard(proto: "wifi_hotspot_sta_usable_channels"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBoolField(value: &self._supports5Ghz) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._bssid) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._ipAddress) }() + case 4: try { try decoder.decodeSingularBoolField(value: &self._supports6Ghz) }() + case 5: try { try decoder.decodeSingularBoolField(value: &self._mobileRadio) }() + case 6: try { try decoder.decodeSingularInt32Field(value: &self._apFrequency) }() + case 7: try { try decoder.decodeSingularMessageField(value: &self._availableChannels) }() + case 8: try { try decoder.decodeSingularMessageField(value: &self._wifiDirectCliUsableChannels) }() + case 9: try { try decoder.decodeSingularMessageField(value: &self._wifiLanUsableChannels) }() + case 10: try { try decoder.decodeSingularMessageField(value: &self._wifiAwareUsableChannels) }() + case 11: try { try decoder.decodeSingularMessageField(value: &self._wifiHotspotStaUsableChannels) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._supports5Ghz { + try visitor.visitSingularBoolField(value: v, fieldNumber: 1) + } }() + try { if let v = self._bssid { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = self._ipAddress { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try { if let v = self._supports6Ghz { + try visitor.visitSingularBoolField(value: v, fieldNumber: 4) + } }() + try { if let v = self._mobileRadio { + try visitor.visitSingularBoolField(value: v, fieldNumber: 5) + } }() + try { if let v = self._apFrequency { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) + } }() + try { if let v = self._availableChannels { + try visitor.visitSingularMessageField(value: v, fieldNumber: 7) + } }() + try { if let v = self._wifiDirectCliUsableChannels { + try visitor.visitSingularMessageField(value: v, fieldNumber: 8) + } }() + try { if let v = self._wifiLanUsableChannels { + try visitor.visitSingularMessageField(value: v, fieldNumber: 9) + } }() + try { if let v = self._wifiAwareUsableChannels { + try visitor.visitSingularMessageField(value: v, fieldNumber: 10) + } }() + try { if let v = self._wifiHotspotStaUsableChannels { + try visitor.visitSingularMessageField(value: v, fieldNumber: 11) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_MediumMetadata, rhs: Location_Nearby_Connections_MediumMetadata) -> Bool { + if lhs._supports5Ghz != rhs._supports5Ghz {return false} + if lhs._bssid != rhs._bssid {return false} + if lhs._ipAddress != rhs._ipAddress {return false} + if lhs._supports6Ghz != rhs._supports6Ghz {return false} + if lhs._mobileRadio != rhs._mobileRadio {return false} + if lhs._apFrequency != rhs._apFrequency {return false} + if lhs._availableChannels != rhs._availableChannels {return false} + if lhs._wifiDirectCliUsableChannels != rhs._wifiDirectCliUsableChannels {return false} + if lhs._wifiLanUsableChannels != rhs._wifiLanUsableChannels {return false} + if lhs._wifiAwareUsableChannels != rhs._wifiAwareUsableChannels {return false} + if lhs._wifiHotspotStaUsableChannels != rhs._wifiHotspotStaUsableChannels {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_AvailableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".AvailableChannels" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "channels"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.channels.isEmpty { + try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_AvailableChannels, rhs: Location_Nearby_Connections_AvailableChannels) -> Bool { + if lhs.channels != rhs.channels {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_WifiDirectCliUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".WifiDirectCliUsableChannels" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "channels"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.channels.isEmpty { + try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_WifiDirectCliUsableChannels, rhs: Location_Nearby_Connections_WifiDirectCliUsableChannels) -> Bool { + if lhs.channels != rhs.channels {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_WifiLanUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".WifiLanUsableChannels" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "channels"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.channels.isEmpty { + try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_WifiLanUsableChannels, rhs: Location_Nearby_Connections_WifiLanUsableChannels) -> Bool { + if lhs.channels != rhs.channels {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_WifiAwareUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".WifiAwareUsableChannels" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "channels"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.channels.isEmpty { + try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_WifiAwareUsableChannels, rhs: Location_Nearby_Connections_WifiAwareUsableChannels) -> Bool { + if lhs.channels != rhs.channels {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_WifiHotspotStaUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".WifiHotspotStaUsableChannels" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "channels"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.channels.isEmpty { + try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_WifiHotspotStaUsableChannels, rhs: Location_Nearby_Connections_WifiHotspotStaUsableChannels) -> Bool { + if lhs.channels != rhs.channels {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_LocationHint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".LocationHint" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "location"), + 2: .same(proto: "format"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._location) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self._format) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._location { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._format { + try visitor.visitSingularEnumField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_LocationHint, rhs: Location_Nearby_Connections_LocationHint) -> Bool { + if lhs._location != rhs._location {return false} + if lhs._format != rhs._format {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_LocationStandard: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".LocationStandard" + static let _protobuf_nameMap = SwiftProtobuf._NameMap() + + mutating func decodeMessage(decoder: inout D) throws { + while let _ = try decoder.nextFieldNumber() { + } + } + + func traverse(visitor: inout V) throws { + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_LocationStandard, rhs: Location_Nearby_Connections_LocationStandard) -> Bool { + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_LocationStandard.Format: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN"), + 1: .same(proto: "E164_CALLING"), + 2: .same(proto: "ISO_3166_1_ALPHA_2"), + ] +} + +extension Location_Nearby_Connections_OsInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".OsInfo" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Location_Nearby_Connections_OsInfo, rhs: Location_Nearby_Connections_OsInfo) -> Bool { + if lhs._type != rhs._type {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Location_Nearby_Connections_OsInfo.OsType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_OS_TYPE"), + 1: .same(proto: "ANDROID"), + 2: .same(proto: "CHROME_OS"), + 3: .same(proto: "WINDOWS"), + 4: .same(proto: "APPLE"), + 100: .same(proto: "LINUX"), + ] +} diff --git a/submissions/sapphire/ProtobufGenerated/securegcm.pb.swift b/submissions/sapphire/ProtobufGenerated/securegcm.pb.swift new file mode 100644 index 00000000..5da7ecc7 --- /dev/null +++ b/submissions/sapphire/ProtobufGenerated/securegcm.pb.swift @@ -0,0 +1,1522 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: securegcm.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// This enum is used by iOS devices as values for device_display_diagonal_mils +/// in GcmDeviceInfo. There is no good way to calculate it on those devices. +enum Securegcm_AppleDeviceDiagonalMils: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// This is the mils diagonal on an iPhone 5. + case applePhone // = 4000 + + /// This is the mils diagonal on an iPad mini. + case applePad // = 7900 + + init() { + self = .applePhone + } + + init?(rawValue: Int) { + switch rawValue { + case 4000: self = .applePhone + case 7900: self = .applePad + default: return nil + } + } + + var rawValue: Int { + switch self { + case .applePhone: return 4000 + case .applePad: return 7900 + } + } + +} + +#if swift(>=4.2) + +extension Securegcm_AppleDeviceDiagonalMils: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// This should be kept in sync with DeviceType in: +/// java/com/google/security/cryptauth/backend/services/common/common_enums.proto +enum Securegcm_DeviceType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknown // = 0 + case android // = 1 + case chrome // = 2 + case ios // = 3 + case browser // = 4 + case osx // = 5 + + init() { + self = .unknown + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .android + case 2: self = .chrome + case 3: self = .ios + case 4: self = .browser + case 5: self = .osx + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknown: return 0 + case .android: return 1 + case .chrome: return 2 + case .ios: return 3 + case .browser: return 4 + case .osx: return 5 + } + } + +} + +#if swift(>=4.2) + +extension Securegcm_DeviceType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// MultiDevice features which may be supported and enabled on a device. See +enum Securegcm_SoftwareFeature: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownFeature // = 0 + case betterTogetherHost // = 1 + case betterTogetherClient // = 2 + case easyUnlockHost // = 3 + case easyUnlockClient // = 4 + case magicTetherHost // = 5 + case magicTetherClient // = 6 + case smsConnectHost // = 7 + case smsConnectClient // = 8 + + init() { + self = .unknownFeature + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownFeature + case 1: self = .betterTogetherHost + case 2: self = .betterTogetherClient + case 3: self = .easyUnlockHost + case 4: self = .easyUnlockClient + case 5: self = .magicTetherHost + case 6: self = .magicTetherClient + case 7: self = .smsConnectHost + case 8: self = .smsConnectClient + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownFeature: return 0 + case .betterTogetherHost: return 1 + case .betterTogetherClient: return 2 + case .easyUnlockHost: return 3 + case .easyUnlockClient: return 4 + case .magicTetherHost: return 5 + case .magicTetherClient: return 6 + case .smsConnectHost: return 7 + case .smsConnectClient: return 8 + } + } + +} + +#if swift(>=4.2) + +extension Securegcm_SoftwareFeature: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// A list of "reasons" that can be provided for calling server-side APIs. +/// This is particularly important for calls that can be triggered by different +/// kinds of events. Please try to keep reasons as generic as possible, so that +/// codes can be re-used by various callers in a sensible fashion. +enum Securegcm_InvocationReason: SwiftProtobuf.Enum { + typealias RawValue = Int + case reasonUnknown // = 0 + + /// First run of the software package invoking this call + case reasonInitialization // = 1 + + /// Ordinary periodic actions (e.g. monthly master key rotation) + case reasonPeriodic // = 2 + + /// Slow-cycle periodic action (e.g. yearly keypair rotation???) + case reasonSlowPeriodic // = 3 + + /// Fast-cycle periodic action (e.g. daily sync for Smart Lock users) + case reasonFastPeriodic // = 4 + + /// Expired state (e.g. expired credentials, or cached entries) was detected + case reasonExpiration // = 5 + + /// An unexpected protocol failure occurred (so attempting to repair state) + case reasonFailureRecovery // = 6 + + /// A new account has been added to the device + case reasonNewAccount // = 7 + + /// An existing account on the device has been changed + case reasonChangedAccount // = 8 + + /// The user toggled the state of a feature (e.g. Smart Lock enabled via BT) + case reasonFeatureToggled // = 9 + + /// A "push" from the server caused this action (e.g. a sync tickle) + case reasonServerInitiated // = 10 + + /// A local address change triggered this (e.g. GCM registration id changed) + case reasonAddressChange // = 11 + + /// A software update has triggered this + case reasonSoftwareUpdate // = 12 + + /// A manual action by the user triggered this (e.g. commands sent via adb) + case reasonManual // = 13 + + /// A custom key has been invalidated on the device (e.g. screen lock is + /// disabled). + case reasonCustomKeyInvalidation // = 14 + + /// Periodic action triggered by auth_proximity + case reasonProximityPeriodic // = 15 + + init() { + self = .reasonUnknown + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .reasonUnknown + case 1: self = .reasonInitialization + case 2: self = .reasonPeriodic + case 3: self = .reasonSlowPeriodic + case 4: self = .reasonFastPeriodic + case 5: self = .reasonExpiration + case 6: self = .reasonFailureRecovery + case 7: self = .reasonNewAccount + case 8: self = .reasonChangedAccount + case 9: self = .reasonFeatureToggled + case 10: self = .reasonServerInitiated + case 11: self = .reasonAddressChange + case 12: self = .reasonSoftwareUpdate + case 13: self = .reasonManual + case 14: self = .reasonCustomKeyInvalidation + case 15: self = .reasonProximityPeriodic + default: return nil + } + } + + var rawValue: Int { + switch self { + case .reasonUnknown: return 0 + case .reasonInitialization: return 1 + case .reasonPeriodic: return 2 + case .reasonSlowPeriodic: return 3 + case .reasonFastPeriodic: return 4 + case .reasonExpiration: return 5 + case .reasonFailureRecovery: return 6 + case .reasonNewAccount: return 7 + case .reasonChangedAccount: return 8 + case .reasonFeatureToggled: return 9 + case .reasonServerInitiated: return 10 + case .reasonAddressChange: return 11 + case .reasonSoftwareUpdate: return 12 + case .reasonManual: return 13 + case .reasonCustomKeyInvalidation: return 14 + case .reasonProximityPeriodic: return 15 + } + } + +} + +#if swift(>=4.2) + +extension Securegcm_InvocationReason: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +enum Securegcm_Type: SwiftProtobuf.Enum { + typealias RawValue = Int + case enrollment // = 0 + case tickle // = 1 + case txRequest // = 2 + case txReply // = 3 + case txSyncRequest // = 4 + case txSyncResponse // = 5 + case txPing // = 6 + case deviceInfoUpdate // = 7 + case txCancelRequest // = 8 + + /// DEPRECATED (can be re-used after Aug 2015) + case proximityauthPairing // = 10 + + /// The kind of identity assertion generated by a "GCM V1" device (i.e., + /// an Android phone that has registered with us a public and a symmetric + /// key) + case gcmv1IdentityAssertion // = 11 + + /// Device-to-device communications are protected by an unauthenticated + /// Diffie-Hellman exchange. The InitiatorHello message is simply the + /// initiator's public DH key, and is not encoded as a SecureMessage, so + /// it doesn't have a tag. + /// The ResponderHello message (which is sent by the responder + /// to the initiator), on the other hand, carries a payload that is protected + /// by the derived shared key. It also contains the responder's + /// public DH key. ResponderHelloAndPayload messages have the + /// DEVICE_TO_DEVICE_RESPONDER_HELLO tag. + case deviceToDeviceResponderHelloPayload // = 12 + + /// Device-to-device communications are protected by an unauthenticated + /// Diffie-Hellman exchange. Once the initiator and responder + /// agree on a shared key (through Diffie-Hellman), they will use messages + /// tagged with DEVICE_TO_DEVICE_MESSAGE to exchange data. + case deviceToDeviceMessage // = 13 + + /// Notification to let a device know it should contact a nearby device. + case deviceProximityCallback // = 14 + + /// Device-to-device communications are protected by an unauthenticated + /// Diffie-Hellman exchange. During device-to-device authentication, the first + /// message from initiator (the challenge) is signed and put into the payload + /// of the message sent back to the initiator. + case unlockKeySignedChallenge // = 15 + + /// Specialty (corp only) features + case loginNotification // = 101 + + init() { + self = .enrollment + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .enrollment + case 1: self = .tickle + case 2: self = .txRequest + case 3: self = .txReply + case 4: self = .txSyncRequest + case 5: self = .txSyncResponse + case 6: self = .txPing + case 7: self = .deviceInfoUpdate + case 8: self = .txCancelRequest + case 10: self = .proximityauthPairing + case 11: self = .gcmv1IdentityAssertion + case 12: self = .deviceToDeviceResponderHelloPayload + case 13: self = .deviceToDeviceMessage + case 14: self = .deviceProximityCallback + case 15: self = .unlockKeySignedChallenge + case 101: self = .loginNotification + default: return nil + } + } + + var rawValue: Int { + switch self { + case .enrollment: return 0 + case .tickle: return 1 + case .txRequest: return 2 + case .txReply: return 3 + case .txSyncRequest: return 4 + case .txSyncResponse: return 5 + case .txPing: return 6 + case .deviceInfoUpdate: return 7 + case .txCancelRequest: return 8 + case .proximityauthPairing: return 10 + case .gcmv1IdentityAssertion: return 11 + case .deviceToDeviceResponderHelloPayload: return 12 + case .deviceToDeviceMessage: return 13 + case .deviceProximityCallback: return 14 + case .unlockKeySignedChallenge: return 15 + case .loginNotification: return 101 + } + } + +} + +#if swift(>=4.2) + +extension Securegcm_Type: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// Message used only during enrollment +/// Field numbers should be kept in sync with DeviceInfo in: +/// java/com/google/security/cryptauth/backend/services/common/common.proto +struct Securegcm_GcmDeviceInfo { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// This field's name does not match the one in DeviceInfo for legacy reasons. + /// Consider using long_device_id and device_type instead when enrolling + /// non-android devices. + var androidDeviceID: UInt64 { + get {return _storage._androidDeviceID ?? 0} + set {_uniqueStorage()._androidDeviceID = newValue} + } + /// Returns true if `androidDeviceID` has been explicitly set. + var hasAndroidDeviceID: Bool {return _storage._androidDeviceID != nil} + /// Clears the value of `androidDeviceID`. Subsequent reads from it will return its default value. + mutating func clearAndroidDeviceID() {_uniqueStorage()._androidDeviceID = nil} + + /// Used for device_address of DeviceInfo field 2, but for GCM capable devices. + var gcmRegistrationID: Data { + get {return _storage._gcmRegistrationID ?? Data()} + set {_uniqueStorage()._gcmRegistrationID = newValue} + } + /// Returns true if `gcmRegistrationID` has been explicitly set. + var hasGcmRegistrationID: Bool {return _storage._gcmRegistrationID != nil} + /// Clears the value of `gcmRegistrationID`. Subsequent reads from it will return its default value. + mutating func clearGcmRegistrationID() {_uniqueStorage()._gcmRegistrationID = nil} + + /// Used for device_address of DeviceInfo field 2, but for iOS devices. + var apnRegistrationID: Data { + get {return _storage._apnRegistrationID ?? Data()} + set {_uniqueStorage()._apnRegistrationID = newValue} + } + /// Returns true if `apnRegistrationID` has been explicitly set. + var hasApnRegistrationID: Bool {return _storage._apnRegistrationID != nil} + /// Clears the value of `apnRegistrationID`. Subsequent reads from it will return its default value. + mutating func clearApnRegistrationID() {_uniqueStorage()._apnRegistrationID = nil} + + /// Does the user have notifications enabled for the given device address. + var notificationEnabled: Bool { + get {return _storage._notificationEnabled ?? true} + set {_uniqueStorage()._notificationEnabled = newValue} + } + /// Returns true if `notificationEnabled` has been explicitly set. + var hasNotificationEnabled: Bool {return _storage._notificationEnabled != nil} + /// Clears the value of `notificationEnabled`. Subsequent reads from it will return its default value. + mutating func clearNotificationEnabled() {_uniqueStorage()._notificationEnabled = nil} + + /// Used for device_address of DeviceInfo field 2, a Bluetooth Mac address for + /// the device (e.g., to be used with EasyUnlock) + var bluetoothMacAddress: String { + get {return _storage._bluetoothMacAddress ?? String()} + set {_uniqueStorage()._bluetoothMacAddress = newValue} + } + /// Returns true if `bluetoothMacAddress` has been explicitly set. + var hasBluetoothMacAddress: Bool {return _storage._bluetoothMacAddress != nil} + /// Clears the value of `bluetoothMacAddress`. Subsequent reads from it will return its default value. + mutating func clearBluetoothMacAddress() {_uniqueStorage()._bluetoothMacAddress = nil} + + /// SHA-256 hash of the device master key (from the key exchange). + /// Differs from DeviceInfo field 3, which contains the actual master key. + var deviceMasterKeyHash: Data { + get {return _storage._deviceMasterKeyHash ?? Data()} + set {_uniqueStorage()._deviceMasterKeyHash = newValue} + } + /// Returns true if `deviceMasterKeyHash` has been explicitly set. + var hasDeviceMasterKeyHash: Bool {return _storage._deviceMasterKeyHash != nil} + /// Clears the value of `deviceMasterKeyHash`. Subsequent reads from it will return its default value. + mutating func clearDeviceMasterKeyHash() {_uniqueStorage()._deviceMasterKeyHash = nil} + + /// A SecureMessage.EcP256PublicKey + var userPublicKey: Data { + get {return _storage._userPublicKey ?? Data()} + set {_uniqueStorage()._userPublicKey = newValue} + } + /// Returns true if `userPublicKey` has been explicitly set. + var hasUserPublicKey: Bool {return _storage._userPublicKey != nil} + /// Clears the value of `userPublicKey`. Subsequent reads from it will return its default value. + mutating func clearUserPublicKey() {_uniqueStorage()._userPublicKey = nil} + + /// device's model name + /// (e.g., an android.os.Build.MODEL or UIDevice.model) + var deviceModel: String { + get {return _storage._deviceModel ?? String()} + set {_uniqueStorage()._deviceModel = newValue} + } + /// Returns true if `deviceModel` has been explicitly set. + var hasDeviceModel: Bool {return _storage._deviceModel != nil} + /// Clears the value of `deviceModel`. Subsequent reads from it will return its default value. + mutating func clearDeviceModel() {_uniqueStorage()._deviceModel = nil} + + /// device's locale + var locale: String { + get {return _storage._locale ?? String()} + set {_uniqueStorage()._locale = newValue} + } + /// Returns true if `locale` has been explicitly set. + var hasLocale: Bool {return _storage._locale != nil} + /// Clears the value of `locale`. Subsequent reads from it will return its default value. + mutating func clearLocale() {_uniqueStorage()._locale = nil} + + /// The handle for user_public_key (and implicitly, a master key) + var keyHandle: Data { + get {return _storage._keyHandle ?? Data()} + set {_uniqueStorage()._keyHandle = newValue} + } + /// Returns true if `keyHandle` has been explicitly set. + var hasKeyHandle: Bool {return _storage._keyHandle != nil} + /// Clears the value of `keyHandle`. Subsequent reads from it will return its default value. + mutating func clearKeyHandle() {_uniqueStorage()._keyHandle = nil} + + /// The initial counter value for the device, sent by the device + var counter: Int64 { + get {return _storage._counter ?? 0} + set {_uniqueStorage()._counter = newValue} + } + /// Returns true if `counter` has been explicitly set. + var hasCounter: Bool {return _storage._counter != nil} + /// Clears the value of `counter`. Subsequent reads from it will return its default value. + mutating func clearCounter() {_uniqueStorage()._counter = nil} + + /// The Operating System version on the device + /// (e.g., an android.os.Build.DISPLAY or UIDevice.systemVersion) + var deviceOsVersion: String { + get {return _storage._deviceOsVersion ?? String()} + set {_uniqueStorage()._deviceOsVersion = newValue} + } + /// Returns true if `deviceOsVersion` has been explicitly set. + var hasDeviceOsVersion: Bool {return _storage._deviceOsVersion != nil} + /// Clears the value of `deviceOsVersion`. Subsequent reads from it will return its default value. + mutating func clearDeviceOsVersion() {_uniqueStorage()._deviceOsVersion = nil} + + /// The Operating System version number on the device + /// (e.g., an android.os.Build.VERSION.SDK_INT) + var deviceOsVersionCode: Int64 { + get {return _storage._deviceOsVersionCode ?? 0} + set {_uniqueStorage()._deviceOsVersionCode = newValue} + } + /// Returns true if `deviceOsVersionCode` has been explicitly set. + var hasDeviceOsVersionCode: Bool {return _storage._deviceOsVersionCode != nil} + /// Clears the value of `deviceOsVersionCode`. Subsequent reads from it will return its default value. + mutating func clearDeviceOsVersionCode() {_uniqueStorage()._deviceOsVersionCode = nil} + + /// The Operating System release on the device + /// (e.g., an android.os.Build.VERSION.RELEASE) + var deviceOsRelease: String { + get {return _storage._deviceOsRelease ?? String()} + set {_uniqueStorage()._deviceOsRelease = newValue} + } + /// Returns true if `deviceOsRelease` has been explicitly set. + var hasDeviceOsRelease: Bool {return _storage._deviceOsRelease != nil} + /// Clears the value of `deviceOsRelease`. Subsequent reads from it will return its default value. + mutating func clearDeviceOsRelease() {_uniqueStorage()._deviceOsRelease = nil} + + /// The Operating System codename on the device + /// (e.g., an android.os.Build.VERSION.CODENAME or UIDevice.systemName) + var deviceOsCodename: String { + get {return _storage._deviceOsCodename ?? String()} + set {_uniqueStorage()._deviceOsCodename = newValue} + } + /// Returns true if `deviceOsCodename` has been explicitly set. + var hasDeviceOsCodename: Bool {return _storage._deviceOsCodename != nil} + /// Clears the value of `deviceOsCodename`. Subsequent reads from it will return its default value. + mutating func clearDeviceOsCodename() {_uniqueStorage()._deviceOsCodename = nil} + + /// The software version running on the device + /// (e.g., Authenticator app version string) + var deviceSoftwareVersion: String { + get {return _storage._deviceSoftwareVersion ?? String()} + set {_uniqueStorage()._deviceSoftwareVersion = newValue} + } + /// Returns true if `deviceSoftwareVersion` has been explicitly set. + var hasDeviceSoftwareVersion: Bool {return _storage._deviceSoftwareVersion != nil} + /// Clears the value of `deviceSoftwareVersion`. Subsequent reads from it will return its default value. + mutating func clearDeviceSoftwareVersion() {_uniqueStorage()._deviceSoftwareVersion = nil} + + /// The software version number running on the device + /// (e.g., Authenticator app version code) + var deviceSoftwareVersionCode: Int64 { + get {return _storage._deviceSoftwareVersionCode ?? 0} + set {_uniqueStorage()._deviceSoftwareVersionCode = newValue} + } + /// Returns true if `deviceSoftwareVersionCode` has been explicitly set. + var hasDeviceSoftwareVersionCode: Bool {return _storage._deviceSoftwareVersionCode != nil} + /// Clears the value of `deviceSoftwareVersionCode`. Subsequent reads from it will return its default value. + mutating func clearDeviceSoftwareVersionCode() {_uniqueStorage()._deviceSoftwareVersionCode = nil} + + /// Software package information if applicable + /// (e.g., com.google.android.apps.authenticator2) + var deviceSoftwarePackage: String { + get {return _storage._deviceSoftwarePackage ?? String()} + set {_uniqueStorage()._deviceSoftwarePackage = newValue} + } + /// Returns true if `deviceSoftwarePackage` has been explicitly set. + var hasDeviceSoftwarePackage: Bool {return _storage._deviceSoftwarePackage != nil} + /// Clears the value of `deviceSoftwarePackage`. Subsequent reads from it will return its default value. + mutating func clearDeviceSoftwarePackage() {_uniqueStorage()._deviceSoftwarePackage = nil} + + /// Size of the display in thousandths of an inch (e.g., 7000 mils = 7 in) + var deviceDisplayDiagonalMils: Int32 { + get {return _storage._deviceDisplayDiagonalMils ?? 0} + set {_uniqueStorage()._deviceDisplayDiagonalMils = newValue} + } + /// Returns true if `deviceDisplayDiagonalMils` has been explicitly set. + var hasDeviceDisplayDiagonalMils: Bool {return _storage._deviceDisplayDiagonalMils != nil} + /// Clears the value of `deviceDisplayDiagonalMils`. Subsequent reads from it will return its default value. + mutating func clearDeviceDisplayDiagonalMils() {_uniqueStorage()._deviceDisplayDiagonalMils = nil} + + /// For Authzen capable devices, their Authzen protocol version + var deviceAuthzenVersion: Int32 { + get {return _storage._deviceAuthzenVersion ?? 0} + set {_uniqueStorage()._deviceAuthzenVersion = newValue} + } + /// Returns true if `deviceAuthzenVersion` has been explicitly set. + var hasDeviceAuthzenVersion: Bool {return _storage._deviceAuthzenVersion != nil} + /// Clears the value of `deviceAuthzenVersion`. Subsequent reads from it will return its default value. + mutating func clearDeviceAuthzenVersion() {_uniqueStorage()._deviceAuthzenVersion = nil} + + /// Not all devices have device identifiers that fit in 64 bits. + var longDeviceID: Data { + get {return _storage._longDeviceID ?? Data()} + set {_uniqueStorage()._longDeviceID = newValue} + } + /// Returns true if `longDeviceID` has been explicitly set. + var hasLongDeviceID: Bool {return _storage._longDeviceID != nil} + /// Clears the value of `longDeviceID`. Subsequent reads from it will return its default value. + mutating func clearLongDeviceID() {_uniqueStorage()._longDeviceID = nil} + + /// The device manufacturer name + /// (e.g., android.os.Build.MANUFACTURER) + var deviceManufacturer: String { + get {return _storage._deviceManufacturer ?? String()} + set {_uniqueStorage()._deviceManufacturer = newValue} + } + /// Returns true if `deviceManufacturer` has been explicitly set. + var hasDeviceManufacturer: Bool {return _storage._deviceManufacturer != nil} + /// Clears the value of `deviceManufacturer`. Subsequent reads from it will return its default value. + mutating func clearDeviceManufacturer() {_uniqueStorage()._deviceManufacturer = nil} + + /// Used to indicate which type of device this is. + var deviceType: Securegcm_DeviceType { + get {return _storage._deviceType ?? .android} + set {_uniqueStorage()._deviceType = newValue} + } + /// Returns true if `deviceType` has been explicitly set. + var hasDeviceType: Bool {return _storage._deviceType != nil} + /// Clears the value of `deviceType`. Subsequent reads from it will return its default value. + mutating func clearDeviceType() {_uniqueStorage()._deviceType = nil} + + /// Is this device using a secure screenlock (e.g., pattern or pin unlock) + var usingSecureScreenlock: Bool { + get {return _storage._usingSecureScreenlock ?? false} + set {_uniqueStorage()._usingSecureScreenlock = newValue} + } + /// Returns true if `usingSecureScreenlock` has been explicitly set. + var hasUsingSecureScreenlock: Bool {return _storage._usingSecureScreenlock != nil} + /// Clears the value of `usingSecureScreenlock`. Subsequent reads from it will return its default value. + mutating func clearUsingSecureScreenlock() {_uniqueStorage()._usingSecureScreenlock = nil} + + /// Is auto-unlocking the screenlock (e.g., when at "home") supported? + var autoUnlockScreenlockSupported: Bool { + get {return _storage._autoUnlockScreenlockSupported ?? false} + set {_uniqueStorage()._autoUnlockScreenlockSupported = newValue} + } + /// Returns true if `autoUnlockScreenlockSupported` has been explicitly set. + var hasAutoUnlockScreenlockSupported: Bool {return _storage._autoUnlockScreenlockSupported != nil} + /// Clears the value of `autoUnlockScreenlockSupported`. Subsequent reads from it will return its default value. + mutating func clearAutoUnlockScreenlockSupported() {_uniqueStorage()._autoUnlockScreenlockSupported = nil} + + /// Is auto-unlocking the screenlock (e.g., when at "home") enabled? + var autoUnlockScreenlockEnabled: Bool { + get {return _storage._autoUnlockScreenlockEnabled ?? false} + set {_uniqueStorage()._autoUnlockScreenlockEnabled = newValue} + } + /// Returns true if `autoUnlockScreenlockEnabled` has been explicitly set. + var hasAutoUnlockScreenlockEnabled: Bool {return _storage._autoUnlockScreenlockEnabled != nil} + /// Clears the value of `autoUnlockScreenlockEnabled`. Subsequent reads from it will return its default value. + mutating func clearAutoUnlockScreenlockEnabled() {_uniqueStorage()._autoUnlockScreenlockEnabled = nil} + + /// Does the device have a Bluetooth (classic) radio? + var bluetoothRadioSupported: Bool { + get {return _storage._bluetoothRadioSupported ?? false} + set {_uniqueStorage()._bluetoothRadioSupported = newValue} + } + /// Returns true if `bluetoothRadioSupported` has been explicitly set. + var hasBluetoothRadioSupported: Bool {return _storage._bluetoothRadioSupported != nil} + /// Clears the value of `bluetoothRadioSupported`. Subsequent reads from it will return its default value. + mutating func clearBluetoothRadioSupported() {_uniqueStorage()._bluetoothRadioSupported = nil} + + /// Is the Bluetooth (classic) radio on? + var bluetoothRadioEnabled: Bool { + get {return _storage._bluetoothRadioEnabled ?? false} + set {_uniqueStorage()._bluetoothRadioEnabled = newValue} + } + /// Returns true if `bluetoothRadioEnabled` has been explicitly set. + var hasBluetoothRadioEnabled: Bool {return _storage._bluetoothRadioEnabled != nil} + /// Clears the value of `bluetoothRadioEnabled`. Subsequent reads from it will return its default value. + mutating func clearBluetoothRadioEnabled() {_uniqueStorage()._bluetoothRadioEnabled = nil} + + /// Does the device hardware support a mobile data connection? + var mobileDataSupported: Bool { + get {return _storage._mobileDataSupported ?? false} + set {_uniqueStorage()._mobileDataSupported = newValue} + } + /// Returns true if `mobileDataSupported` has been explicitly set. + var hasMobileDataSupported: Bool {return _storage._mobileDataSupported != nil} + /// Clears the value of `mobileDataSupported`. Subsequent reads from it will return its default value. + mutating func clearMobileDataSupported() {_uniqueStorage()._mobileDataSupported = nil} + + /// Does the device support tethering? + var tetheringSupported: Bool { + get {return _storage._tetheringSupported ?? false} + set {_uniqueStorage()._tetheringSupported = newValue} + } + /// Returns true if `tetheringSupported` has been explicitly set. + var hasTetheringSupported: Bool {return _storage._tetheringSupported != nil} + /// Clears the value of `tetheringSupported`. Subsequent reads from it will return its default value. + mutating func clearTetheringSupported() {_uniqueStorage()._tetheringSupported = nil} + + /// Does the device have a BLE radio? + var bleRadioSupported: Bool { + get {return _storage._bleRadioSupported ?? false} + set {_uniqueStorage()._bleRadioSupported = newValue} + } + /// Returns true if `bleRadioSupported` has been explicitly set. + var hasBleRadioSupported: Bool {return _storage._bleRadioSupported != nil} + /// Clears the value of `bleRadioSupported`. Subsequent reads from it will return its default value. + mutating func clearBleRadioSupported() {_uniqueStorage()._bleRadioSupported = nil} + + /// Is the device a "Pixel Experience" Android device? + var pixelExperience: Bool { + get {return _storage._pixelExperience ?? false} + set {_uniqueStorage()._pixelExperience = newValue} + } + /// Returns true if `pixelExperience` has been explicitly set. + var hasPixelExperience: Bool {return _storage._pixelExperience != nil} + /// Clears the value of `pixelExperience`. Subsequent reads from it will return its default value. + mutating func clearPixelExperience() {_uniqueStorage()._pixelExperience = nil} + + /// Is the device running in the ARC++ container on a chromebook? + var arcPlusPlus: Bool { + get {return _storage._arcPlusPlus ?? false} + set {_uniqueStorage()._arcPlusPlus = newValue} + } + /// Returns true if `arcPlusPlus` has been explicitly set. + var hasArcPlusPlus: Bool {return _storage._arcPlusPlus != nil} + /// Clears the value of `arcPlusPlus`. Subsequent reads from it will return its default value. + mutating func clearArcPlusPlus() {_uniqueStorage()._arcPlusPlus = nil} + + /// Is the value set in |using_secure_screenlock| reliable? On some Android + /// devices, the platform API to get the screenlock state is not trustworthy. + /// See b/32212161. + var isScreenlockStateFlaky: Bool { + get {return _storage._isScreenlockStateFlaky ?? false} + set {_uniqueStorage()._isScreenlockStateFlaky = newValue} + } + /// Returns true if `isScreenlockStateFlaky` has been explicitly set. + var hasIsScreenlockStateFlaky: Bool {return _storage._isScreenlockStateFlaky != nil} + /// Clears the value of `isScreenlockStateFlaky`. Subsequent reads from it will return its default value. + mutating func clearIsScreenlockStateFlaky() {_uniqueStorage()._isScreenlockStateFlaky = nil} + + /// A list of multi-device software features supported by the device. + var supportedSoftwareFeatures: [Securegcm_SoftwareFeature] { + get {return _storage._supportedSoftwareFeatures} + set {_uniqueStorage()._supportedSoftwareFeatures = newValue} + } + + /// A list of multi-device software features currently enabled (active) on the + /// device. + var enabledSoftwareFeatures: [Securegcm_SoftwareFeature] { + get {return _storage._enabledSoftwareFeatures} + set {_uniqueStorage()._enabledSoftwareFeatures = newValue} + } + + /// The enrollment session id this is sent with + var enrollmentSessionID: Data { + get {return _storage._enrollmentSessionID ?? Data()} + set {_uniqueStorage()._enrollmentSessionID = newValue} + } + /// Returns true if `enrollmentSessionID` has been explicitly set. + var hasEnrollmentSessionID: Bool {return _storage._enrollmentSessionID != nil} + /// Clears the value of `enrollmentSessionID`. Subsequent reads from it will return its default value. + mutating func clearEnrollmentSessionID() {_uniqueStorage()._enrollmentSessionID = nil} + + /// A copy of the user's OAuth token + var oauthToken: String { + get {return _storage._oauthToken ?? String()} + set {_uniqueStorage()._oauthToken = newValue} + } + /// Returns true if `oauthToken` has been explicitly set. + var hasOauthToken: Bool {return _storage._oauthToken != nil} + /// Clears the value of `oauthToken`. Subsequent reads from it will return its default value. + mutating func clearOauthToken() {_uniqueStorage()._oauthToken = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _storage = _StorageClass.defaultInstance +} + +struct Securegcm_GcmMetadata { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var type: Securegcm_Type { + get {return _type ?? .enrollment} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + var version: Int32 { + get {return _version ?? 0} + set {_version = newValue} + } + /// Returns true if `version` has been explicitly set. + var hasVersion: Bool {return self._version != nil} + /// Clears the value of `version`. Subsequent reads from it will return its default value. + mutating func clearVersion() {self._version = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _type: Securegcm_Type? = nil + fileprivate var _version: Int32? = nil +} + +struct Securegcm_Tickle { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Time after which this tickle should expire + var expiryTime: UInt64 { + get {return _expiryTime ?? 0} + set {_expiryTime = newValue} + } + /// Returns true if `expiryTime` has been explicitly set. + var hasExpiryTime: Bool {return self._expiryTime != nil} + /// Clears the value of `expiryTime`. Subsequent reads from it will return its default value. + mutating func clearExpiryTime() {self._expiryTime = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _expiryTime: UInt64? = nil +} + +struct Securegcm_LoginNotificationInfo { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Time at which the server received the login notification request. + var creationTime: UInt64 { + get {return _creationTime ?? 0} + set {_creationTime = newValue} + } + /// Returns true if `creationTime` has been explicitly set. + var hasCreationTime: Bool {return self._creationTime != nil} + /// Clears the value of `creationTime`. Subsequent reads from it will return its default value. + mutating func clearCreationTime() {self._creationTime = nil} + + /// Must correspond to user_id in LoginNotificationRequest, if set. + var email: String { + get {return _email ?? String()} + set {_email = newValue} + } + /// Returns true if `email` has been explicitly set. + var hasEmail: Bool {return self._email != nil} + /// Clears the value of `email`. Subsequent reads from it will return its default value. + mutating func clearEmail() {self._email = nil} + + /// Host where the user's credentials were used to login, if meaningful. + var host: String { + get {return _host ?? String()} + set {_host = newValue} + } + /// Returns true if `host` has been explicitly set. + var hasHost: Bool {return self._host != nil} + /// Clears the value of `host`. Subsequent reads from it will return its default value. + mutating func clearHost() {self._host = nil} + + /// Location from where the user's credentials were used, if meaningful. + var source: String { + get {return _source ?? String()} + set {_source = newValue} + } + /// Returns true if `source` has been explicitly set. + var hasSource: Bool {return self._source != nil} + /// Clears the value of `source`. Subsequent reads from it will return its default value. + mutating func clearSource() {self._source = nil} + + /// Type of login, e.g. ssh, gnome-screensaver, or web. + var eventType: String { + get {return _eventType ?? String()} + set {_eventType = newValue} + } + /// Returns true if `eventType` has been explicitly set. + var hasEventType: Bool {return self._eventType != nil} + /// Clears the value of `eventType`. Subsequent reads from it will return its default value. + mutating func clearEventType() {self._eventType = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _creationTime: UInt64? = nil + fileprivate var _email: String? = nil + fileprivate var _host: String? = nil + fileprivate var _source: String? = nil + fileprivate var _eventType: String? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Securegcm_AppleDeviceDiagonalMils: @unchecked Sendable {} +extension Securegcm_DeviceType: @unchecked Sendable {} +extension Securegcm_SoftwareFeature: @unchecked Sendable {} +extension Securegcm_InvocationReason: @unchecked Sendable {} +extension Securegcm_Type: @unchecked Sendable {} +extension Securegcm_GcmDeviceInfo: @unchecked Sendable {} +extension Securegcm_GcmMetadata: @unchecked Sendable {} +extension Securegcm_Tickle: @unchecked Sendable {} +extension Securegcm_LoginNotificationInfo: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "securegcm" + +extension Securegcm_AppleDeviceDiagonalMils: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 4000: .same(proto: "APPLE_PHONE"), + 7900: .same(proto: "APPLE_PAD"), + ] +} + +extension Securegcm_DeviceType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN"), + 1: .same(proto: "ANDROID"), + 2: .same(proto: "CHROME"), + 3: .same(proto: "IOS"), + 4: .same(proto: "BROWSER"), + 5: .same(proto: "OSX"), + ] +} + +extension Securegcm_SoftwareFeature: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_FEATURE"), + 1: .same(proto: "BETTER_TOGETHER_HOST"), + 2: .same(proto: "BETTER_TOGETHER_CLIENT"), + 3: .same(proto: "EASY_UNLOCK_HOST"), + 4: .same(proto: "EASY_UNLOCK_CLIENT"), + 5: .same(proto: "MAGIC_TETHER_HOST"), + 6: .same(proto: "MAGIC_TETHER_CLIENT"), + 7: .same(proto: "SMS_CONNECT_HOST"), + 8: .same(proto: "SMS_CONNECT_CLIENT"), + ] +} + +extension Securegcm_InvocationReason: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "REASON_UNKNOWN"), + 1: .same(proto: "REASON_INITIALIZATION"), + 2: .same(proto: "REASON_PERIODIC"), + 3: .same(proto: "REASON_SLOW_PERIODIC"), + 4: .same(proto: "REASON_FAST_PERIODIC"), + 5: .same(proto: "REASON_EXPIRATION"), + 6: .same(proto: "REASON_FAILURE_RECOVERY"), + 7: .same(proto: "REASON_NEW_ACCOUNT"), + 8: .same(proto: "REASON_CHANGED_ACCOUNT"), + 9: .same(proto: "REASON_FEATURE_TOGGLED"), + 10: .same(proto: "REASON_SERVER_INITIATED"), + 11: .same(proto: "REASON_ADDRESS_CHANGE"), + 12: .same(proto: "REASON_SOFTWARE_UPDATE"), + 13: .same(proto: "REASON_MANUAL"), + 14: .same(proto: "REASON_CUSTOM_KEY_INVALIDATION"), + 15: .same(proto: "REASON_PROXIMITY_PERIODIC"), + ] +} + +extension Securegcm_Type: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "ENROLLMENT"), + 1: .same(proto: "TICKLE"), + 2: .same(proto: "TX_REQUEST"), + 3: .same(proto: "TX_REPLY"), + 4: .same(proto: "TX_SYNC_REQUEST"), + 5: .same(proto: "TX_SYNC_RESPONSE"), + 6: .same(proto: "TX_PING"), + 7: .same(proto: "DEVICE_INFO_UPDATE"), + 8: .same(proto: "TX_CANCEL_REQUEST"), + 10: .same(proto: "PROXIMITYAUTH_PAIRING"), + 11: .same(proto: "GCMV1_IDENTITY_ASSERTION"), + 12: .same(proto: "DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD"), + 13: .same(proto: "DEVICE_TO_DEVICE_MESSAGE"), + 14: .same(proto: "DEVICE_PROXIMITY_CALLBACK"), + 15: .same(proto: "UNLOCK_KEY_SIGNED_CHALLENGE"), + 101: .same(proto: "LOGIN_NOTIFICATION"), + ] +} + +extension Securegcm_GcmDeviceInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".GcmDeviceInfo" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "android_device_id"), + 102: .standard(proto: "gcm_registration_id"), + 202: .standard(proto: "apn_registration_id"), + 203: .standard(proto: "notification_enabled"), + 302: .standard(proto: "bluetooth_mac_address"), + 103: .standard(proto: "device_master_key_hash"), + 4: .standard(proto: "user_public_key"), + 7: .standard(proto: "device_model"), + 8: .same(proto: "locale"), + 9: .standard(proto: "key_handle"), + 12: .same(proto: "counter"), + 13: .standard(proto: "device_os_version"), + 14: .standard(proto: "device_os_version_code"), + 15: .standard(proto: "device_os_release"), + 16: .standard(proto: "device_os_codename"), + 17: .standard(proto: "device_software_version"), + 18: .standard(proto: "device_software_version_code"), + 19: .standard(proto: "device_software_package"), + 22: .standard(proto: "device_display_diagonal_mils"), + 24: .standard(proto: "device_authzen_version"), + 29: .standard(proto: "long_device_id"), + 31: .standard(proto: "device_manufacturer"), + 32: .standard(proto: "device_type"), + 400: .standard(proto: "using_secure_screenlock"), + 401: .standard(proto: "auto_unlock_screenlock_supported"), + 402: .standard(proto: "auto_unlock_screenlock_enabled"), + 403: .standard(proto: "bluetooth_radio_supported"), + 404: .standard(proto: "bluetooth_radio_enabled"), + 405: .standard(proto: "mobile_data_supported"), + 406: .standard(proto: "tethering_supported"), + 407: .standard(proto: "ble_radio_supported"), + 408: .standard(proto: "pixel_experience"), + 409: .standard(proto: "arc_plus_plus"), + 410: .standard(proto: "is_screenlock_state_flaky"), + 411: .standard(proto: "supported_software_features"), + 412: .standard(proto: "enabled_software_features"), + 1000: .standard(proto: "enrollment_session_id"), + 1001: .standard(proto: "oauth_token"), + ] + + fileprivate class _StorageClass { + var _androidDeviceID: UInt64? = nil + var _gcmRegistrationID: Data? = nil + var _apnRegistrationID: Data? = nil + var _notificationEnabled: Bool? = nil + var _bluetoothMacAddress: String? = nil + var _deviceMasterKeyHash: Data? = nil + var _userPublicKey: Data? = nil + var _deviceModel: String? = nil + var _locale: String? = nil + var _keyHandle: Data? = nil + var _counter: Int64? = nil + var _deviceOsVersion: String? = nil + var _deviceOsVersionCode: Int64? = nil + var _deviceOsRelease: String? = nil + var _deviceOsCodename: String? = nil + var _deviceSoftwareVersion: String? = nil + var _deviceSoftwareVersionCode: Int64? = nil + var _deviceSoftwarePackage: String? = nil + var _deviceDisplayDiagonalMils: Int32? = nil + var _deviceAuthzenVersion: Int32? = nil + var _longDeviceID: Data? = nil + var _deviceManufacturer: String? = nil + var _deviceType: Securegcm_DeviceType? = nil + var _usingSecureScreenlock: Bool? = nil + var _autoUnlockScreenlockSupported: Bool? = nil + var _autoUnlockScreenlockEnabled: Bool? = nil + var _bluetoothRadioSupported: Bool? = nil + var _bluetoothRadioEnabled: Bool? = nil + var _mobileDataSupported: Bool? = nil + var _tetheringSupported: Bool? = nil + var _bleRadioSupported: Bool? = nil + var _pixelExperience: Bool? = nil + var _arcPlusPlus: Bool? = nil + var _isScreenlockStateFlaky: Bool? = nil + var _supportedSoftwareFeatures: [Securegcm_SoftwareFeature] = [] + var _enabledSoftwareFeatures: [Securegcm_SoftwareFeature] = [] + var _enrollmentSessionID: Data? = nil + var _oauthToken: String? = nil + + static let defaultInstance = _StorageClass() + + private init() {} + + init(copying source: _StorageClass) { + _androidDeviceID = source._androidDeviceID + _gcmRegistrationID = source._gcmRegistrationID + _apnRegistrationID = source._apnRegistrationID + _notificationEnabled = source._notificationEnabled + _bluetoothMacAddress = source._bluetoothMacAddress + _deviceMasterKeyHash = source._deviceMasterKeyHash + _userPublicKey = source._userPublicKey + _deviceModel = source._deviceModel + _locale = source._locale + _keyHandle = source._keyHandle + _counter = source._counter + _deviceOsVersion = source._deviceOsVersion + _deviceOsVersionCode = source._deviceOsVersionCode + _deviceOsRelease = source._deviceOsRelease + _deviceOsCodename = source._deviceOsCodename + _deviceSoftwareVersion = source._deviceSoftwareVersion + _deviceSoftwareVersionCode = source._deviceSoftwareVersionCode + _deviceSoftwarePackage = source._deviceSoftwarePackage + _deviceDisplayDiagonalMils = source._deviceDisplayDiagonalMils + _deviceAuthzenVersion = source._deviceAuthzenVersion + _longDeviceID = source._longDeviceID + _deviceManufacturer = source._deviceManufacturer + _deviceType = source._deviceType + _usingSecureScreenlock = source._usingSecureScreenlock + _autoUnlockScreenlockSupported = source._autoUnlockScreenlockSupported + _autoUnlockScreenlockEnabled = source._autoUnlockScreenlockEnabled + _bluetoothRadioSupported = source._bluetoothRadioSupported + _bluetoothRadioEnabled = source._bluetoothRadioEnabled + _mobileDataSupported = source._mobileDataSupported + _tetheringSupported = source._tetheringSupported + _bleRadioSupported = source._bleRadioSupported + _pixelExperience = source._pixelExperience + _arcPlusPlus = source._arcPlusPlus + _isScreenlockStateFlaky = source._isScreenlockStateFlaky + _supportedSoftwareFeatures = source._supportedSoftwareFeatures + _enabledSoftwareFeatures = source._enabledSoftwareFeatures + _enrollmentSessionID = source._enrollmentSessionID + _oauthToken = source._oauthToken + } + } + + fileprivate mutating func _uniqueStorage() -> _StorageClass { + if !isKnownUniquelyReferenced(&_storage) { + _storage = _StorageClass(copying: _storage) + } + return _storage + } + + public var isInitialized: Bool { + return withExtendedLifetime(_storage) { (_storage: _StorageClass) in + if _storage._userPublicKey == nil {return false} + return true + } + } + + mutating func decodeMessage(decoder: inout D) throws { + _ = _uniqueStorage() + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularFixed64Field(value: &_storage._androidDeviceID) }() + case 4: try { try decoder.decodeSingularBytesField(value: &_storage._userPublicKey) }() + case 7: try { try decoder.decodeSingularStringField(value: &_storage._deviceModel) }() + case 8: try { try decoder.decodeSingularStringField(value: &_storage._locale) }() + case 9: try { try decoder.decodeSingularBytesField(value: &_storage._keyHandle) }() + case 12: try { try decoder.decodeSingularInt64Field(value: &_storage._counter) }() + case 13: try { try decoder.decodeSingularStringField(value: &_storage._deviceOsVersion) }() + case 14: try { try decoder.decodeSingularInt64Field(value: &_storage._deviceOsVersionCode) }() + case 15: try { try decoder.decodeSingularStringField(value: &_storage._deviceOsRelease) }() + case 16: try { try decoder.decodeSingularStringField(value: &_storage._deviceOsCodename) }() + case 17: try { try decoder.decodeSingularStringField(value: &_storage._deviceSoftwareVersion) }() + case 18: try { try decoder.decodeSingularInt64Field(value: &_storage._deviceSoftwareVersionCode) }() + case 19: try { try decoder.decodeSingularStringField(value: &_storage._deviceSoftwarePackage) }() + case 22: try { try decoder.decodeSingularInt32Field(value: &_storage._deviceDisplayDiagonalMils) }() + case 24: try { try decoder.decodeSingularInt32Field(value: &_storage._deviceAuthzenVersion) }() + case 29: try { try decoder.decodeSingularBytesField(value: &_storage._longDeviceID) }() + case 31: try { try decoder.decodeSingularStringField(value: &_storage._deviceManufacturer) }() + case 32: try { try decoder.decodeSingularEnumField(value: &_storage._deviceType) }() + case 102: try { try decoder.decodeSingularBytesField(value: &_storage._gcmRegistrationID) }() + case 103: try { try decoder.decodeSingularBytesField(value: &_storage._deviceMasterKeyHash) }() + case 202: try { try decoder.decodeSingularBytesField(value: &_storage._apnRegistrationID) }() + case 203: try { try decoder.decodeSingularBoolField(value: &_storage._notificationEnabled) }() + case 302: try { try decoder.decodeSingularStringField(value: &_storage._bluetoothMacAddress) }() + case 400: try { try decoder.decodeSingularBoolField(value: &_storage._usingSecureScreenlock) }() + case 401: try { try decoder.decodeSingularBoolField(value: &_storage._autoUnlockScreenlockSupported) }() + case 402: try { try decoder.decodeSingularBoolField(value: &_storage._autoUnlockScreenlockEnabled) }() + case 403: try { try decoder.decodeSingularBoolField(value: &_storage._bluetoothRadioSupported) }() + case 404: try { try decoder.decodeSingularBoolField(value: &_storage._bluetoothRadioEnabled) }() + case 405: try { try decoder.decodeSingularBoolField(value: &_storage._mobileDataSupported) }() + case 406: try { try decoder.decodeSingularBoolField(value: &_storage._tetheringSupported) }() + case 407: try { try decoder.decodeSingularBoolField(value: &_storage._bleRadioSupported) }() + case 408: try { try decoder.decodeSingularBoolField(value: &_storage._pixelExperience) }() + case 409: try { try decoder.decodeSingularBoolField(value: &_storage._arcPlusPlus) }() + case 410: try { try decoder.decodeSingularBoolField(value: &_storage._isScreenlockStateFlaky) }() + case 411: try { try decoder.decodeRepeatedEnumField(value: &_storage._supportedSoftwareFeatures) }() + case 412: try { try decoder.decodeRepeatedEnumField(value: &_storage._enabledSoftwareFeatures) }() + case 1000: try { try decoder.decodeSingularBytesField(value: &_storage._enrollmentSessionID) }() + case 1001: try { try decoder.decodeSingularStringField(value: &_storage._oauthToken) }() + default: break + } + } + } + } + + func traverse(visitor: inout V) throws { + try withExtendedLifetime(_storage) { (_storage: _StorageClass) in + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = _storage._androidDeviceID { + try visitor.visitSingularFixed64Field(value: v, fieldNumber: 1) + } }() + try { if let v = _storage._userPublicKey { + try visitor.visitSingularBytesField(value: v, fieldNumber: 4) + } }() + try { if let v = _storage._deviceModel { + try visitor.visitSingularStringField(value: v, fieldNumber: 7) + } }() + try { if let v = _storage._locale { + try visitor.visitSingularStringField(value: v, fieldNumber: 8) + } }() + try { if let v = _storage._keyHandle { + try visitor.visitSingularBytesField(value: v, fieldNumber: 9) + } }() + try { if let v = _storage._counter { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 12) + } }() + try { if let v = _storage._deviceOsVersion { + try visitor.visitSingularStringField(value: v, fieldNumber: 13) + } }() + try { if let v = _storage._deviceOsVersionCode { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 14) + } }() + try { if let v = _storage._deviceOsRelease { + try visitor.visitSingularStringField(value: v, fieldNumber: 15) + } }() + try { if let v = _storage._deviceOsCodename { + try visitor.visitSingularStringField(value: v, fieldNumber: 16) + } }() + try { if let v = _storage._deviceSoftwareVersion { + try visitor.visitSingularStringField(value: v, fieldNumber: 17) + } }() + try { if let v = _storage._deviceSoftwareVersionCode { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 18) + } }() + try { if let v = _storage._deviceSoftwarePackage { + try visitor.visitSingularStringField(value: v, fieldNumber: 19) + } }() + try { if let v = _storage._deviceDisplayDiagonalMils { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 22) + } }() + try { if let v = _storage._deviceAuthzenVersion { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 24) + } }() + try { if let v = _storage._longDeviceID { + try visitor.visitSingularBytesField(value: v, fieldNumber: 29) + } }() + try { if let v = _storage._deviceManufacturer { + try visitor.visitSingularStringField(value: v, fieldNumber: 31) + } }() + try { if let v = _storage._deviceType { + try visitor.visitSingularEnumField(value: v, fieldNumber: 32) + } }() + try { if let v = _storage._gcmRegistrationID { + try visitor.visitSingularBytesField(value: v, fieldNumber: 102) + } }() + try { if let v = _storage._deviceMasterKeyHash { + try visitor.visitSingularBytesField(value: v, fieldNumber: 103) + } }() + try { if let v = _storage._apnRegistrationID { + try visitor.visitSingularBytesField(value: v, fieldNumber: 202) + } }() + try { if let v = _storage._notificationEnabled { + try visitor.visitSingularBoolField(value: v, fieldNumber: 203) + } }() + try { if let v = _storage._bluetoothMacAddress { + try visitor.visitSingularStringField(value: v, fieldNumber: 302) + } }() + try { if let v = _storage._usingSecureScreenlock { + try visitor.visitSingularBoolField(value: v, fieldNumber: 400) + } }() + try { if let v = _storage._autoUnlockScreenlockSupported { + try visitor.visitSingularBoolField(value: v, fieldNumber: 401) + } }() + try { if let v = _storage._autoUnlockScreenlockEnabled { + try visitor.visitSingularBoolField(value: v, fieldNumber: 402) + } }() + try { if let v = _storage._bluetoothRadioSupported { + try visitor.visitSingularBoolField(value: v, fieldNumber: 403) + } }() + try { if let v = _storage._bluetoothRadioEnabled { + try visitor.visitSingularBoolField(value: v, fieldNumber: 404) + } }() + try { if let v = _storage._mobileDataSupported { + try visitor.visitSingularBoolField(value: v, fieldNumber: 405) + } }() + try { if let v = _storage._tetheringSupported { + try visitor.visitSingularBoolField(value: v, fieldNumber: 406) + } }() + try { if let v = _storage._bleRadioSupported { + try visitor.visitSingularBoolField(value: v, fieldNumber: 407) + } }() + try { if let v = _storage._pixelExperience { + try visitor.visitSingularBoolField(value: v, fieldNumber: 408) + } }() + try { if let v = _storage._arcPlusPlus { + try visitor.visitSingularBoolField(value: v, fieldNumber: 409) + } }() + try { if let v = _storage._isScreenlockStateFlaky { + try visitor.visitSingularBoolField(value: v, fieldNumber: 410) + } }() + if !_storage._supportedSoftwareFeatures.isEmpty { + try visitor.visitRepeatedEnumField(value: _storage._supportedSoftwareFeatures, fieldNumber: 411) + } + if !_storage._enabledSoftwareFeatures.isEmpty { + try visitor.visitRepeatedEnumField(value: _storage._enabledSoftwareFeatures, fieldNumber: 412) + } + try { if let v = _storage._enrollmentSessionID { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1000) + } }() + try { if let v = _storage._oauthToken { + try visitor.visitSingularStringField(value: v, fieldNumber: 1001) + } }() + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_GcmDeviceInfo, rhs: Securegcm_GcmDeviceInfo) -> Bool { + if lhs._storage !== rhs._storage { + let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in + let _storage = _args.0 + let rhs_storage = _args.1 + if _storage._androidDeviceID != rhs_storage._androidDeviceID {return false} + if _storage._gcmRegistrationID != rhs_storage._gcmRegistrationID {return false} + if _storage._apnRegistrationID != rhs_storage._apnRegistrationID {return false} + if _storage._notificationEnabled != rhs_storage._notificationEnabled {return false} + if _storage._bluetoothMacAddress != rhs_storage._bluetoothMacAddress {return false} + if _storage._deviceMasterKeyHash != rhs_storage._deviceMasterKeyHash {return false} + if _storage._userPublicKey != rhs_storage._userPublicKey {return false} + if _storage._deviceModel != rhs_storage._deviceModel {return false} + if _storage._locale != rhs_storage._locale {return false} + if _storage._keyHandle != rhs_storage._keyHandle {return false} + if _storage._counter != rhs_storage._counter {return false} + if _storage._deviceOsVersion != rhs_storage._deviceOsVersion {return false} + if _storage._deviceOsVersionCode != rhs_storage._deviceOsVersionCode {return false} + if _storage._deviceOsRelease != rhs_storage._deviceOsRelease {return false} + if _storage._deviceOsCodename != rhs_storage._deviceOsCodename {return false} + if _storage._deviceSoftwareVersion != rhs_storage._deviceSoftwareVersion {return false} + if _storage._deviceSoftwareVersionCode != rhs_storage._deviceSoftwareVersionCode {return false} + if _storage._deviceSoftwarePackage != rhs_storage._deviceSoftwarePackage {return false} + if _storage._deviceDisplayDiagonalMils != rhs_storage._deviceDisplayDiagonalMils {return false} + if _storage._deviceAuthzenVersion != rhs_storage._deviceAuthzenVersion {return false} + if _storage._longDeviceID != rhs_storage._longDeviceID {return false} + if _storage._deviceManufacturer != rhs_storage._deviceManufacturer {return false} + if _storage._deviceType != rhs_storage._deviceType {return false} + if _storage._usingSecureScreenlock != rhs_storage._usingSecureScreenlock {return false} + if _storage._autoUnlockScreenlockSupported != rhs_storage._autoUnlockScreenlockSupported {return false} + if _storage._autoUnlockScreenlockEnabled != rhs_storage._autoUnlockScreenlockEnabled {return false} + if _storage._bluetoothRadioSupported != rhs_storage._bluetoothRadioSupported {return false} + if _storage._bluetoothRadioEnabled != rhs_storage._bluetoothRadioEnabled {return false} + if _storage._mobileDataSupported != rhs_storage._mobileDataSupported {return false} + if _storage._tetheringSupported != rhs_storage._tetheringSupported {return false} + if _storage._bleRadioSupported != rhs_storage._bleRadioSupported {return false} + if _storage._pixelExperience != rhs_storage._pixelExperience {return false} + if _storage._arcPlusPlus != rhs_storage._arcPlusPlus {return false} + if _storage._isScreenlockStateFlaky != rhs_storage._isScreenlockStateFlaky {return false} + if _storage._supportedSoftwareFeatures != rhs_storage._supportedSoftwareFeatures {return false} + if _storage._enabledSoftwareFeatures != rhs_storage._enabledSoftwareFeatures {return false} + if _storage._enrollmentSessionID != rhs_storage._enrollmentSessionID {return false} + if _storage._oauthToken != rhs_storage._oauthToken {return false} + return true + } + if !storagesAreEqual {return false} + } + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_GcmMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".GcmMetadata" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .same(proto: "version"), + ] + + public var isInitialized: Bool { + if self._type == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._version) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._version { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_GcmMetadata, rhs: Securegcm_GcmMetadata) -> Bool { + if lhs._type != rhs._type {return false} + if lhs._version != rhs._version {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_Tickle: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Tickle" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "expiry_time"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularFixed64Field(value: &self._expiryTime) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._expiryTime { + try visitor.visitSingularFixed64Field(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_Tickle, rhs: Securegcm_Tickle) -> Bool { + if lhs._expiryTime != rhs._expiryTime {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_LoginNotificationInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".LoginNotificationInfo" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 2: .standard(proto: "creation_time"), + 3: .same(proto: "email"), + 4: .same(proto: "host"), + 5: .same(proto: "source"), + 6: .standard(proto: "event_type"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 2: try { try decoder.decodeSingularFixed64Field(value: &self._creationTime) }() + case 3: try { try decoder.decodeSingularStringField(value: &self._email) }() + case 4: try { try decoder.decodeSingularStringField(value: &self._host) }() + case 5: try { try decoder.decodeSingularStringField(value: &self._source) }() + case 6: try { try decoder.decodeSingularStringField(value: &self._eventType) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._creationTime { + try visitor.visitSingularFixed64Field(value: v, fieldNumber: 2) + } }() + try { if let v = self._email { + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + } }() + try { if let v = self._host { + try visitor.visitSingularStringField(value: v, fieldNumber: 4) + } }() + try { if let v = self._source { + try visitor.visitSingularStringField(value: v, fieldNumber: 5) + } }() + try { if let v = self._eventType { + try visitor.visitSingularStringField(value: v, fieldNumber: 6) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_LoginNotificationInfo, rhs: Securegcm_LoginNotificationInfo) -> Bool { + if lhs._creationTime != rhs._creationTime {return false} + if lhs._email != rhs._email {return false} + if lhs._host != rhs._host {return false} + if lhs._source != rhs._source {return false} + if lhs._eventType != rhs._eventType {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/submissions/sapphire/ProtobufGenerated/securemessage.pb.swift b/submissions/sapphire/ProtobufGenerated/securemessage.pb.swift new file mode 100644 index 00000000..eae8d016 --- /dev/null +++ b/submissions/sapphire/ProtobufGenerated/securemessage.pb.swift @@ -0,0 +1,951 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: securemessage.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Proto definitions for SecureMessage format + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// Supported "signature" schemes (both symmetric key and public key based) +enum Securemessage_SigScheme: SwiftProtobuf.Enum { + typealias RawValue = Int + case hmacSha256 // = 1 + case ecdsaP256Sha256 // = 2 + + /// Not recommended -- use ECDSA_P256_SHA256 instead + case rsa2048Sha256 // = 3 + + init() { + self = .hmacSha256 + } + + init?(rawValue: Int) { + switch rawValue { + case 1: self = .hmacSha256 + case 2: self = .ecdsaP256Sha256 + case 3: self = .rsa2048Sha256 + default: return nil + } + } + + var rawValue: Int { + switch self { + case .hmacSha256: return 1 + case .ecdsaP256Sha256: return 2 + case .rsa2048Sha256: return 3 + } + } + +} + +#if swift(>=4.2) + +extension Securemessage_SigScheme: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// Supported encryption schemes +enum Securemessage_EncScheme: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// No encryption + case none // = 1 + case aes256Cbc // = 2 + + init() { + self = .none + } + + init?(rawValue: Int) { + switch rawValue { + case 1: self = .none + case 2: self = .aes256Cbc + default: return nil + } + } + + var rawValue: Int { + switch self { + case .none: return 1 + case .aes256Cbc: return 2 + } + } + +} + +#if swift(>=4.2) + +extension Securemessage_EncScheme: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// A list of supported public key types +enum Securemessage_PublicKeyType: SwiftProtobuf.Enum { + typealias RawValue = Int + case ecP256 // = 1 + case rsa2048 // = 2 + + /// 2048-bit MODP group 14, from RFC 3526 + case dh2048Modp // = 3 + + init() { + self = .ecP256 + } + + init?(rawValue: Int) { + switch rawValue { + case 1: self = .ecP256 + case 2: self = .rsa2048 + case 3: self = .dh2048Modp + default: return nil + } + } + + var rawValue: Int { + switch self { + case .ecP256: return 1 + case .rsa2048: return 2 + case .dh2048Modp: return 3 + } + } + +} + +#if swift(>=4.2) + +extension Securemessage_PublicKeyType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Securemessage_SecureMessage { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Must contain a HeaderAndBody message + var headerAndBody: Data { + get {return _headerAndBody ?? Data()} + set {_headerAndBody = newValue} + } + /// Returns true if `headerAndBody` has been explicitly set. + var hasHeaderAndBody: Bool {return self._headerAndBody != nil} + /// Clears the value of `headerAndBody`. Subsequent reads from it will return its default value. + mutating func clearHeaderAndBody() {self._headerAndBody = nil} + + /// Signature of header_and_body + var signature: Data { + get {return _signature ?? Data()} + set {_signature = newValue} + } + /// Returns true if `signature` has been explicitly set. + var hasSignature: Bool {return self._signature != nil} + /// Clears the value of `signature`. Subsequent reads from it will return its default value. + mutating func clearSignature() {self._signature = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _headerAndBody: Data? = nil + fileprivate var _signature: Data? = nil +} + +struct Securemessage_Header { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var signatureScheme: Securemessage_SigScheme { + get {return _signatureScheme ?? .hmacSha256} + set {_signatureScheme = newValue} + } + /// Returns true if `signatureScheme` has been explicitly set. + var hasSignatureScheme: Bool {return self._signatureScheme != nil} + /// Clears the value of `signatureScheme`. Subsequent reads from it will return its default value. + mutating func clearSignatureScheme() {self._signatureScheme = nil} + + var encryptionScheme: Securemessage_EncScheme { + get {return _encryptionScheme ?? .none} + set {_encryptionScheme = newValue} + } + /// Returns true if `encryptionScheme` has been explicitly set. + var hasEncryptionScheme: Bool {return self._encryptionScheme != nil} + /// Clears the value of `encryptionScheme`. Subsequent reads from it will return its default value. + mutating func clearEncryptionScheme() {self._encryptionScheme = nil} + + /// Identifies the verification key + var verificationKeyID: Data { + get {return _verificationKeyID ?? Data()} + set {_verificationKeyID = newValue} + } + /// Returns true if `verificationKeyID` has been explicitly set. + var hasVerificationKeyID: Bool {return self._verificationKeyID != nil} + /// Clears the value of `verificationKeyID`. Subsequent reads from it will return its default value. + mutating func clearVerificationKeyID() {self._verificationKeyID = nil} + + /// Identifies the decryption key + var decryptionKeyID: Data { + get {return _decryptionKeyID ?? Data()} + set {_decryptionKeyID = newValue} + } + /// Returns true if `decryptionKeyID` has been explicitly set. + var hasDecryptionKeyID: Bool {return self._decryptionKeyID != nil} + /// Clears the value of `decryptionKeyID`. Subsequent reads from it will return its default value. + mutating func clearDecryptionKeyID() {self._decryptionKeyID = nil} + + /// Encryption may use an IV + var iv: Data { + get {return _iv ?? Data()} + set {_iv = newValue} + } + /// Returns true if `iv` has been explicitly set. + var hasIv: Bool {return self._iv != nil} + /// Clears the value of `iv`. Subsequent reads from it will return its default value. + mutating func clearIv() {self._iv = nil} + + /// Arbitrary per-protocol public data, to be sent with the plain-text header + var publicMetadata: Data { + get {return _publicMetadata ?? Data()} + set {_publicMetadata = newValue} + } + /// Returns true if `publicMetadata` has been explicitly set. + var hasPublicMetadata: Bool {return self._publicMetadata != nil} + /// Clears the value of `publicMetadata`. Subsequent reads from it will return its default value. + mutating func clearPublicMetadata() {self._publicMetadata = nil} + + /// The length of some associated data this is not sent in this SecureMessage, + /// but which will be bound to the signature. + var associatedDataLength: UInt32 { + get {return _associatedDataLength ?? 0} + set {_associatedDataLength = newValue} + } + /// Returns true if `associatedDataLength` has been explicitly set. + var hasAssociatedDataLength: Bool {return self._associatedDataLength != nil} + /// Clears the value of `associatedDataLength`. Subsequent reads from it will return its default value. + mutating func clearAssociatedDataLength() {self._associatedDataLength = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _signatureScheme: Securemessage_SigScheme? = nil + fileprivate var _encryptionScheme: Securemessage_EncScheme? = nil + fileprivate var _verificationKeyID: Data? = nil + fileprivate var _decryptionKeyID: Data? = nil + fileprivate var _iv: Data? = nil + fileprivate var _publicMetadata: Data? = nil + fileprivate var _associatedDataLength: UInt32? = nil +} + +struct Securemessage_HeaderAndBody { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Public data about this message (to be bound in the signature) + var header: Securemessage_Header { + get {return _header ?? Securemessage_Header()} + set {_header = newValue} + } + /// Returns true if `header` has been explicitly set. + var hasHeader: Bool {return self._header != nil} + /// Clears the value of `header`. Subsequent reads from it will return its default value. + mutating func clearHeader() {self._header = nil} + + /// Payload data + var body: Data { + get {return _body ?? Data()} + set {_body = newValue} + } + /// Returns true if `body` has been explicitly set. + var hasBody: Bool {return self._body != nil} + /// Clears the value of `body`. Subsequent reads from it will return its default value. + mutating func clearBody() {self._body = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _header: Securemessage_Header? = nil + fileprivate var _body: Data? = nil +} + +/// Must be kept wire-format compatible with HeaderAndBody. Provides the +/// SecureMessage code with a consistent wire-format representation that +/// remains stable irrespective of protobuf implementation choices. This +/// low-level representation of a HeaderAndBody should not be used by +/// any code outside of the SecureMessage library implementation/tests. +struct Securemessage_HeaderAndBodyInternal { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// A raw (wire-format) byte encoding of a Header, suitable for hashing + var header: Data { + get {return _header ?? Data()} + set {_header = newValue} + } + /// Returns true if `header` has been explicitly set. + var hasHeader: Bool {return self._header != nil} + /// Clears the value of `header`. Subsequent reads from it will return its default value. + mutating func clearHeader() {self._header = nil} + + /// Payload data + var body: Data { + get {return _body ?? Data()} + set {_body = newValue} + } + /// Returns true if `body` has been explicitly set. + var hasBody: Bool {return self._body != nil} + /// Clears the value of `body`. Subsequent reads from it will return its default value. + mutating func clearBody() {self._body = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _header: Data? = nil + fileprivate var _body: Data? = nil +} + +/// A convenience proto for encoding NIST P-256 elliptic curve public keys +struct Securemessage_EcP256PublicKey { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// x and y are encoded in big-endian two's complement (slightly wasteful) + /// Client MUST verify (x,y) is a valid point on NIST P256 + var x: Data { + get {return _x ?? Data()} + set {_x = newValue} + } + /// Returns true if `x` has been explicitly set. + var hasX: Bool {return self._x != nil} + /// Clears the value of `x`. Subsequent reads from it will return its default value. + mutating func clearX() {self._x = nil} + + var y: Data { + get {return _y ?? Data()} + set {_y = newValue} + } + /// Returns true if `y` has been explicitly set. + var hasY: Bool {return self._y != nil} + /// Clears the value of `y`. Subsequent reads from it will return its default value. + mutating func clearY() {self._y = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _x: Data? = nil + fileprivate var _y: Data? = nil +} + +/// A convenience proto for encoding RSA public keys with small exponents +struct Securemessage_SimpleRsaPublicKey { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Encoded in big-endian two's complement + var n: Data { + get {return _n ?? Data()} + set {_n = newValue} + } + /// Returns true if `n` has been explicitly set. + var hasN: Bool {return self._n != nil} + /// Clears the value of `n`. Subsequent reads from it will return its default value. + mutating func clearN() {self._n = nil} + + var e: Int32 { + get {return _e ?? 65537} + set {_e = newValue} + } + /// Returns true if `e` has been explicitly set. + var hasE: Bool {return self._e != nil} + /// Clears the value of `e`. Subsequent reads from it will return its default value. + mutating func clearE() {self._e = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _n: Data? = nil + fileprivate var _e: Int32? = nil +} + +/// A convenience proto for encoding Diffie-Hellman public keys, +/// for use only when Elliptic Curve based key exchanges are not possible. +/// (Note that the group parameters must be specified separately) +struct Securemessage_DhPublicKey { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Big-endian two's complement encoded group element + var y: Data { + get {return _y ?? Data()} + set {_y = newValue} + } + /// Returns true if `y` has been explicitly set. + var hasY: Bool {return self._y != nil} + /// Clears the value of `y`. Subsequent reads from it will return its default value. + mutating func clearY() {self._y = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _y: Data? = nil +} + +struct Securemessage_GenericPublicKey { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var type: Securemessage_PublicKeyType { + get {return _type ?? .ecP256} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + var ecP256PublicKey: Securemessage_EcP256PublicKey { + get {return _ecP256PublicKey ?? Securemessage_EcP256PublicKey()} + set {_ecP256PublicKey = newValue} + } + /// Returns true if `ecP256PublicKey` has been explicitly set. + var hasEcP256PublicKey: Bool {return self._ecP256PublicKey != nil} + /// Clears the value of `ecP256PublicKey`. Subsequent reads from it will return its default value. + mutating func clearEcP256PublicKey() {self._ecP256PublicKey = nil} + + var rsa2048PublicKey: Securemessage_SimpleRsaPublicKey { + get {return _rsa2048PublicKey ?? Securemessage_SimpleRsaPublicKey()} + set {_rsa2048PublicKey = newValue} + } + /// Returns true if `rsa2048PublicKey` has been explicitly set. + var hasRsa2048PublicKey: Bool {return self._rsa2048PublicKey != nil} + /// Clears the value of `rsa2048PublicKey`. Subsequent reads from it will return its default value. + mutating func clearRsa2048PublicKey() {self._rsa2048PublicKey = nil} + + /// Use only as a last resort + var dh2048PublicKey: Securemessage_DhPublicKey { + get {return _dh2048PublicKey ?? Securemessage_DhPublicKey()} + set {_dh2048PublicKey = newValue} + } + /// Returns true if `dh2048PublicKey` has been explicitly set. + var hasDh2048PublicKey: Bool {return self._dh2048PublicKey != nil} + /// Clears the value of `dh2048PublicKey`. Subsequent reads from it will return its default value. + mutating func clearDh2048PublicKey() {self._dh2048PublicKey = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _type: Securemessage_PublicKeyType? = nil + fileprivate var _ecP256PublicKey: Securemessage_EcP256PublicKey? = nil + fileprivate var _rsa2048PublicKey: Securemessage_SimpleRsaPublicKey? = nil + fileprivate var _dh2048PublicKey: Securemessage_DhPublicKey? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Securemessage_SigScheme: @unchecked Sendable {} +extension Securemessage_EncScheme: @unchecked Sendable {} +extension Securemessage_PublicKeyType: @unchecked Sendable {} +extension Securemessage_SecureMessage: @unchecked Sendable {} +extension Securemessage_Header: @unchecked Sendable {} +extension Securemessage_HeaderAndBody: @unchecked Sendable {} +extension Securemessage_HeaderAndBodyInternal: @unchecked Sendable {} +extension Securemessage_EcP256PublicKey: @unchecked Sendable {} +extension Securemessage_SimpleRsaPublicKey: @unchecked Sendable {} +extension Securemessage_DhPublicKey: @unchecked Sendable {} +extension Securemessage_GenericPublicKey: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "securemessage" + +extension Securemessage_SigScheme: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "HMAC_SHA256"), + 2: .same(proto: "ECDSA_P256_SHA256"), + 3: .same(proto: "RSA2048_SHA256"), + ] +} + +extension Securemessage_EncScheme: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "NONE"), + 2: .same(proto: "AES_256_CBC"), + ] +} + +extension Securemessage_PublicKeyType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "EC_P256"), + 2: .same(proto: "RSA2048"), + 3: .same(proto: "DH2048_MODP"), + ] +} + +extension Securemessage_SecureMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".SecureMessage" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "header_and_body"), + 2: .same(proto: "signature"), + ] + + public var isInitialized: Bool { + if self._headerAndBody == nil {return false} + if self._signature == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._headerAndBody) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._signature) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._headerAndBody { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._signature { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_SecureMessage, rhs: Securemessage_SecureMessage) -> Bool { + if lhs._headerAndBody != rhs._headerAndBody {return false} + if lhs._signature != rhs._signature {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securemessage_Header: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Header" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "signature_scheme"), + 2: .standard(proto: "encryption_scheme"), + 3: .standard(proto: "verification_key_id"), + 4: .standard(proto: "decryption_key_id"), + 5: .same(proto: "iv"), + 6: .standard(proto: "public_metadata"), + 7: .standard(proto: "associated_data_length"), + ] + + public var isInitialized: Bool { + if self._signatureScheme == nil {return false} + if self._encryptionScheme == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._signatureScheme) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self._encryptionScheme) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._verificationKeyID) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self._decryptionKeyID) }() + case 5: try { try decoder.decodeSingularBytesField(value: &self._iv) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self._publicMetadata) }() + case 7: try { try decoder.decodeSingularUInt32Field(value: &self._associatedDataLength) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._signatureScheme { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._encryptionScheme { + try visitor.visitSingularEnumField(value: v, fieldNumber: 2) + } }() + try { if let v = self._verificationKeyID { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try { if let v = self._decryptionKeyID { + try visitor.visitSingularBytesField(value: v, fieldNumber: 4) + } }() + try { if let v = self._iv { + try visitor.visitSingularBytesField(value: v, fieldNumber: 5) + } }() + try { if let v = self._publicMetadata { + try visitor.visitSingularBytesField(value: v, fieldNumber: 6) + } }() + try { if let v = self._associatedDataLength { + try visitor.visitSingularUInt32Field(value: v, fieldNumber: 7) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_Header, rhs: Securemessage_Header) -> Bool { + if lhs._signatureScheme != rhs._signatureScheme {return false} + if lhs._encryptionScheme != rhs._encryptionScheme {return false} + if lhs._verificationKeyID != rhs._verificationKeyID {return false} + if lhs._decryptionKeyID != rhs._decryptionKeyID {return false} + if lhs._iv != rhs._iv {return false} + if lhs._publicMetadata != rhs._publicMetadata {return false} + if lhs._associatedDataLength != rhs._associatedDataLength {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securemessage_HeaderAndBody: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".HeaderAndBody" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "header"), + 2: .same(proto: "body"), + ] + + public var isInitialized: Bool { + if self._header == nil {return false} + if self._body == nil {return false} + if let v = self._header, !v.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularMessageField(value: &self._header) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._body) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._header { + try visitor.visitSingularMessageField(value: v, fieldNumber: 1) + } }() + try { if let v = self._body { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_HeaderAndBody, rhs: Securemessage_HeaderAndBody) -> Bool { + if lhs._header != rhs._header {return false} + if lhs._body != rhs._body {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securemessage_HeaderAndBodyInternal: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".HeaderAndBodyInternal" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "header"), + 2: .same(proto: "body"), + ] + + public var isInitialized: Bool { + if self._header == nil {return false} + if self._body == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._header) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._body) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._header { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._body { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_HeaderAndBodyInternal, rhs: Securemessage_HeaderAndBodyInternal) -> Bool { + if lhs._header != rhs._header {return false} + if lhs._body != rhs._body {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securemessage_EcP256PublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".EcP256PublicKey" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "x"), + 2: .same(proto: "y"), + ] + + public var isInitialized: Bool { + if self._x == nil {return false} + if self._y == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._x) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._y) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._x { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._y { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_EcP256PublicKey, rhs: Securemessage_EcP256PublicKey) -> Bool { + if lhs._x != rhs._x {return false} + if lhs._y != rhs._y {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securemessage_SimpleRsaPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".SimpleRsaPublicKey" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "n"), + 2: .same(proto: "e"), + ] + + public var isInitialized: Bool { + if self._n == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._n) }() + case 2: try { try decoder.decodeSingularInt32Field(value: &self._e) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._n { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._e { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_SimpleRsaPublicKey, rhs: Securemessage_SimpleRsaPublicKey) -> Bool { + if lhs._n != rhs._n {return false} + if lhs._e != rhs._e {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securemessage_DhPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".DhPublicKey" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "y"), + ] + + public var isInitialized: Bool { + if self._y == nil {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._y) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._y { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_DhPublicKey, rhs: Securemessage_DhPublicKey) -> Bool { + if lhs._y != rhs._y {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securemessage_GenericPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".GenericPublicKey" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .standard(proto: "ec_p256_public_key"), + 3: .standard(proto: "rsa2048_public_key"), + 4: .standard(proto: "dh2048_public_key"), + ] + + public var isInitialized: Bool { + if self._type == nil {return false} + if let v = self._ecP256PublicKey, !v.isInitialized {return false} + if let v = self._rsa2048PublicKey, !v.isInitialized {return false} + if let v = self._dh2048PublicKey, !v.isInitialized {return false} + return true + } + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._ecP256PublicKey) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._rsa2048PublicKey) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._dh2048PublicKey) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._ecP256PublicKey { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = self._rsa2048PublicKey { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try { if let v = self._dh2048PublicKey { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securemessage_GenericPublicKey, rhs: Securemessage_GenericPublicKey) -> Bool { + if lhs._type != rhs._type {return false} + if lhs._ecP256PublicKey != rhs._ecP256PublicKey {return false} + if lhs._rsa2048PublicKey != rhs._rsa2048PublicKey {return false} + if lhs._dh2048PublicKey != rhs._dh2048PublicKey {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/submissions/sapphire/ProtobufGenerated/ukey.pb.swift b/submissions/sapphire/ProtobufGenerated/ukey.pb.swift new file mode 100644 index 00000000..3cbbf2b6 --- /dev/null +++ b/submissions/sapphire/ProtobufGenerated/ukey.pb.swift @@ -0,0 +1,735 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: ukey.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +enum Securegcm_Ukey2HandshakeCipher: SwiftProtobuf.Enum { + typealias RawValue = Int + case reserved // = 0 + + /// NIST P-256 used for ECDH, SHA512 used for + case p256Sha512 // = 100 + + /// commitment + case curve25519Sha512 // = 200 + + init() { + self = .reserved + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .reserved + case 100: self = .p256Sha512 + case 200: self = .curve25519Sha512 + default: return nil + } + } + + var rawValue: Int { + switch self { + case .reserved: return 0 + case .p256Sha512: return 100 + case .curve25519Sha512: return 200 + } + } + +} + +#if swift(>=4.2) + +extension Securegcm_Ukey2HandshakeCipher: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Securegcm_Ukey2Message { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Identifies message type + var messageType: Securegcm_Ukey2Message.TypeEnum { + get {return _messageType ?? .unknownDoNotUse} + set {_messageType = newValue} + } + /// Returns true if `messageType` has been explicitly set. + var hasMessageType: Bool {return self._messageType != nil} + /// Clears the value of `messageType`. Subsequent reads from it will return its default value. + mutating func clearMessageType() {self._messageType = nil} + + /// Actual message, to be parsed according to + var messageData: Data { + get {return _messageData ?? Data()} + set {_messageData = newValue} + } + /// Returns true if `messageData` has been explicitly set. + var hasMessageData: Bool {return self._messageData != nil} + /// Clears the value of `messageData`. Subsequent reads from it will return its default value. + mutating func clearMessageData() {self._messageData = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum TypeEnum: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownDoNotUse // = 0 + case alert // = 1 + case clientInit // = 2 + case serverInit // = 3 + case clientFinish // = 4 + + init() { + self = .unknownDoNotUse + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownDoNotUse + case 1: self = .alert + case 2: self = .clientInit + case 3: self = .serverInit + case 4: self = .clientFinish + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownDoNotUse: return 0 + case .alert: return 1 + case .clientInit: return 2 + case .serverInit: return 3 + case .clientFinish: return 4 + } + } + + } + + init() {} + + fileprivate var _messageType: Securegcm_Ukey2Message.TypeEnum? = nil + fileprivate var _messageData: Data? = nil +} + +#if swift(>=4.2) + +extension Securegcm_Ukey2Message.TypeEnum: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Securegcm_Ukey2Alert { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var type: Securegcm_Ukey2Alert.AlertType { + get {return _type ?? .badMessage} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + var errorMessage: String { + get {return _errorMessage ?? String()} + set {_errorMessage = newValue} + } + /// Returns true if `errorMessage` has been explicitly set. + var hasErrorMessage: Bool {return self._errorMessage != nil} + /// Clears the value of `errorMessage`. Subsequent reads from it will return its default value. + mutating func clearErrorMessage() {self._errorMessage = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum AlertType: SwiftProtobuf.Enum { + typealias RawValue = Int + + /// Framing errors + case badMessage // = 1 + + /// message_type has an undefined value + case badMessageType // = 2 + + /// message_type received does not correspond to + case incorrectMessage // = 3 + + /// expected type at this stage of the protocol + case badMessageData // = 4 + + /// ClientInit and ServerInit errors + case badVersion // = 100 + + /// suitable version to speak with client. + case badRandom // = 101 + + /// length + case badHandshakeCipher // = 102 + + /// The next protocol is missing, unknown, or + case badNextProtocol // = 103 + + /// unsupported + case badPublicKey // = 104 + + /// Other errors + case internalError // = 200 + + init() { + self = .badMessage + } + + init?(rawValue: Int) { + switch rawValue { + case 1: self = .badMessage + case 2: self = .badMessageType + case 3: self = .incorrectMessage + case 4: self = .badMessageData + case 100: self = .badVersion + case 101: self = .badRandom + case 102: self = .badHandshakeCipher + case 103: self = .badNextProtocol + case 104: self = .badPublicKey + case 200: self = .internalError + default: return nil + } + } + + var rawValue: Int { + switch self { + case .badMessage: return 1 + case .badMessageType: return 2 + case .incorrectMessage: return 3 + case .badMessageData: return 4 + case .badVersion: return 100 + case .badRandom: return 101 + case .badHandshakeCipher: return 102 + case .badNextProtocol: return 103 + case .badPublicKey: return 104 + case .internalError: return 200 + } + } + + } + + init() {} + + fileprivate var _type: Securegcm_Ukey2Alert.AlertType? = nil + fileprivate var _errorMessage: String? = nil +} + +#if swift(>=4.2) + +extension Securegcm_Ukey2Alert.AlertType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +struct Securegcm_Ukey2ClientInit { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// highest supported version for rollback + var version: Int32 { + get {return _version ?? 0} + set {_version = newValue} + } + /// Returns true if `version` has been explicitly set. + var hasVersion: Bool {return self._version != nil} + /// Clears the value of `version`. Subsequent reads from it will return its default value. + mutating func clearVersion() {self._version = nil} + + /// protection + var random: Data { + get {return _random ?? Data()} + set {_random = newValue} + } + /// Returns true if `random` has been explicitly set. + var hasRandom: Bool {return self._random != nil} + /// Clears the value of `random`. Subsequent reads from it will return its default value. + mutating func clearRandom() {self._random = nil} + + var cipherCommitments: [Securegcm_Ukey2ClientInit.CipherCommitment] = [] + + /// Next protocol that the client wants to speak. + var nextProtocol: String { + get {return _nextProtocol ?? String()} + set {_nextProtocol = newValue} + } + /// Returns true if `nextProtocol` has been explicitly set. + var hasNextProtocol: Bool {return self._nextProtocol != nil} + /// Clears the value of `nextProtocol`. Subsequent reads from it will return its default value. + mutating func clearNextProtocol() {self._nextProtocol = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + /// One commitment (hash of ClientFinished containing public key) per supported + /// cipher + struct CipherCommitment { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var handshakeCipher: Securegcm_Ukey2HandshakeCipher { + get {return _handshakeCipher ?? .reserved} + set {_handshakeCipher = newValue} + } + /// Returns true if `handshakeCipher` has been explicitly set. + var hasHandshakeCipher: Bool {return self._handshakeCipher != nil} + /// Clears the value of `handshakeCipher`. Subsequent reads from it will return its default value. + mutating func clearHandshakeCipher() {self._handshakeCipher = nil} + + var commitment: Data { + get {return _commitment ?? Data()} + set {_commitment = newValue} + } + /// Returns true if `commitment` has been explicitly set. + var hasCommitment: Bool {return self._commitment != nil} + /// Clears the value of `commitment`. Subsequent reads from it will return its default value. + mutating func clearCommitment() {self._commitment = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _handshakeCipher: Securegcm_Ukey2HandshakeCipher? = nil + fileprivate var _commitment: Data? = nil + } + + init() {} + + fileprivate var _version: Int32? = nil + fileprivate var _random: Data? = nil + fileprivate var _nextProtocol: String? = nil +} + +struct Securegcm_Ukey2ServerInit { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// highest supported version for rollback + var version: Int32 { + get {return _version ?? 0} + set {_version = newValue} + } + /// Returns true if `version` has been explicitly set. + var hasVersion: Bool {return self._version != nil} + /// Clears the value of `version`. Subsequent reads from it will return its default value. + mutating func clearVersion() {self._version = nil} + + /// protection + var random: Data { + get {return _random ?? Data()} + set {_random = newValue} + } + /// Returns true if `random` has been explicitly set. + var hasRandom: Bool {return self._random != nil} + /// Clears the value of `random`. Subsequent reads from it will return its default value. + mutating func clearRandom() {self._random = nil} + + /// Selected Cipher and corresponding public key + var handshakeCipher: Securegcm_Ukey2HandshakeCipher { + get {return _handshakeCipher ?? .reserved} + set {_handshakeCipher = newValue} + } + /// Returns true if `handshakeCipher` has been explicitly set. + var hasHandshakeCipher: Bool {return self._handshakeCipher != nil} + /// Clears the value of `handshakeCipher`. Subsequent reads from it will return its default value. + mutating func clearHandshakeCipher() {self._handshakeCipher = nil} + + var publicKey: Data { + get {return _publicKey ?? Data()} + set {_publicKey = newValue} + } + /// Returns true if `publicKey` has been explicitly set. + var hasPublicKey: Bool {return self._publicKey != nil} + /// Clears the value of `publicKey`. Subsequent reads from it will return its default value. + mutating func clearPublicKey() {self._publicKey = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _version: Int32? = nil + fileprivate var _random: Data? = nil + fileprivate var _handshakeCipher: Securegcm_Ukey2HandshakeCipher? = nil + fileprivate var _publicKey: Data? = nil +} + +struct Securegcm_Ukey2ClientFinished { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// public key matching selected handshake + var publicKey: Data { + get {return _publicKey ?? Data()} + set {_publicKey = newValue} + } + /// Returns true if `publicKey` has been explicitly set. + var hasPublicKey: Bool {return self._publicKey != nil} + /// Clears the value of `publicKey`. Subsequent reads from it will return its default value. + mutating func clearPublicKey() {self._publicKey = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _publicKey: Data? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Securegcm_Ukey2HandshakeCipher: @unchecked Sendable {} +extension Securegcm_Ukey2Message: @unchecked Sendable {} +extension Securegcm_Ukey2Message.TypeEnum: @unchecked Sendable {} +extension Securegcm_Ukey2Alert: @unchecked Sendable {} +extension Securegcm_Ukey2Alert.AlertType: @unchecked Sendable {} +extension Securegcm_Ukey2ClientInit: @unchecked Sendable {} +extension Securegcm_Ukey2ClientInit.CipherCommitment: @unchecked Sendable {} +extension Securegcm_Ukey2ServerInit: @unchecked Sendable {} +extension Securegcm_Ukey2ClientFinished: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "securegcm" + +extension Securegcm_Ukey2HandshakeCipher: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "RESERVED"), + 100: .same(proto: "P256_SHA512"), + 200: .same(proto: "CURVE25519_SHA512"), + ] +} + +extension Securegcm_Ukey2Message: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Ukey2Message" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "message_type"), + 2: .standard(proto: "message_data"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._messageType) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._messageData) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._messageType { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._messageData { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_Ukey2Message, rhs: Securegcm_Ukey2Message) -> Bool { + if lhs._messageType != rhs._messageType {return false} + if lhs._messageData != rhs._messageData {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_Ukey2Message.TypeEnum: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_DO_NOT_USE"), + 1: .same(proto: "ALERT"), + 2: .same(proto: "CLIENT_INIT"), + 3: .same(proto: "SERVER_INIT"), + 4: .same(proto: "CLIENT_FINISH"), + ] +} + +extension Securegcm_Ukey2Alert: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Ukey2Alert" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .standard(proto: "error_message"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 2: try { try decoder.decodeSingularStringField(value: &self._errorMessage) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._errorMessage { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_Ukey2Alert, rhs: Securegcm_Ukey2Alert) -> Bool { + if lhs._type != rhs._type {return false} + if lhs._errorMessage != rhs._errorMessage {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_Ukey2Alert.AlertType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "BAD_MESSAGE"), + 2: .same(proto: "BAD_MESSAGE_TYPE"), + 3: .same(proto: "INCORRECT_MESSAGE"), + 4: .same(proto: "BAD_MESSAGE_DATA"), + 100: .same(proto: "BAD_VERSION"), + 101: .same(proto: "BAD_RANDOM"), + 102: .same(proto: "BAD_HANDSHAKE_CIPHER"), + 103: .same(proto: "BAD_NEXT_PROTOCOL"), + 104: .same(proto: "BAD_PUBLIC_KEY"), + 200: .same(proto: "INTERNAL_ERROR"), + ] +} + +extension Securegcm_Ukey2ClientInit: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Ukey2ClientInit" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "version"), + 2: .same(proto: "random"), + 3: .standard(proto: "cipher_commitments"), + 4: .standard(proto: "next_protocol"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._version) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._random) }() + case 3: try { try decoder.decodeRepeatedMessageField(value: &self.cipherCommitments) }() + case 4: try { try decoder.decodeSingularStringField(value: &self._nextProtocol) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._version { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._random { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + if !self.cipherCommitments.isEmpty { + try visitor.visitRepeatedMessageField(value: self.cipherCommitments, fieldNumber: 3) + } + try { if let v = self._nextProtocol { + try visitor.visitSingularStringField(value: v, fieldNumber: 4) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_Ukey2ClientInit, rhs: Securegcm_Ukey2ClientInit) -> Bool { + if lhs._version != rhs._version {return false} + if lhs._random != rhs._random {return false} + if lhs.cipherCommitments != rhs.cipherCommitments {return false} + if lhs._nextProtocol != rhs._nextProtocol {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_Ukey2ClientInit.CipherCommitment: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = Securegcm_Ukey2ClientInit.protoMessageName + ".CipherCommitment" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "handshake_cipher"), + 2: .same(proto: "commitment"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._handshakeCipher) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._commitment) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._handshakeCipher { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._commitment { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_Ukey2ClientInit.CipherCommitment, rhs: Securegcm_Ukey2ClientInit.CipherCommitment) -> Bool { + if lhs._handshakeCipher != rhs._handshakeCipher {return false} + if lhs._commitment != rhs._commitment {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_Ukey2ServerInit: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Ukey2ServerInit" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "version"), + 2: .same(proto: "random"), + 3: .standard(proto: "handshake_cipher"), + 4: .standard(proto: "public_key"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularInt32Field(value: &self._version) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._random) }() + case 3: try { try decoder.decodeSingularEnumField(value: &self._handshakeCipher) }() + case 4: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._version { + try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) + } }() + try { if let v = self._random { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try { if let v = self._handshakeCipher { + try visitor.visitSingularEnumField(value: v, fieldNumber: 3) + } }() + try { if let v = self._publicKey { + try visitor.visitSingularBytesField(value: v, fieldNumber: 4) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_Ukey2ServerInit, rhs: Securegcm_Ukey2ServerInit) -> Bool { + if lhs._version != rhs._version {return false} + if lhs._random != rhs._random {return false} + if lhs._handshakeCipher != rhs._handshakeCipher {return false} + if lhs._publicKey != rhs._publicKey {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Securegcm_Ukey2ClientFinished: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Ukey2ClientFinished" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "public_key"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._publicKey { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Securegcm_Ukey2ClientFinished, rhs: Securegcm_Ukey2ClientFinished) -> Bool { + if lhs._publicKey != rhs._publicKey {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/submissions/sapphire/ProtobufGenerated/wire_format.pb.swift b/submissions/sapphire/ProtobufGenerated/wire_format.pb.swift new file mode 100644 index 00000000..d8c5bd04 --- /dev/null +++ b/submissions/sapphire/ProtobufGenerated/wire_format.pb.swift @@ -0,0 +1,1617 @@ +// DO NOT EDIT. +// swift-format-ignore-file +// +// Generated by the Swift generator plugin for the protocol buffer compiler. +// Source: wire_format.proto +// +// For information on using the generated types, please see the documentation: +// https://github.com/apple/swift-protobuf/ + +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Brought from: //depot/google3/location/nearby/sharing/proto/wire_format.proto +// At CL 317565061 + +import Foundation +import SwiftProtobuf + +// If the compiler emits an error on this type, it is because this file +// was generated by a version of the `protoc` Swift plug-in that is +// incompatible with the version of SwiftProtobuf to which you are linking. +// Please ensure that you are building against the same version of the API +// that was used to generate this file. +fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { + struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} + typealias Version = _2 +} + +/// File metadata. Does not include the actual bytes of the file. +/// NEXT_ID=6 +struct Sharing_Nearby_FileMetadata { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The human readable name of this file (eg. 'Cookbook.pdf'). + var name: String { + get {return _name ?? String()} + set {_name = newValue} + } + /// Returns true if `name` has been explicitly set. + var hasName: Bool {return self._name != nil} + /// Clears the value of `name`. Subsequent reads from it will return its default value. + mutating func clearName() {self._name = nil} + + /// The type of file (eg. 'IMAGE' from 'dog.jpg'). Specifying a type helps + /// provide a richer experience on the receiving side. + var type: Sharing_Nearby_FileMetadata.TypeEnum { + get {return _type ?? .unknown} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + /// The FILE payload id that will be sent as a follow up containing the actual + /// bytes of the file. + var payloadID: Int64 { + get {return _payloadID ?? 0} + set {_payloadID = newValue} + } + /// Returns true if `payloadID` has been explicitly set. + var hasPayloadID: Bool {return self._payloadID != nil} + /// Clears the value of `payloadID`. Subsequent reads from it will return its default value. + mutating func clearPayloadID() {self._payloadID = nil} + + /// The total size of the file. + var size: Int64 { + get {return _size ?? 0} + set {_size = newValue} + } + /// Returns true if `size` has been explicitly set. + var hasSize: Bool {return self._size != nil} + /// Clears the value of `size`. Subsequent reads from it will return its default value. + mutating func clearSize() {self._size = nil} + + /// The mimeType of file (eg. 'image/jpeg' from 'dog.jpg'). Specifying a + /// mimeType helps provide a richer experience on receiving side. + var mimeType: String { + get {return _mimeType ?? "application/octet-stream"} + set {_mimeType = newValue} + } + /// Returns true if `mimeType` has been explicitly set. + var hasMimeType: Bool {return self._mimeType != nil} + /// Clears the value of `mimeType`. Subsequent reads from it will return its default value. + mutating func clearMimeType() {self._mimeType = nil} + + /// A uuid for the attachment. Should be unique across all attachments. + var id: Int64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum TypeEnum: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknown // = 0 + case image // = 1 + case video // = 2 + case app // = 3 + case audio // = 4 + + init() { + self = .unknown + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .image + case 2: self = .video + case 3: self = .app + case 4: self = .audio + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknown: return 0 + case .image: return 1 + case .video: return 2 + case .app: return 3 + case .audio: return 4 + } + } + + } + + init() {} + + fileprivate var _name: String? = nil + fileprivate var _type: Sharing_Nearby_FileMetadata.TypeEnum? = nil + fileprivate var _payloadID: Int64? = nil + fileprivate var _size: Int64? = nil + fileprivate var _mimeType: String? = nil + fileprivate var _id: Int64? = nil +} + +#if swift(>=4.2) + +extension Sharing_Nearby_FileMetadata.TypeEnum: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// NEXT_ID=5 +struct Sharing_Nearby_TextMetadata { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The title of the text content. + var textTitle: String { + get {return _textTitle ?? String()} + set {_textTitle = newValue} + } + /// Returns true if `textTitle` has been explicitly set. + var hasTextTitle: Bool {return self._textTitle != nil} + /// Clears the value of `textTitle`. Subsequent reads from it will return its default value. + mutating func clearTextTitle() {self._textTitle = nil} + + /// The type of text (phone number, url, address, or plain text). + var type: Sharing_Nearby_TextMetadata.TypeEnum { + get {return _type ?? .unknown} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + /// The BYTE payload id that will be sent as a follow up containing the actual + /// bytes of the text. + var payloadID: Int64 { + get {return _payloadID ?? 0} + set {_payloadID = newValue} + } + /// Returns true if `payloadID` has been explicitly set. + var hasPayloadID: Bool {return self._payloadID != nil} + /// Clears the value of `payloadID`. Subsequent reads from it will return its default value. + mutating func clearPayloadID() {self._payloadID = nil} + + /// The size of the text content. + var size: Int64 { + get {return _size ?? 0} + set {_size = newValue} + } + /// Returns true if `size` has been explicitly set. + var hasSize: Bool {return self._size != nil} + /// Clears the value of `size`. Subsequent reads from it will return its default value. + mutating func clearSize() {self._size = nil} + + /// A uuid for the attachment. Should be unique across all attachments. + var id: Int64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum TypeEnum: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknown // = 0 + case text // = 1 + + /// Open with browsers. + case url // = 2 + + /// Open with map apps. + case address // = 3 + + /// Dial. + case phoneNumber // = 4 + + init() { + self = .unknown + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .text + case 2: self = .url + case 3: self = .address + case 4: self = .phoneNumber + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknown: return 0 + case .text: return 1 + case .url: return 2 + case .address: return 3 + case .phoneNumber: return 4 + } + } + + } + + init() {} + + fileprivate var _textTitle: String? = nil + fileprivate var _type: Sharing_Nearby_TextMetadata.TypeEnum? = nil + fileprivate var _payloadID: Int64? = nil + fileprivate var _size: Int64? = nil + fileprivate var _id: Int64? = nil +} + +#if swift(>=4.2) + +extension Sharing_Nearby_TextMetadata.TypeEnum: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// NEXT_ID=5 +struct Sharing_Nearby_WifiCredentialsMetadata { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The Wifi network name. This will be sent in introduction. + var ssid: String { + get {return _ssid ?? String()} + set {_ssid = newValue} + } + /// Returns true if `ssid` has been explicitly set. + var hasSsid: Bool {return self._ssid != nil} + /// Clears the value of `ssid`. Subsequent reads from it will return its default value. + mutating func clearSsid() {self._ssid = nil} + + /// The security type of network (OPEN, WPA_PSK, WEP). + var securityType: Sharing_Nearby_WifiCredentialsMetadata.SecurityType { + get {return _securityType ?? .unknownSecurityType} + set {_securityType = newValue} + } + /// Returns true if `securityType` has been explicitly set. + var hasSecurityType: Bool {return self._securityType != nil} + /// Clears the value of `securityType`. Subsequent reads from it will return its default value. + mutating func clearSecurityType() {self._securityType = nil} + + /// The BYTE payload id that will be sent as a follow up containing the + /// password. + var payloadID: Int64 { + get {return _payloadID ?? 0} + set {_payloadID = newValue} + } + /// Returns true if `payloadID` has been explicitly set. + var hasPayloadID: Bool {return self._payloadID != nil} + /// Clears the value of `payloadID`. Subsequent reads from it will return its default value. + mutating func clearPayloadID() {self._payloadID = nil} + + /// A uuid for the attachment. Should be unique across all attachments. + var id: Int64 { + get {return _id ?? 0} + set {_id = newValue} + } + /// Returns true if `id` has been explicitly set. + var hasID: Bool {return self._id != nil} + /// Clears the value of `id`. Subsequent reads from it will return its default value. + mutating func clearID() {self._id = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum SecurityType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownSecurityType // = 0 + case `open` // = 1 + case wpaPsk // = 2 + case wep // = 3 + + init() { + self = .unknownSecurityType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownSecurityType + case 1: self = .open + case 2: self = .wpaPsk + case 3: self = .wep + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownSecurityType: return 0 + case .open: return 1 + case .wpaPsk: return 2 + case .wep: return 3 + } + } + + } + + init() {} + + fileprivate var _ssid: String? = nil + fileprivate var _securityType: Sharing_Nearby_WifiCredentialsMetadata.SecurityType? = nil + fileprivate var _payloadID: Int64? = nil + fileprivate var _id: Int64? = nil +} + +#if swift(>=4.2) + +extension Sharing_Nearby_WifiCredentialsMetadata.SecurityType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// A frame used when sending messages over the wire. +/// NEXT_ID=3 +struct Sharing_Nearby_Frame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var version: Sharing_Nearby_Frame.Version { + get {return _version ?? .unknownVersion} + set {_version = newValue} + } + /// Returns true if `version` has been explicitly set. + var hasVersion: Bool {return self._version != nil} + /// Clears the value of `version`. Subsequent reads from it will return its default value. + mutating func clearVersion() {self._version = nil} + + /// Right now there's only 1 version, but if there are more, exactly one of + /// the following fields will be set. + var v1: Sharing_Nearby_V1Frame { + get {return _v1 ?? Sharing_Nearby_V1Frame()} + set {_v1 = newValue} + } + /// Returns true if `v1` has been explicitly set. + var hasV1: Bool {return self._v1 != nil} + /// Clears the value of `v1`. Subsequent reads from it will return its default value. + mutating func clearV1() {self._v1 = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum Version: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownVersion // = 0 + case v1 // = 1 + + init() { + self = .unknownVersion + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownVersion + case 1: self = .v1 + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownVersion: return 0 + case .v1: return 1 + } + } + + } + + init() {} + + fileprivate var _version: Sharing_Nearby_Frame.Version? = nil + fileprivate var _v1: Sharing_Nearby_V1Frame? = nil +} + +#if swift(>=4.2) + +extension Sharing_Nearby_Frame.Version: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// NEXT_ID=7 +struct Sharing_Nearby_V1Frame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var type: Sharing_Nearby_V1Frame.FrameType { + get {return _type ?? .unknownFrameType} + set {_type = newValue} + } + /// Returns true if `type` has been explicitly set. + var hasType: Bool {return self._type != nil} + /// Clears the value of `type`. Subsequent reads from it will return its default value. + mutating func clearType() {self._type = nil} + + /// Exactly one of the following fields will be set. + var introduction: Sharing_Nearby_IntroductionFrame { + get {return _introduction ?? Sharing_Nearby_IntroductionFrame()} + set {_introduction = newValue} + } + /// Returns true if `introduction` has been explicitly set. + var hasIntroduction: Bool {return self._introduction != nil} + /// Clears the value of `introduction`. Subsequent reads from it will return its default value. + mutating func clearIntroduction() {self._introduction = nil} + + var connectionResponse: Sharing_Nearby_ConnectionResponseFrame { + get {return _connectionResponse ?? Sharing_Nearby_ConnectionResponseFrame()} + set {_connectionResponse = newValue} + } + /// Returns true if `connectionResponse` has been explicitly set. + var hasConnectionResponse: Bool {return self._connectionResponse != nil} + /// Clears the value of `connectionResponse`. Subsequent reads from it will return its default value. + mutating func clearConnectionResponse() {self._connectionResponse = nil} + + var pairedKeyEncryption: Sharing_Nearby_PairedKeyEncryptionFrame { + get {return _pairedKeyEncryption ?? Sharing_Nearby_PairedKeyEncryptionFrame()} + set {_pairedKeyEncryption = newValue} + } + /// Returns true if `pairedKeyEncryption` has been explicitly set. + var hasPairedKeyEncryption: Bool {return self._pairedKeyEncryption != nil} + /// Clears the value of `pairedKeyEncryption`. Subsequent reads from it will return its default value. + mutating func clearPairedKeyEncryption() {self._pairedKeyEncryption = nil} + + var pairedKeyResult: Sharing_Nearby_PairedKeyResultFrame { + get {return _pairedKeyResult ?? Sharing_Nearby_PairedKeyResultFrame()} + set {_pairedKeyResult = newValue} + } + /// Returns true if `pairedKeyResult` has been explicitly set. + var hasPairedKeyResult: Bool {return self._pairedKeyResult != nil} + /// Clears the value of `pairedKeyResult`. Subsequent reads from it will return its default value. + mutating func clearPairedKeyResult() {self._pairedKeyResult = nil} + + var certificateInfo: Sharing_Nearby_CertificateInfoFrame { + get {return _certificateInfo ?? Sharing_Nearby_CertificateInfoFrame()} + set {_certificateInfo = newValue} + } + /// Returns true if `certificateInfo` has been explicitly set. + var hasCertificateInfo: Bool {return self._certificateInfo != nil} + /// Clears the value of `certificateInfo`. Subsequent reads from it will return its default value. + mutating func clearCertificateInfo() {self._certificateInfo = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum FrameType: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknownFrameType // = 0 + case introduction // = 1 + case response // = 2 + case pairedKeyEncryption // = 3 + case pairedKeyResult // = 4 + case certificateInfo // = 5 + case cancel // = 6 + + init() { + self = .unknownFrameType + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknownFrameType + case 1: self = .introduction + case 2: self = .response + case 3: self = .pairedKeyEncryption + case 4: self = .pairedKeyResult + case 5: self = .certificateInfo + case 6: self = .cancel + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknownFrameType: return 0 + case .introduction: return 1 + case .response: return 2 + case .pairedKeyEncryption: return 3 + case .pairedKeyResult: return 4 + case .certificateInfo: return 5 + case .cancel: return 6 + } + } + + } + + init() {} + + fileprivate var _type: Sharing_Nearby_V1Frame.FrameType? = nil + fileprivate var _introduction: Sharing_Nearby_IntroductionFrame? = nil + fileprivate var _connectionResponse: Sharing_Nearby_ConnectionResponseFrame? = nil + fileprivate var _pairedKeyEncryption: Sharing_Nearby_PairedKeyEncryptionFrame? = nil + fileprivate var _pairedKeyResult: Sharing_Nearby_PairedKeyResultFrame? = nil + fileprivate var _certificateInfo: Sharing_Nearby_CertificateInfoFrame? = nil +} + +#if swift(>=4.2) + +extension Sharing_Nearby_V1Frame.FrameType: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// An introduction packet sent by the sending side. Contains a list of files +/// they'd like to share. +/// NEXT_ID=4 +struct Sharing_Nearby_IntroductionFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + var fileMetadata: [Sharing_Nearby_FileMetadata] = [] + + var textMetadata: [Sharing_Nearby_TextMetadata] = [] + + /// The required app package to open the content. May be null. + var requiredPackage: String { + get {return _requiredPackage ?? String()} + set {_requiredPackage = newValue} + } + /// Returns true if `requiredPackage` has been explicitly set. + var hasRequiredPackage: Bool {return self._requiredPackage != nil} + /// Clears the value of `requiredPackage`. Subsequent reads from it will return its default value. + mutating func clearRequiredPackage() {self._requiredPackage = nil} + + var wifiCredentialsMetadata: [Sharing_Nearby_WifiCredentialsMetadata] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _requiredPackage: String? = nil +} + +/// A response packet sent by the receiving side. Accepts or rejects the list of +/// files. +/// NEXT_ID=2 +struct Sharing_Nearby_ConnectionResponseFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The receiving side's response. + var status: Sharing_Nearby_ConnectionResponseFrame.Status { + get {return _status ?? .unknown} + set {_status = newValue} + } + /// Returns true if `status` has been explicitly set. + var hasStatus: Bool {return self._status != nil} + /// Clears the value of `status`. Subsequent reads from it will return its default value. + mutating func clearStatus() {self._status = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum Status: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknown // = 0 + case accept // = 1 + case reject // = 2 + case notEnoughSpace // = 3 + case unsupportedAttachmentType // = 4 + case timedOut // = 5 + + init() { + self = .unknown + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .accept + case 2: self = .reject + case 3: self = .notEnoughSpace + case 4: self = .unsupportedAttachmentType + case 5: self = .timedOut + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknown: return 0 + case .accept: return 1 + case .reject: return 2 + case .notEnoughSpace: return 3 + case .unsupportedAttachmentType: return 4 + case .timedOut: return 5 + } + } + + } + + init() {} + + fileprivate var _status: Sharing_Nearby_ConnectionResponseFrame.Status? = nil +} + +#if swift(>=4.2) + +extension Sharing_Nearby_ConnectionResponseFrame.Status: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// A paired key encryption packet sent between devices, contains signed data. +/// NEXT_ID=3 +struct Sharing_Nearby_PairedKeyEncryptionFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The encrypted data in byte array format. + var signedData: Data { + get {return _signedData ?? Data()} + set {_signedData = newValue} + } + /// Returns true if `signedData` has been explicitly set. + var hasSignedData: Bool {return self._signedData != nil} + /// Clears the value of `signedData`. Subsequent reads from it will return its default value. + mutating func clearSignedData() {self._signedData = nil} + + /// The hash of a certificate id. + var secretIDHash: Data { + get {return _secretIDHash ?? Data()} + set {_secretIDHash = newValue} + } + /// Returns true if `secretIDHash` has been explicitly set. + var hasSecretIDHash: Bool {return self._secretIDHash != nil} + /// Clears the value of `secretIDHash`. Subsequent reads from it will return its default value. + mutating func clearSecretIDHash() {self._secretIDHash = nil} + + /// An optional encrypted data in byte array format. + var optionalSignedData: Data { + get {return _optionalSignedData ?? Data()} + set {_optionalSignedData = newValue} + } + /// Returns true if `optionalSignedData` has been explicitly set. + var hasOptionalSignedData: Bool {return self._optionalSignedData != nil} + /// Clears the value of `optionalSignedData`. Subsequent reads from it will return its default value. + mutating func clearOptionalSignedData() {self._optionalSignedData = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _signedData: Data? = nil + fileprivate var _secretIDHash: Data? = nil + fileprivate var _optionalSignedData: Data? = nil +} + +/// A paired key verification result packet sent between devices. +/// NEXT_ID=2 +struct Sharing_Nearby_PairedKeyResultFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The verification result. + var status: Sharing_Nearby_PairedKeyResultFrame.Status { + get {return _status ?? .unknown} + set {_status = newValue} + } + /// Returns true if `status` has been explicitly set. + var hasStatus: Bool {return self._status != nil} + /// Clears the value of `status`. Subsequent reads from it will return its default value. + mutating func clearStatus() {self._status = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + enum Status: SwiftProtobuf.Enum { + typealias RawValue = Int + case unknown // = 0 + case success // = 1 + case fail // = 2 + case unable // = 3 + + init() { + self = .unknown + } + + init?(rawValue: Int) { + switch rawValue { + case 0: self = .unknown + case 1: self = .success + case 2: self = .fail + case 3: self = .unable + default: return nil + } + } + + var rawValue: Int { + switch self { + case .unknown: return 0 + case .success: return 1 + case .fail: return 2 + case .unable: return 3 + } + } + + } + + init() {} + + fileprivate var _status: Sharing_Nearby_PairedKeyResultFrame.Status? = nil +} + +#if swift(>=4.2) + +extension Sharing_Nearby_PairedKeyResultFrame.Status: CaseIterable { + // Support synthesized by the compiler. +} + +#endif // swift(>=4.2) + +/// A package containing certificate info to be shared to remote device offline. +/// NEXT_ID=2 +struct Sharing_Nearby_CertificateInfoFrame { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The public certificates to be shared with remote devices. + var publicCertificate: [Sharing_Nearby_PublicCertificate] = [] + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} +} + +/// A public certificate from the local device. +/// NEXT_ID=8 +struct Sharing_Nearby_PublicCertificate { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// The unique id of the public certificate. + var secretID: Data { + get {return _secretID ?? Data()} + set {_secretID = newValue} + } + /// Returns true if `secretID` has been explicitly set. + var hasSecretID: Bool {return self._secretID != nil} + /// Clears the value of `secretID`. Subsequent reads from it will return its default value. + mutating func clearSecretID() {self._secretID = nil} + + /// A bytes representation of a Secret Key owned by contact, to decrypt the + /// metadata_key stored within the advertisement. + var authenticityKey: Data { + get {return _authenticityKey ?? Data()} + set {_authenticityKey = newValue} + } + /// Returns true if `authenticityKey` has been explicitly set. + var hasAuthenticityKey: Bool {return self._authenticityKey != nil} + /// Clears the value of `authenticityKey`. Subsequent reads from it will return its default value. + mutating func clearAuthenticityKey() {self._authenticityKey = nil} + + /// A bytes representation a public key of X509Certificate, owned by contact, + /// to decrypt encrypted UKEY2 (from Nearby Connections API) as a hand shake in + /// contact verification phase. + var publicKey: Data { + get {return _publicKey ?? Data()} + set {_publicKey = newValue} + } + /// Returns true if `publicKey` has been explicitly set. + var hasPublicKey: Bool {return self._publicKey != nil} + /// Clears the value of `publicKey`. Subsequent reads from it will return its default value. + mutating func clearPublicKey() {self._publicKey = nil} + + /// The time in millis from epoch when this certificate becomes effective. + var startTime: Int64 { + get {return _startTime ?? 0} + set {_startTime = newValue} + } + /// Returns true if `startTime` has been explicitly set. + var hasStartTime: Bool {return self._startTime != nil} + /// Clears the value of `startTime`. Subsequent reads from it will return its default value. + mutating func clearStartTime() {self._startTime = nil} + + /// The time in millis from epoch when this certificate expires. + var endTime: Int64 { + get {return _endTime ?? 0} + set {_endTime = newValue} + } + /// Returns true if `endTime` has been explicitly set. + var hasEndTime: Bool {return self._endTime != nil} + /// Clears the value of `endTime`. Subsequent reads from it will return its default value. + mutating func clearEndTime() {self._endTime = nil} + + /// The encrypted metadata in bytes, contains personal information of the + /// device/user who created this certificate. Needs to be decrypted into bytes, + /// and converted back to EncryptedMetadata object to access fields. + var encryptedMetadataBytes: Data { + get {return _encryptedMetadataBytes ?? Data()} + set {_encryptedMetadataBytes = newValue} + } + /// Returns true if `encryptedMetadataBytes` has been explicitly set. + var hasEncryptedMetadataBytes: Bool {return self._encryptedMetadataBytes != nil} + /// Clears the value of `encryptedMetadataBytes`. Subsequent reads from it will return its default value. + mutating func clearEncryptedMetadataBytes() {self._encryptedMetadataBytes = nil} + + /// The tag for verifying metadata_encryption_key. + var metadataEncryptionKeyTag: Data { + get {return _metadataEncryptionKeyTag ?? Data()} + set {_metadataEncryptionKeyTag = newValue} + } + /// Returns true if `metadataEncryptionKeyTag` has been explicitly set. + var hasMetadataEncryptionKeyTag: Bool {return self._metadataEncryptionKeyTag != nil} + /// Clears the value of `metadataEncryptionKeyTag`. Subsequent reads from it will return its default value. + mutating func clearMetadataEncryptionKeyTag() {self._metadataEncryptionKeyTag = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _secretID: Data? = nil + fileprivate var _authenticityKey: Data? = nil + fileprivate var _publicKey: Data? = nil + fileprivate var _startTime: Int64? = nil + fileprivate var _endTime: Int64? = nil + fileprivate var _encryptedMetadataBytes: Data? = nil + fileprivate var _metadataEncryptionKeyTag: Data? = nil +} + +/// NEXT_ID=3 +struct Sharing_Nearby_WifiCredentials { + // SwiftProtobuf.Message conformance is added in an extension below. See the + // `Message` and `Message+*Additions` files in the SwiftProtobuf library for + // methods supported on all messages. + + /// Wi-Fi password. + var password: String { + get {return _password ?? String()} + set {_password = newValue} + } + /// Returns true if `password` has been explicitly set. + var hasPassword: Bool {return self._password != nil} + /// Clears the value of `password`. Subsequent reads from it will return its default value. + mutating func clearPassword() {self._password = nil} + + /// True if the network is a hidden network that is not broadcasting its SSID. + /// Default is false. + var hiddenSsid: Bool { + get {return _hiddenSsid ?? false} + set {_hiddenSsid = newValue} + } + /// Returns true if `hiddenSsid` has been explicitly set. + var hasHiddenSsid: Bool {return self._hiddenSsid != nil} + /// Clears the value of `hiddenSsid`. Subsequent reads from it will return its default value. + mutating func clearHiddenSsid() {self._hiddenSsid = nil} + + var unknownFields = SwiftProtobuf.UnknownStorage() + + init() {} + + fileprivate var _password: String? = nil + fileprivate var _hiddenSsid: Bool? = nil +} + +#if swift(>=5.5) && canImport(_Concurrency) +extension Sharing_Nearby_FileMetadata: @unchecked Sendable {} +extension Sharing_Nearby_FileMetadata.TypeEnum: @unchecked Sendable {} +extension Sharing_Nearby_TextMetadata: @unchecked Sendable {} +extension Sharing_Nearby_TextMetadata.TypeEnum: @unchecked Sendable {} +extension Sharing_Nearby_WifiCredentialsMetadata: @unchecked Sendable {} +extension Sharing_Nearby_WifiCredentialsMetadata.SecurityType: @unchecked Sendable {} +extension Sharing_Nearby_Frame: @unchecked Sendable {} +extension Sharing_Nearby_Frame.Version: @unchecked Sendable {} +extension Sharing_Nearby_V1Frame: @unchecked Sendable {} +extension Sharing_Nearby_V1Frame.FrameType: @unchecked Sendable {} +extension Sharing_Nearby_IntroductionFrame: @unchecked Sendable {} +extension Sharing_Nearby_ConnectionResponseFrame: @unchecked Sendable {} +extension Sharing_Nearby_ConnectionResponseFrame.Status: @unchecked Sendable {} +extension Sharing_Nearby_PairedKeyEncryptionFrame: @unchecked Sendable {} +extension Sharing_Nearby_PairedKeyResultFrame: @unchecked Sendable {} +extension Sharing_Nearby_PairedKeyResultFrame.Status: @unchecked Sendable {} +extension Sharing_Nearby_CertificateInfoFrame: @unchecked Sendable {} +extension Sharing_Nearby_PublicCertificate: @unchecked Sendable {} +extension Sharing_Nearby_WifiCredentials: @unchecked Sendable {} +#endif // swift(>=5.5) && canImport(_Concurrency) + +// MARK: - Code below here is support for the SwiftProtobuf runtime. + +fileprivate let _protobuf_package = "sharing.nearby" + +extension Sharing_Nearby_FileMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".FileMetadata" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "name"), + 2: .same(proto: "type"), + 3: .standard(proto: "payload_id"), + 4: .same(proto: "size"), + 5: .standard(proto: "mime_type"), + 6: .same(proto: "id"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() + case 2: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 3: try { try decoder.decodeSingularInt64Field(value: &self._payloadID) }() + case 4: try { try decoder.decodeSingularInt64Field(value: &self._size) }() + case 5: try { try decoder.decodeSingularStringField(value: &self._mimeType) }() + case 6: try { try decoder.decodeSingularInt64Field(value: &self._id) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._name { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 2) + } }() + try { if let v = self._payloadID { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 3) + } }() + try { if let v = self._size { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) + } }() + try { if let v = self._mimeType { + try visitor.visitSingularStringField(value: v, fieldNumber: 5) + } }() + try { if let v = self._id { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 6) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_FileMetadata, rhs: Sharing_Nearby_FileMetadata) -> Bool { + if lhs._name != rhs._name {return false} + if lhs._type != rhs._type {return false} + if lhs._payloadID != rhs._payloadID {return false} + if lhs._size != rhs._size {return false} + if lhs._mimeType != rhs._mimeType {return false} + if lhs._id != rhs._id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_FileMetadata.TypeEnum: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN"), + 1: .same(proto: "IMAGE"), + 2: .same(proto: "VIDEO"), + 3: .same(proto: "APP"), + 4: .same(proto: "AUDIO"), + ] +} + +extension Sharing_Nearby_TextMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".TextMetadata" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 2: .standard(proto: "text_title"), + 3: .same(proto: "type"), + 4: .standard(proto: "payload_id"), + 5: .same(proto: "size"), + 6: .same(proto: "id"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 2: try { try decoder.decodeSingularStringField(value: &self._textTitle) }() + case 3: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 4: try { try decoder.decodeSingularInt64Field(value: &self._payloadID) }() + case 5: try { try decoder.decodeSingularInt64Field(value: &self._size) }() + case 6: try { try decoder.decodeSingularInt64Field(value: &self._id) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._textTitle { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 3) + } }() + try { if let v = self._payloadID { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) + } }() + try { if let v = self._size { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 5) + } }() + try { if let v = self._id { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 6) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_TextMetadata, rhs: Sharing_Nearby_TextMetadata) -> Bool { + if lhs._textTitle != rhs._textTitle {return false} + if lhs._type != rhs._type {return false} + if lhs._payloadID != rhs._payloadID {return false} + if lhs._size != rhs._size {return false} + if lhs._id != rhs._id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_TextMetadata.TypeEnum: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN"), + 1: .same(proto: "TEXT"), + 2: .same(proto: "URL"), + 3: .same(proto: "ADDRESS"), + 4: .same(proto: "PHONE_NUMBER"), + ] +} + +extension Sharing_Nearby_WifiCredentialsMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".WifiCredentialsMetadata" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 2: .same(proto: "ssid"), + 3: .standard(proto: "security_type"), + 4: .standard(proto: "payload_id"), + 5: .same(proto: "id"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 2: try { try decoder.decodeSingularStringField(value: &self._ssid) }() + case 3: try { try decoder.decodeSingularEnumField(value: &self._securityType) }() + case 4: try { try decoder.decodeSingularInt64Field(value: &self._payloadID) }() + case 5: try { try decoder.decodeSingularInt64Field(value: &self._id) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._ssid { + try visitor.visitSingularStringField(value: v, fieldNumber: 2) + } }() + try { if let v = self._securityType { + try visitor.visitSingularEnumField(value: v, fieldNumber: 3) + } }() + try { if let v = self._payloadID { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) + } }() + try { if let v = self._id { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 5) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_WifiCredentialsMetadata, rhs: Sharing_Nearby_WifiCredentialsMetadata) -> Bool { + if lhs._ssid != rhs._ssid {return false} + if lhs._securityType != rhs._securityType {return false} + if lhs._payloadID != rhs._payloadID {return false} + if lhs._id != rhs._id {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_WifiCredentialsMetadata.SecurityType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_SECURITY_TYPE"), + 1: .same(proto: "OPEN"), + 2: .same(proto: "WPA_PSK"), + 3: .same(proto: "WEP"), + ] +} + +extension Sharing_Nearby_Frame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".Frame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "version"), + 2: .same(proto: "v1"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._version) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._v1) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._version { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._v1 { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_Frame, rhs: Sharing_Nearby_Frame) -> Bool { + if lhs._version != rhs._version {return false} + if lhs._v1 != rhs._v1 {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_Frame.Version: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_VERSION"), + 1: .same(proto: "V1"), + ] +} + +extension Sharing_Nearby_V1Frame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".V1Frame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "type"), + 2: .same(proto: "introduction"), + 3: .standard(proto: "connection_response"), + 4: .standard(proto: "paired_key_encryption"), + 5: .standard(proto: "paired_key_result"), + 6: .standard(proto: "certificate_info"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() + case 2: try { try decoder.decodeSingularMessageField(value: &self._introduction) }() + case 3: try { try decoder.decodeSingularMessageField(value: &self._connectionResponse) }() + case 4: try { try decoder.decodeSingularMessageField(value: &self._pairedKeyEncryption) }() + case 5: try { try decoder.decodeSingularMessageField(value: &self._pairedKeyResult) }() + case 6: try { try decoder.decodeSingularMessageField(value: &self._certificateInfo) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._type { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try { if let v = self._introduction { + try visitor.visitSingularMessageField(value: v, fieldNumber: 2) + } }() + try { if let v = self._connectionResponse { + try visitor.visitSingularMessageField(value: v, fieldNumber: 3) + } }() + try { if let v = self._pairedKeyEncryption { + try visitor.visitSingularMessageField(value: v, fieldNumber: 4) + } }() + try { if let v = self._pairedKeyResult { + try visitor.visitSingularMessageField(value: v, fieldNumber: 5) + } }() + try { if let v = self._certificateInfo { + try visitor.visitSingularMessageField(value: v, fieldNumber: 6) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_V1Frame, rhs: Sharing_Nearby_V1Frame) -> Bool { + if lhs._type != rhs._type {return false} + if lhs._introduction != rhs._introduction {return false} + if lhs._connectionResponse != rhs._connectionResponse {return false} + if lhs._pairedKeyEncryption != rhs._pairedKeyEncryption {return false} + if lhs._pairedKeyResult != rhs._pairedKeyResult {return false} + if lhs._certificateInfo != rhs._certificateInfo {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_V1Frame.FrameType: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN_FRAME_TYPE"), + 1: .same(proto: "INTRODUCTION"), + 2: .same(proto: "RESPONSE"), + 3: .same(proto: "PAIRED_KEY_ENCRYPTION"), + 4: .same(proto: "PAIRED_KEY_RESULT"), + 5: .same(proto: "CERTIFICATE_INFO"), + 6: .same(proto: "CANCEL"), + ] +} + +extension Sharing_Nearby_IntroductionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".IntroductionFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "file_metadata"), + 2: .standard(proto: "text_metadata"), + 3: .standard(proto: "required_package"), + 4: .standard(proto: "wifi_credentials_metadata"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.fileMetadata) }() + case 2: try { try decoder.decodeRepeatedMessageField(value: &self.textMetadata) }() + case 3: try { try decoder.decodeSingularStringField(value: &self._requiredPackage) }() + case 4: try { try decoder.decodeRepeatedMessageField(value: &self.wifiCredentialsMetadata) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + if !self.fileMetadata.isEmpty { + try visitor.visitRepeatedMessageField(value: self.fileMetadata, fieldNumber: 1) + } + if !self.textMetadata.isEmpty { + try visitor.visitRepeatedMessageField(value: self.textMetadata, fieldNumber: 2) + } + try { if let v = self._requiredPackage { + try visitor.visitSingularStringField(value: v, fieldNumber: 3) + } }() + if !self.wifiCredentialsMetadata.isEmpty { + try visitor.visitRepeatedMessageField(value: self.wifiCredentialsMetadata, fieldNumber: 4) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_IntroductionFrame, rhs: Sharing_Nearby_IntroductionFrame) -> Bool { + if lhs.fileMetadata != rhs.fileMetadata {return false} + if lhs.textMetadata != rhs.textMetadata {return false} + if lhs._requiredPackage != rhs._requiredPackage {return false} + if lhs.wifiCredentialsMetadata != rhs.wifiCredentialsMetadata {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_ConnectionResponseFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".ConnectionResponseFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "status"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._status) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._status { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_ConnectionResponseFrame, rhs: Sharing_Nearby_ConnectionResponseFrame) -> Bool { + if lhs._status != rhs._status {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_ConnectionResponseFrame.Status: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN"), + 1: .same(proto: "ACCEPT"), + 2: .same(proto: "REJECT"), + 3: .same(proto: "NOT_ENOUGH_SPACE"), + 4: .same(proto: "UNSUPPORTED_ATTACHMENT_TYPE"), + 5: .same(proto: "TIMED_OUT"), + ] +} + +extension Sharing_Nearby_PairedKeyEncryptionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".PairedKeyEncryptionFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "signed_data"), + 2: .standard(proto: "secret_id_hash"), + 3: .standard(proto: "optional_signed_data"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._signedData) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._secretIDHash) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._optionalSignedData) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._signedData { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._secretIDHash { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try { if let v = self._optionalSignedData { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_PairedKeyEncryptionFrame, rhs: Sharing_Nearby_PairedKeyEncryptionFrame) -> Bool { + if lhs._signedData != rhs._signedData {return false} + if lhs._secretIDHash != rhs._secretIDHash {return false} + if lhs._optionalSignedData != rhs._optionalSignedData {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_PairedKeyResultFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".PairedKeyResultFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "status"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularEnumField(value: &self._status) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._status { + try visitor.visitSingularEnumField(value: v, fieldNumber: 1) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_PairedKeyResultFrame, rhs: Sharing_Nearby_PairedKeyResultFrame) -> Bool { + if lhs._status != rhs._status {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_PairedKeyResultFrame.Status: SwiftProtobuf._ProtoNameProviding { + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 0: .same(proto: "UNKNOWN"), + 1: .same(proto: "SUCCESS"), + 2: .same(proto: "FAIL"), + 3: .same(proto: "UNABLE"), + ] +} + +extension Sharing_Nearby_CertificateInfoFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".CertificateInfoFrame" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "public_certificate"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeRepeatedMessageField(value: &self.publicCertificate) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + if !self.publicCertificate.isEmpty { + try visitor.visitRepeatedMessageField(value: self.publicCertificate, fieldNumber: 1) + } + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_CertificateInfoFrame, rhs: Sharing_Nearby_CertificateInfoFrame) -> Bool { + if lhs.publicCertificate != rhs.publicCertificate {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_PublicCertificate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".PublicCertificate" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .standard(proto: "secret_id"), + 2: .standard(proto: "authenticity_key"), + 3: .standard(proto: "public_key"), + 4: .standard(proto: "start_time"), + 5: .standard(proto: "end_time"), + 6: .standard(proto: "encrypted_metadata_bytes"), + 7: .standard(proto: "metadata_encryption_key_tag"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularBytesField(value: &self._secretID) }() + case 2: try { try decoder.decodeSingularBytesField(value: &self._authenticityKey) }() + case 3: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }() + case 4: try { try decoder.decodeSingularInt64Field(value: &self._startTime) }() + case 5: try { try decoder.decodeSingularInt64Field(value: &self._endTime) }() + case 6: try { try decoder.decodeSingularBytesField(value: &self._encryptedMetadataBytes) }() + case 7: try { try decoder.decodeSingularBytesField(value: &self._metadataEncryptionKeyTag) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._secretID { + try visitor.visitSingularBytesField(value: v, fieldNumber: 1) + } }() + try { if let v = self._authenticityKey { + try visitor.visitSingularBytesField(value: v, fieldNumber: 2) + } }() + try { if let v = self._publicKey { + try visitor.visitSingularBytesField(value: v, fieldNumber: 3) + } }() + try { if let v = self._startTime { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) + } }() + try { if let v = self._endTime { + try visitor.visitSingularInt64Field(value: v, fieldNumber: 5) + } }() + try { if let v = self._encryptedMetadataBytes { + try visitor.visitSingularBytesField(value: v, fieldNumber: 6) + } }() + try { if let v = self._metadataEncryptionKeyTag { + try visitor.visitSingularBytesField(value: v, fieldNumber: 7) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_PublicCertificate, rhs: Sharing_Nearby_PublicCertificate) -> Bool { + if lhs._secretID != rhs._secretID {return false} + if lhs._authenticityKey != rhs._authenticityKey {return false} + if lhs._publicKey != rhs._publicKey {return false} + if lhs._startTime != rhs._startTime {return false} + if lhs._endTime != rhs._endTime {return false} + if lhs._encryptedMetadataBytes != rhs._encryptedMetadataBytes {return false} + if lhs._metadataEncryptionKeyTag != rhs._metadataEncryptionKeyTag {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} + +extension Sharing_Nearby_WifiCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { + static let protoMessageName: String = _protobuf_package + ".WifiCredentials" + static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ + 1: .same(proto: "password"), + 2: .standard(proto: "hidden_ssid"), + ] + + mutating func decodeMessage(decoder: inout D) throws { + while let fieldNumber = try decoder.nextFieldNumber() { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every case branch when no optimizations are + // enabled. https://github.com/apple/swift-protobuf/issues/1034 + switch fieldNumber { + case 1: try { try decoder.decodeSingularStringField(value: &self._password) }() + case 2: try { try decoder.decodeSingularBoolField(value: &self._hiddenSsid) }() + default: break + } + } + } + + func traverse(visitor: inout V) throws { + // The use of inline closures is to circumvent an issue where the compiler + // allocates stack space for every if/case branch local when no optimizations + // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and + // https://github.com/apple/swift-protobuf/issues/1182 + try { if let v = self._password { + try visitor.visitSingularStringField(value: v, fieldNumber: 1) + } }() + try { if let v = self._hiddenSsid { + try visitor.visitSingularBoolField(value: v, fieldNumber: 2) + } }() + try unknownFields.traverse(visitor: &visitor) + } + + static func ==(lhs: Sharing_Nearby_WifiCredentials, rhs: Sharing_Nearby_WifiCredentials) -> Bool { + if lhs._password != rhs._password {return false} + if lhs._hiddenSsid != rhs._hiddenSsid {return false} + if lhs.unknownFields != rhs.unknownFields {return false} + return true + } +} diff --git a/submissions/sapphire/ProtobufSource/device_to_device_messages.proto b/submissions/sapphire/ProtobufSource/device_to_device_messages.proto new file mode 100644 index 00000000..5600373e --- /dev/null +++ b/submissions/sapphire/ProtobufSource/device_to_device_messages.proto @@ -0,0 +1,81 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package securegcm; + +import "securemessage.proto"; + +option optimize_for = LITE_RUNTIME; +option java_package = "com.google.security.cryptauth.lib.securegcm"; +option java_outer_classname = "DeviceToDeviceMessagesProto"; +option objc_class_prefix = "SGCM"; + +// Used by protocols between devices +message DeviceToDeviceMessage { + // the payload of the message + optional bytes message = 1; + + // the sequence number of the message - must be increasing. + optional int32 sequence_number = 2; +} + +// sent as the first message from initiator to responder +// in an unauthenticated Diffie-Hellman Key Exchange +message InitiatorHello { + // The session public key to send to the responder + optional securemessage.GenericPublicKey public_dh_key = 1; + + // The protocol version + optional int32 protocol_version = 2 [default = 0]; +} + +// sent inside the header of the first message from the responder to the +// initiator in an unauthenticated Diffie-Hellman Key Exchange +message ResponderHello { + // The session public key to send to the initiator + optional securemessage.GenericPublicKey public_dh_key = 1; + + // The protocol version + optional int32 protocol_version = 2 [default = 0]; +} + +// Type of curve +enum Curve { ED_25519 = 1; } + +// A convenience proto for encoding curve points in affine representation +message EcPoint { + required Curve curve = 1; + + // x and y are encoded in big-endian two's complement + // client MUST verify (x,y) is a valid point on the specified curve + required bytes x = 2; + required bytes y = 3; +} + +message SpakeHandshakeMessage { + // Each flow in the protocol bumps this counter + optional int32 flow_number = 1; + + // Some (but not all) SPAKE flows send a point on an elliptic curve + optional EcPoint ec_point = 2; + + // Some (but not all) SPAKE flows send a hash value + optional bytes hash_value = 3; + + // The last flow of a SPAKE protocol can send an optional payload, + // since the key exchange is already complete on the sender's side. + optional bytes payload = 4; +} diff --git a/submissions/sapphire/ProtobufSource/offline_wire_formats.proto b/submissions/sapphire/ProtobufSource/offline_wire_formats.proto new file mode 100644 index 00000000..c1120040 --- /dev/null +++ b/submissions/sapphire/ProtobufSource/offline_wire_formats.proto @@ -0,0 +1,403 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package location.nearby.connections; + +option optimize_for = LITE_RUNTIME; +option java_outer_classname = "OfflineWireFormatsProto"; +option java_package = "com.google.location.nearby.connections.proto"; +option objc_class_prefix = "GNCP"; + +message OfflineFrame { + enum Version { + UNKNOWN_VERSION = 0; + V1 = 1; + } + optional Version version = 1; + + // Right now there's only 1 version, but if there are more, exactly one of + // the following fields will be set. + optional V1Frame v1 = 2; +} + +message V1Frame { + enum FrameType { + UNKNOWN_FRAME_TYPE = 0; + CONNECTION_REQUEST = 1; + CONNECTION_RESPONSE = 2; + PAYLOAD_TRANSFER = 3; + BANDWIDTH_UPGRADE_NEGOTIATION = 4; + KEEP_ALIVE = 5; + DISCONNECTION = 6; + PAIRED_KEY_ENCRYPTION = 7; + } + optional FrameType type = 1; + + // Exactly one of the following fields will be set. + optional ConnectionRequestFrame connection_request = 2; + optional ConnectionResponseFrame connection_response = 3; + optional PayloadTransferFrame payload_transfer = 4; + optional BandwidthUpgradeNegotiationFrame bandwidth_upgrade_negotiation = 5; + optional KeepAliveFrame keep_alive = 6; + optional DisconnectionFrame disconnection = 7; + optional PairedKeyEncryptionFrame paired_key_encryption = 8; +} + +message ConnectionRequestFrame { + // Should always match cs/symbol:location.nearby.proto.connections.Medium + // LINT.IfChange + enum Medium { + UNKNOWN_MEDIUM = 0; + MDNS = 1 [deprecated = true]; + BLUETOOTH = 2; + WIFI_HOTSPOT = 3; + BLE = 4; + WIFI_LAN = 5; + WIFI_AWARE = 6; + NFC = 7; + WIFI_DIRECT = 8; + WEB_RTC = 9; + BLE_L2CAP = 10; + USB = 11; + } + // LINT.ThenChange(//depot/google3/third_party/nearby/proto/connections_enums.proto) + + optional string endpoint_id = 1; + optional string endpoint_name = 2; + optional bytes handshake_data = 3; + // A random number generated for each outgoing connection that is presently + // used to act as a tiebreaker when 2 devices connect to each other + // simultaneously; this can also be used for other initialization-scoped + // things in the future. + optional int32 nonce = 4; + // The mediums this device supports upgrading to. This list should be filtered + // by both the strategy and this device's individual limitations. + repeated Medium mediums = 5; + optional bytes endpoint_info = 6; + optional MediumMetadata medium_metadata = 7; + optional int32 keep_alive_interval_millis = 8; + optional int32 keep_alive_timeout_millis = 9; + // The type of {@link Device} object. + optional int32 device_type = 10 [default = 0]; + // The bytes of serialized {@link Device} object. + optional bytes device_info = 11; +} + +message ConnectionResponseFrame { + // This doesn't need to send back endpoint_id and endpoint_name (like + // the ConnectionRequestFrame does) because those have already been + // transmitted out-of-band, at the time this endpoint was discovered. + + // One of: + // + // - ConnectionsStatusCodes.STATUS_OK + // - ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED. + optional int32 status = 1 [deprecated = true]; + optional bytes handshake_data = 2; + + // Used to replace the status integer parameter with a meaningful enum item. + // Map ConnectionsStatusCodes.STATUS_OK to ACCEPT and + // ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED to REJECT. + // Flag: connection_replace_status_with_response_connectionResponseFrame + enum ResponseStatus { + UNKNOWN_RESPONSE_STATUS = 0; + ACCEPT = 1; + REJECT = 2; + } + optional ResponseStatus response = 3; + optional OsInfo os_info = 4; + // A bitmask value to indicate which medium supports Multiplex transmission + // feature. Each supporting medium could utilize one bit starting from the + // least significant bit in this field. eq. BT utilizes the LSB bit which 0x01 + // means bt supports multiplex while 0x00 means not. Refer to ClientProxy.java + // for the bit usages. + optional int32 multiplex_socket_bitmask = 5; + optional int32 nearby_connections_version = 6; +} + +message PayloadTransferFrame { + enum PacketType { + UNKNOWN_PACKET_TYPE = 0; + DATA = 1; + CONTROL = 2; + } + + message PayloadHeader { + enum PayloadType { + UNKNOWN_PAYLOAD_TYPE = 0; + BYTES = 1; + FILE = 2; + STREAM = 3; + } + optional int64 id = 1; + optional PayloadType type = 2; + optional int64 total_size = 3; + optional bool is_sensitive = 4; + optional string file_name = 5; + optional string parent_folder = 6; + } + + // Accompanies DATA packets. + message PayloadChunk { + enum Flags { + LAST_CHUNK = 0x1; + } + optional int32 flags = 1; + optional int64 offset = 2; + optional bytes body = 3; + } + + // Accompanies CONTROL packets. + message ControlMessage { + enum EventType { + UNKNOWN_EVENT_TYPE = 0; + PAYLOAD_ERROR = 1; + PAYLOAD_CANCELED = 2; + PAYLOAD_RECEIVED_ACK = 3; + } + + optional EventType event = 1; + optional int64 offset = 2; + } + + optional PacketType packet_type = 1; + optional PayloadHeader payload_header = 2; + + // Exactly one of the following fields will be set, depending on the type. + optional PayloadChunk payload_chunk = 3; + optional ControlMessage control_message = 4; +} + +message BandwidthUpgradeNegotiationFrame { + enum EventType { + UNKNOWN_EVENT_TYPE = 0; + UPGRADE_PATH_AVAILABLE = 1; + LAST_WRITE_TO_PRIOR_CHANNEL = 2; + SAFE_TO_CLOSE_PRIOR_CHANNEL = 3; + CLIENT_INTRODUCTION = 4; + UPGRADE_FAILURE = 5; + CLIENT_INTRODUCTION_ACK = 6; + } + + // Accompanies UPGRADE_PATH_AVAILABLE and UPGRADE_FAILURE events. + message UpgradePathInfo { + // Should always match cs/symbol:location.nearby.proto.connections.Medium + enum Medium { + UNKNOWN_MEDIUM = 0; + MDNS = 1 [deprecated = true]; + BLUETOOTH = 2; + WIFI_HOTSPOT = 3; + BLE = 4; + WIFI_LAN = 5; + WIFI_AWARE = 6; + NFC = 7; + WIFI_DIRECT = 8; + WEB_RTC = 9; + // 10 is reserved. + USB = 11; + } + + // Accompanies Medium.WIFI_HOTSPOT. + message WifiHotspotCredentials { + optional string ssid = 1; + optional string password = 2; + optional int32 port = 3; + optional string gateway = 4 [default = "0.0.0.0"]; + // This field can be a band or frequency + optional int32 frequency = 5 [default = -1]; + } + + // Accompanies Medium.WIFI_LAN. + message WifiLanSocket { + optional bytes ip_address = 1; + optional int32 wifi_port = 2; + } + + // Accompanies Medium.BLUETOOTH. + message BluetoothCredentials { + optional string service_name = 1; + optional string mac_address = 2; + } + + // Accompanies Medium.WIFI_AWARE. + message WifiAwareCredentials { + optional string service_id = 1; + optional bytes service_info = 2; + optional string password = 3; + } + + // Accompanies Medium.WIFI_DIRECT. + message WifiDirectCredentials { + optional string ssid = 1; + optional string password = 2; + optional int32 port = 3; + optional int32 frequency = 4; + optional string gateway = 5 [default = "0.0.0.0"]; + } + + // Accompanies Medium.WEB_RTC + message WebRtcCredentials { + optional string peer_id = 1; + optional LocationHint location_hint = 2; + } + + optional Medium medium = 1; + + // Exactly one of the following fields will be set. + optional WifiHotspotCredentials wifi_hotspot_credentials = 2; + optional WifiLanSocket wifi_lan_socket = 3; + optional BluetoothCredentials bluetooth_credentials = 4; + optional WifiAwareCredentials wifi_aware_credentials = 5; + optional WifiDirectCredentials wifi_direct_credentials = 6; + optional WebRtcCredentials web_rtc_credentials = 8; + + // Disable Encryption for this upgrade medium to improve throughput. + optional bool supports_disabling_encryption = 7; + + // An ack will be sent after the CLIENT_INTRODUCTION frame. + optional bool supports_client_introduction_ack = 9; + } + + // Accompanies CLIENT_INTRODUCTION events. + message ClientIntroduction { + optional string endpoint_id = 1; + optional bool supports_disabling_encryption = 2; + } + + // Accompanies CLIENT_INTRODUCTION_ACK events. + message ClientIntroductionAck {} + + optional EventType event_type = 1; + + // Exactly one of the following fields will be set. + optional UpgradePathInfo upgrade_path_info = 2; + optional ClientIntroduction client_introduction = 3; + optional ClientIntroductionAck client_introduction_ack = 4; +} + +message KeepAliveFrame { + // And ack will be sent after receiving KEEP_ALIVE frame. + optional bool ack = 1; +} + +// Informs the remote side to immediately severe the socket connection. +// Used in bandwidth upgrades to get around a race condition, but may be used +// in other situations to trigger a faster disconnection event than waiting for +// socket closed on the remote side. +message DisconnectionFrame { + // Apply safe-to-disconnect protocol if true. + optional bool request_safe_to_disconnect = 1; + + // Ack of receiving Disconnection frame will be sent to the sender + // frame. + optional bool ack_safe_to_disconnect = 2; +} + +// A paired key encryption packet sent between devices, contains signed data. +message PairedKeyEncryptionFrame { + // The encrypted data (raw authentication token for the established + // connection) in byte array format. + optional bytes signed_data = 1; +} + +message MediumMetadata { + // True if local device supports 5GHz. + optional bool supports_5_ghz = 1; + // WiFi LAN BSSID, in the form of a six-byte MAC address: XX:XX:XX:XX:XX:XX + optional string bssid = 2; + // IP address, in network byte order: the highest order byte of the address is + // in byte[0]. + optional bytes ip_address = 3; + // True if local device supports 6GHz. + optional bool supports_6_ghz = 4; + // True if local device has mobile radio. + optional bool mobile_radio = 5; + // The frequency of the WiFi LAN AP(in MHz). Or -1 is not associated with an + // AP over WiFi, -2 represents the active network uses an Ethernet transport. + optional int32 ap_frequency = 6 [default = -1]; + // Available channels on the local device. + optional AvailableChannels available_channels = 7; + // Usable WiFi Direct client channels on the local device. + optional WifiDirectCliUsableChannels wifi_direct_cli_usable_channels = 8; + // Usable WiFi LAN channels on the local device. + optional WifiLanUsableChannels wifi_lan_usable_channels = 9; + // Usable WiFi Aware channels on the local device. + optional WifiAwareUsableChannels wifi_aware_usable_channels = 10; + // Usable WiFi Hotspot STA channels on the local device. + optional WifiHotspotStaUsableChannels wifi_hotspot_sta_usable_channels = 11; +} + +// Available channels on the local device. +message AvailableChannels { + repeated int32 channels = 1 [packed = true]; +} + +// Usable WiFi Direct client channels on the local device. +message WifiDirectCliUsableChannels { + repeated int32 channels = 1 [packed = true]; +} + +// Usable WiFi LAN channels on the local device. +message WifiLanUsableChannels { + repeated int32 channels = 1 [packed = true]; +} + +// Usable WiFi Aware channels on the local device. +message WifiAwareUsableChannels { + repeated int32 channels = 1 [packed = true]; +} + +// Usable WiFi Hotspot STA channels on the local device. +message WifiHotspotStaUsableChannels { + repeated int32 channels = 1 [packed = true]; +} + +// LocationHint is used to specify a location as well as format. +message LocationHint { + // Location is the location, provided in the format specified by format. + optional string location = 1; + + // the format of location. + optional LocationStandard.Format format = 2; +} + +message LocationStandard { + enum Format { + UNKNOWN = 0; + // E164 country codes: + // https://en.wikipedia.org/wiki/List_of_country_calling_codes + // e.g. +1 for USA + E164_CALLING = 1; + + // ISO 3166-1 alpha-2 country codes: + // https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 + ISO_3166_1_ALPHA_2 = 2; + } +} + +// Device capability for OS information. +message OsInfo { + enum OsType { + UNKNOWN_OS_TYPE = 0; + ANDROID = 1; + CHROME_OS = 2; + WINDOWS = 3; + APPLE = 4; + LINUX = 100; // g3 test environment + } + + optional OsType type = 1; +} diff --git a/submissions/sapphire/ProtobufSource/securegcm.proto b/submissions/sapphire/ProtobufSource/securegcm.proto new file mode 100644 index 00000000..0325f06e --- /dev/null +++ b/submissions/sapphire/ProtobufSource/securegcm.proto @@ -0,0 +1,308 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package securegcm; + +option optimize_for = LITE_RUNTIME; +option java_package = "com.google.security.cryptauth.lib.securegcm"; +option java_outer_classname = "SecureGcmProto"; +option objc_class_prefix = "SGCM"; + +// Message used only during enrollment +// Field numbers should be kept in sync with DeviceInfo in: +// java/com/google/security/cryptauth/backend/services/common/common.proto +message GcmDeviceInfo { + // This field's name does not match the one in DeviceInfo for legacy reasons. + // Consider using long_device_id and device_type instead when enrolling + // non-android devices. + optional fixed64 android_device_id = 1; + + // Used for device_address of DeviceInfo field 2, but for GCM capable devices. + optional bytes gcm_registration_id = 102; + + // Used for device_address of DeviceInfo field 2, but for iOS devices. + optional bytes apn_registration_id = 202; + + // Does the user have notifications enabled for the given device address. + optional bool notification_enabled = 203 [default = true]; + + // Used for device_address of DeviceInfo field 2, a Bluetooth Mac address for + // the device (e.g., to be used with EasyUnlock) + optional string bluetooth_mac_address = 302; + + // SHA-256 hash of the device master key (from the key exchange). + // Differs from DeviceInfo field 3, which contains the actual master key. + optional bytes device_master_key_hash = 103; + + // A SecureMessage.EcP256PublicKey + required bytes user_public_key = 4; + + // device's model name + // (e.g., an android.os.Build.MODEL or UIDevice.model) + optional string device_model = 7; + + // device's locale + optional string locale = 8; + + // The handle for user_public_key (and implicitly, a master key) + optional bytes key_handle = 9; + + // The initial counter value for the device, sent by the device + optional int64 counter = 12 [default = 0]; + + // The Operating System version on the device + // (e.g., an android.os.Build.DISPLAY or UIDevice.systemVersion) + optional string device_os_version = 13; + + // The Operating System version number on the device + // (e.g., an android.os.Build.VERSION.SDK_INT) + optional int64 device_os_version_code = 14; + + // The Operating System release on the device + // (e.g., an android.os.Build.VERSION.RELEASE) + optional string device_os_release = 15; + + // The Operating System codename on the device + // (e.g., an android.os.Build.VERSION.CODENAME or UIDevice.systemName) + optional string device_os_codename = 16; + + // The software version running on the device + // (e.g., Authenticator app version string) + optional string device_software_version = 17; + + // The software version number running on the device + // (e.g., Authenticator app version code) + optional int64 device_software_version_code = 18; + + // Software package information if applicable + // (e.g., com.google.android.apps.authenticator2) + optional string device_software_package = 19; + + // Size of the display in thousandths of an inch (e.g., 7000 mils = 7 in) + optional int32 device_display_diagonal_mils = 22; + + // For Authzen capable devices, their Authzen protocol version + optional int32 device_authzen_version = 24; + + // Not all devices have device identifiers that fit in 64 bits. + optional bytes long_device_id = 29; + + // The device manufacturer name + // (e.g., android.os.Build.MANUFACTURER) + optional string device_manufacturer = 31; + + // Used to indicate which type of device this is. + optional DeviceType device_type = 32 [default = ANDROID]; + + // Fields corresponding to screenlock type/features and hardware features + // should be numbered in the 400 range. + + // Is this device using a secure screenlock (e.g., pattern or pin unlock) + optional bool using_secure_screenlock = 400 [default = false]; + + // Is auto-unlocking the screenlock (e.g., when at "home") supported? + optional bool auto_unlock_screenlock_supported = 401 [default = false]; + + // Is auto-unlocking the screenlock (e.g., when at "home") enabled? + optional bool auto_unlock_screenlock_enabled = 402 [default = false]; + + // Does the device have a Bluetooth (classic) radio? + optional bool bluetooth_radio_supported = 403 [default = false]; + + // Is the Bluetooth (classic) radio on? + optional bool bluetooth_radio_enabled = 404 [default = false]; + + // Does the device hardware support a mobile data connection? + optional bool mobile_data_supported = 405 [default = false]; + + // Does the device support tethering? + optional bool tethering_supported = 406 [default = false]; + + // Does the device have a BLE radio? + optional bool ble_radio_supported = 407 [default = false]; + + // Is the device a "Pixel Experience" Android device? + optional bool pixel_experience = 408 [default = false]; + + // Is the device running in the ARC++ container on a chromebook? + optional bool arc_plus_plus = 409 [default = false]; + + // Is the value set in |using_secure_screenlock| reliable? On some Android + // devices, the platform API to get the screenlock state is not trustworthy. + // See b/32212161. + optional bool is_screenlock_state_flaky = 410 [default = false]; + + // A list of multi-device software features supported by the device. + repeated SoftwareFeature supported_software_features = 411; + + // A list of multi-device software features currently enabled (active) on the + // device. + repeated SoftwareFeature enabled_software_features = 412; + + // The enrollment session id this is sent with + optional bytes enrollment_session_id = 1000; + + // A copy of the user's OAuth token + optional string oauth_token = 1001; +} + +// This enum is used by iOS devices as values for device_display_diagonal_mils +// in GcmDeviceInfo. There is no good way to calculate it on those devices. +enum AppleDeviceDiagonalMils { + // This is the mils diagonal on an iPhone 5. + APPLE_PHONE = 4000; + // This is the mils diagonal on an iPad mini. + APPLE_PAD = 7900; +} + +// This should be kept in sync with DeviceType in: +// java/com/google/security/cryptauth/backend/services/common/common_enums.proto +enum DeviceType { + UNKNOWN = 0; + ANDROID = 1; + CHROME = 2; + IOS = 3; + BROWSER = 4; + OSX = 5; +} + +// MultiDevice features which may be supported and enabled on a device. See +enum SoftwareFeature { + UNKNOWN_FEATURE = 0; + BETTER_TOGETHER_HOST = 1; + BETTER_TOGETHER_CLIENT = 2; + EASY_UNLOCK_HOST = 3; + EASY_UNLOCK_CLIENT = 4; + MAGIC_TETHER_HOST = 5; + MAGIC_TETHER_CLIENT = 6; + SMS_CONNECT_HOST = 7; + SMS_CONNECT_CLIENT = 8; +} + +// A list of "reasons" that can be provided for calling server-side APIs. +// This is particularly important for calls that can be triggered by different +// kinds of events. Please try to keep reasons as generic as possible, so that +// codes can be re-used by various callers in a sensible fashion. +enum InvocationReason { + REASON_UNKNOWN = 0; + // First run of the software package invoking this call + REASON_INITIALIZATION = 1; + // Ordinary periodic actions (e.g. monthly master key rotation) + REASON_PERIODIC = 2; + // Slow-cycle periodic action (e.g. yearly keypair rotation???) + REASON_SLOW_PERIODIC = 3; + // Fast-cycle periodic action (e.g. daily sync for Smart Lock users) + REASON_FAST_PERIODIC = 4; + // Expired state (e.g. expired credentials, or cached entries) was detected + REASON_EXPIRATION = 5; + // An unexpected protocol failure occurred (so attempting to repair state) + REASON_FAILURE_RECOVERY = 6; + // A new account has been added to the device + REASON_NEW_ACCOUNT = 7; + // An existing account on the device has been changed + REASON_CHANGED_ACCOUNT = 8; + // The user toggled the state of a feature (e.g. Smart Lock enabled via BT) + REASON_FEATURE_TOGGLED = 9; + // A "push" from the server caused this action (e.g. a sync tickle) + REASON_SERVER_INITIATED = 10; + // A local address change triggered this (e.g. GCM registration id changed) + REASON_ADDRESS_CHANGE = 11; + // A software update has triggered this + REASON_SOFTWARE_UPDATE = 12; + // A manual action by the user triggered this (e.g. commands sent via adb) + REASON_MANUAL = 13; + // A custom key has been invalidated on the device (e.g. screen lock is + // disabled). + REASON_CUSTOM_KEY_INVALIDATION = 14; + // Periodic action triggered by auth_proximity + REASON_PROXIMITY_PERIODIC = 15; +} + +enum Type { + ENROLLMENT = 0; + TICKLE = 1; + TX_REQUEST = 2; + TX_REPLY = 3; + TX_SYNC_REQUEST = 4; + TX_SYNC_RESPONSE = 5; + TX_PING = 6; + DEVICE_INFO_UPDATE = 7; + TX_CANCEL_REQUEST = 8; + + // DEPRECATED (can be re-used after Aug 2015) + PROXIMITYAUTH_PAIRING = 10; + + // The kind of identity assertion generated by a "GCM V1" device (i.e., + // an Android phone that has registered with us a public and a symmetric + // key) + GCMV1_IDENTITY_ASSERTION = 11; + + // Device-to-device communications are protected by an unauthenticated + // Diffie-Hellman exchange. The InitiatorHello message is simply the + // initiator's public DH key, and is not encoded as a SecureMessage, so + // it doesn't have a tag. + // The ResponderHello message (which is sent by the responder + // to the initiator), on the other hand, carries a payload that is protected + // by the derived shared key. It also contains the responder's + // public DH key. ResponderHelloAndPayload messages have the + // DEVICE_TO_DEVICE_RESPONDER_HELLO tag. + DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD = 12; + + // Device-to-device communications are protected by an unauthenticated + // Diffie-Hellman exchange. Once the initiator and responder + // agree on a shared key (through Diffie-Hellman), they will use messages + // tagged with DEVICE_TO_DEVICE_MESSAGE to exchange data. + DEVICE_TO_DEVICE_MESSAGE = 13; + + // Notification to let a device know it should contact a nearby device. + DEVICE_PROXIMITY_CALLBACK = 14; + + // Device-to-device communications are protected by an unauthenticated + // Diffie-Hellman exchange. During device-to-device authentication, the first + // message from initiator (the challenge) is signed and put into the payload + // of the message sent back to the initiator. + UNLOCK_KEY_SIGNED_CHALLENGE = 15; + + // Specialty (corp only) features + LOGIN_NOTIFICATION = 101; +} + +message GcmMetadata { + required Type type = 1; + optional int32 version = 2 [default = 0]; +} + +message Tickle { + // Time after which this tickle should expire + optional fixed64 expiry_time = 1; +} + +message LoginNotificationInfo { + // Time at which the server received the login notification request. + optional fixed64 creation_time = 2; + + // Must correspond to user_id in LoginNotificationRequest, if set. + optional string email = 3; + + // Host where the user's credentials were used to login, if meaningful. + optional string host = 4; + + // Location from where the user's credentials were used, if meaningful. + optional string source = 5; + + // Type of login, e.g. ssh, gnome-screensaver, or web. + optional string event_type = 6; +} diff --git a/submissions/sapphire/ProtobufSource/securemessage.proto b/submissions/sapphire/ProtobufSource/securemessage.proto new file mode 100644 index 00000000..5118d357 --- /dev/null +++ b/submissions/sapphire/ProtobufSource/securemessage.proto @@ -0,0 +1,126 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Proto definitions for SecureMessage format + +syntax = "proto2"; + +package securemessage; + +option optimize_for = LITE_RUNTIME; +option java_package = "com.google.security.cryptauth.lib.securemessage"; +option java_outer_classname = "SecureMessageProto"; +option objc_class_prefix = "SMSG"; + +message SecureMessage { + // Must contain a HeaderAndBody message + required bytes header_and_body = 1; + // Signature of header_and_body + required bytes signature = 2; +} + +// Supported "signature" schemes (both symmetric key and public key based) +enum SigScheme { + HMAC_SHA256 = 1; + ECDSA_P256_SHA256 = 2; + // Not recommended -- use ECDSA_P256_SHA256 instead + RSA2048_SHA256 = 3; +} + +// Supported encryption schemes +enum EncScheme { + // No encryption + NONE = 1; + AES_256_CBC = 2; +} + +message Header { + required SigScheme signature_scheme = 1; + required EncScheme encryption_scheme = 2; + // Identifies the verification key + optional bytes verification_key_id = 3; + // Identifies the decryption key + optional bytes decryption_key_id = 4; + // Encryption may use an IV + optional bytes iv = 5; + // Arbitrary per-protocol public data, to be sent with the plain-text header + optional bytes public_metadata = 6; + // The length of some associated data this is not sent in this SecureMessage, + // but which will be bound to the signature. + optional uint32 associated_data_length = 7 [default = 0]; +} + +message HeaderAndBody { + // Public data about this message (to be bound in the signature) + required Header header = 1; + // Payload data + required bytes body = 2; +} + +// Must be kept wire-format compatible with HeaderAndBody. Provides the +// SecureMessage code with a consistent wire-format representation that +// remains stable irrespective of protobuf implementation choices. This +// low-level representation of a HeaderAndBody should not be used by +// any code outside of the SecureMessage library implementation/tests. +message HeaderAndBodyInternal { + // A raw (wire-format) byte encoding of a Header, suitable for hashing + required bytes header = 1; + // Payload data + required bytes body = 2; +} + +// ------- +// The remainder of the messages defined here are provided only for +// convenience. They are not needed for SecureMessage proper, but are +// commonly useful wherever SecureMessage might be applied. +// ------- + +// A list of supported public key types +enum PublicKeyType { + EC_P256 = 1; + RSA2048 = 2; + // 2048-bit MODP group 14, from RFC 3526 + DH2048_MODP = 3; +} + +// A convenience proto for encoding NIST P-256 elliptic curve public keys +message EcP256PublicKey { + // x and y are encoded in big-endian two's complement (slightly wasteful) + // Client MUST verify (x,y) is a valid point on NIST P256 + required bytes x = 1; + required bytes y = 2; +} + +// A convenience proto for encoding RSA public keys with small exponents +message SimpleRsaPublicKey { + // Encoded in big-endian two's complement + required bytes n = 1; + optional int32 e = 2 [default = 65537]; +} + +// A convenience proto for encoding Diffie-Hellman public keys, +// for use only when Elliptic Curve based key exchanges are not possible. +// (Note that the group parameters must be specified separately) +message DhPublicKey { + // Big-endian two's complement encoded group element + required bytes y = 1; +} + +message GenericPublicKey { + required PublicKeyType type = 1; + optional EcP256PublicKey ec_p256_public_key = 2; + optional SimpleRsaPublicKey rsa2048_public_key = 3; + // Use only as a last resort + optional DhPublicKey dh2048_public_key = 4; +} diff --git a/submissions/sapphire/ProtobufSource/ukey.proto b/submissions/sapphire/ProtobufSource/ukey.proto new file mode 100644 index 00000000..327d8d3d --- /dev/null +++ b/submissions/sapphire/ProtobufSource/ukey.proto @@ -0,0 +1,105 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +syntax = "proto2"; + +package securegcm; + +option optimize_for = LITE_RUNTIME; +option java_package = "com.google.security.cryptauth.lib.securegcm"; +option java_outer_classname = "UkeyProto"; + +message Ukey2Message { + enum Type { + UNKNOWN_DO_NOT_USE = 0; + ALERT = 1; + CLIENT_INIT = 2; + SERVER_INIT = 3; + CLIENT_FINISH = 4; + } + + optional Type message_type = 1; // Identifies message type + optional bytes message_data = 2; // Actual message, to be parsed according to + // message_type +} + +message Ukey2Alert { + enum AlertType { + // Framing errors + BAD_MESSAGE = 1; // The message could not be deserialized + BAD_MESSAGE_TYPE = 2; // message_type has an undefined value + INCORRECT_MESSAGE = 3; // message_type received does not correspond to + // expected type at this stage of the protocol + BAD_MESSAGE_DATA = 4; // Could not deserialize message_data as per + // value inmessage_type + + // ClientInit and ServerInit errors + BAD_VERSION = 100; // version is invalid; server cannot find + // suitable version to speak with client. + BAD_RANDOM = 101; // Random data is missing or of incorrect + // length + BAD_HANDSHAKE_CIPHER = 102; // No suitable handshake ciphers were found + BAD_NEXT_PROTOCOL = 103; // The next protocol is missing, unknown, or + // unsupported + BAD_PUBLIC_KEY = 104; // The public key could not be parsed + + // Other errors + INTERNAL_ERROR = 200; // An internal error has occurred. error_message + // may contain additional details for logging + // and debugging. + } + + optional AlertType type = 1; + optional string error_message = 2; +} + +enum Ukey2HandshakeCipher { + RESERVED = 0; + P256_SHA512 = 100; // NIST P-256 used for ECDH, SHA512 used for + // commitment + CURVE25519_SHA512 = 200; // Curve 25519 used for ECDH, SHA512 used for + // commitment +} + +message Ukey2ClientInit { + optional int32 version = 1; // highest supported version for rollback + // protection + optional bytes random = 2; // random bytes for replay/reuse protection + + // One commitment (hash of ClientFinished containing public key) per supported + // cipher + message CipherCommitment { + optional Ukey2HandshakeCipher handshake_cipher = 1; + optional bytes commitment = 2; + } + repeated CipherCommitment cipher_commitments = 3; + + // Next protocol that the client wants to speak. + optional string next_protocol = 4; +} + +message Ukey2ServerInit { + optional int32 version = 1; // highest supported version for rollback + // protection + optional bytes random = 2; // random bytes for replay/reuse protection + + // Selected Cipher and corresponding public key + optional Ukey2HandshakeCipher handshake_cipher = 3; + optional bytes public_key = 4; +} + +message Ukey2ClientFinished { + optional bytes public_key = 1; // public key matching selected handshake + // cipher +} diff --git a/submissions/sapphire/ProtobufSource/wire_format.proto b/submissions/sapphire/ProtobufSource/wire_format.proto new file mode 100644 index 00000000..6853e22d --- /dev/null +++ b/submissions/sapphire/ProtobufSource/wire_format.proto @@ -0,0 +1,236 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Brought from: //depot/google3/location/nearby/sharing/proto/wire_format.proto +// At CL 317565061 + +syntax = "proto2"; + +package sharing.nearby; + +// Required in Chrome. +option optimize_for = LITE_RUNTIME; + +// File metadata. Does not include the actual bytes of the file. +// NEXT_ID=6 +message FileMetadata { + enum Type { + UNKNOWN = 0; + IMAGE = 1; + VIDEO = 2; + APP = 3; + AUDIO = 4; + } + + // The human readable name of this file (eg. 'Cookbook.pdf'). + optional string name = 1; + + // The type of file (eg. 'IMAGE' from 'dog.jpg'). Specifying a type helps + // provide a richer experience on the receiving side. + optional Type type = 2 [default = UNKNOWN]; + + // The FILE payload id that will be sent as a follow up containing the actual + // bytes of the file. + optional int64 payload_id = 3; + + // The total size of the file. + optional int64 size = 4; + + // The mimeType of file (eg. 'image/jpeg' from 'dog.jpg'). Specifying a + // mimeType helps provide a richer experience on receiving side. + optional string mime_type = 5 [default = "application/octet-stream"]; + + // A uuid for the attachment. Should be unique across all attachments. + optional int64 id = 6; +} + +// NEXT_ID=5 +message TextMetadata { + enum Type { + UNKNOWN = 0; + TEXT = 1; + // Open with browsers. + URL = 2; + // Open with map apps. + ADDRESS = 3; + // Dial. + PHONE_NUMBER = 4; + } + + // The title of the text content. + optional string text_title = 2; + + // The type of text (phone number, url, address, or plain text). + optional Type type = 3 [default = UNKNOWN]; + + // The BYTE payload id that will be sent as a follow up containing the actual + // bytes of the text. + optional int64 payload_id = 4; + + // The size of the text content. + optional int64 size = 5; + + // A uuid for the attachment. Should be unique across all attachments. + optional int64 id = 6; +} + +// NEXT_ID=5 +message WifiCredentialsMetadata { + enum SecurityType { + UNKNOWN_SECURITY_TYPE = 0; + OPEN = 1; + WPA_PSK = 2; + WEP = 3; + } + + // The Wifi network name. This will be sent in introduction. + optional string ssid = 2; + + // The security type of network (OPEN, WPA_PSK, WEP). + optional SecurityType security_type = 3 [default = UNKNOWN_SECURITY_TYPE]; + + // The BYTE payload id that will be sent as a follow up containing the + // password. + optional int64 payload_id = 4; + + // A uuid for the attachment. Should be unique across all attachments. + optional int64 id = 5; +} + +// A frame used when sending messages over the wire. +// NEXT_ID=3 +message Frame { + enum Version { + UNKNOWN_VERSION = 0; + V1 = 1; + } + optional Version version = 1; + + // Right now there's only 1 version, but if there are more, exactly one of + // the following fields will be set. + optional V1Frame v1 = 2; +} + +// NEXT_ID=7 +message V1Frame { + enum FrameType { + UNKNOWN_FRAME_TYPE = 0; + INTRODUCTION = 1; + RESPONSE = 2; + PAIRED_KEY_ENCRYPTION = 3; + PAIRED_KEY_RESULT = 4; + CERTIFICATE_INFO = 5; + CANCEL = 6; + } + + optional FrameType type = 1; + + // Exactly one of the following fields will be set. + optional IntroductionFrame introduction = 2; + optional ConnectionResponseFrame connection_response = 3; + optional PairedKeyEncryptionFrame paired_key_encryption = 4; + optional PairedKeyResultFrame paired_key_result = 5; + optional CertificateInfoFrame certificate_info = 6; +} + +// An introduction packet sent by the sending side. Contains a list of files +// they'd like to share. +// NEXT_ID=4 +message IntroductionFrame { + repeated FileMetadata file_metadata = 1; + repeated TextMetadata text_metadata = 2; + // The required app package to open the content. May be null. + optional string required_package = 3; + repeated WifiCredentialsMetadata wifi_credentials_metadata = 4; +} + +// A response packet sent by the receiving side. Accepts or rejects the list of +// files. +// NEXT_ID=2 +message ConnectionResponseFrame { + enum Status { + UNKNOWN = 0; + ACCEPT = 1; + REJECT = 2; + NOT_ENOUGH_SPACE = 3; + UNSUPPORTED_ATTACHMENT_TYPE = 4; + TIMED_OUT = 5; + } + + // The receiving side's response. + optional Status status = 1; +} + +// A paired key encryption packet sent between devices, contains signed data. +// NEXT_ID=3 +message PairedKeyEncryptionFrame { + // The encrypted data in byte array format. + optional bytes signed_data = 1; + + // The hash of a certificate id. + optional bytes secret_id_hash = 2; + + // An optional encrypted data in byte array format. + optional bytes optional_signed_data = 3; +} + +// A paired key verification result packet sent between devices. +// NEXT_ID=2 +message PairedKeyResultFrame { + enum Status { + UNKNOWN = 0; + SUCCESS = 1; + FAIL = 2; + UNABLE = 3; + } + + // The verification result. + optional Status status = 1; +} + +// A package containing certificate info to be shared to remote device offline. +// NEXT_ID=2 +message CertificateInfoFrame { + // The public certificates to be shared with remote devices. + repeated PublicCertificate public_certificate = 1; +} + +// A public certificate from the local device. +// NEXT_ID=8 +message PublicCertificate { + // The unique id of the public certificate. + optional bytes secret_id = 1; + + // A bytes representation of a Secret Key owned by contact, to decrypt the + // metadata_key stored within the advertisement. + optional bytes authenticity_key = 2; + + // A bytes representation a public key of X509Certificate, owned by contact, + // to decrypt encrypted UKEY2 (from Nearby Connections API) as a hand shake in + // contact verification phase. + optional bytes public_key = 3; + + // The time in millis from epoch when this certificate becomes effective. + optional int64 start_time = 4; + + // The time in millis from epoch when this certificate expires. + optional int64 end_time = 5; + + // The encrypted metadata in bytes, contains personal information of the + // device/user who created this certificate. Needs to be decrypted into bytes, + // and converted back to EncryptedMetadata object to access fields. + optional bytes encrypted_metadata_bytes = 6; + + // The tag for verifying metadata_encryption_key. + optional bytes metadata_encryption_key_tag = 7; +} + +// NEXT_ID=3 +message WifiCredentials { + // Wi-Fi password. + optional string password = 1; + // True if the network is a hidden network that is not broadcasting its SSID. + // Default is false. + optional bool hidden_ssid = 2 [default = false]; +} \ No newline at end of file diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.pbxproj b/submissions/sapphire/Sapphire.xcodeproj/project.pbxproj new file mode 100644 index 00000000..fc9fd989 --- /dev/null +++ b/submissions/sapphire/Sapphire.xcodeproj/project.pbxproj @@ -0,0 +1,986 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + DA5256792E162B9F00D8F42E /* NearDropDisplayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5256782E162B9F00D8F42E /* NearDropDisplayState.swift */; }; + DA52567B2E162FA900D8F42E /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA52567A2E162FA900D8F42E /* ShareViewController.swift */; }; + DA52567D2E162FBE00D8F42E /* DeviceListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA52567C2E162FBE00D8F42E /* DeviceListCell.swift */; }; + DA7C49632E15ACA60049937A /* MediaRemoteAdapter in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49622E15ACA60049937A /* MediaRemoteAdapter */; }; + DA7C49642E15ACAA0049937A /* MediaRemoteAdapter in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49622E15ACA60049937A /* MediaRemoteAdapter */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + DA7C49982E15D33A0049937A /* OutboundNearbyConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498D2E15D33A0049937A /* OutboundNearbyConnection.swift */; }; + DA7C49992E15D33A0049937A /* wire_format.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49942E15D33A0049937A /* wire_format.pb.swift */; }; + DA7C499A2E15D33A0049937A /* securemessage.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49922E15D33A0049937A /* securemessage.pb.swift */; }; + DA7C499B2E15D33A0049937A /* InboundNearbyConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49892E15D33A0049937A /* InboundNearbyConnection.swift */; }; + DA7C499C2E15D33A0049937A /* NearbyConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498B2E15D33A0049937A /* NearbyConnectionManager.swift */; }; + DA7C499D2E15D33A0049937A /* Data+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49962E15D33A0049937A /* Data+Extensions.swift */; }; + DA7C499E2E15D33A0049937A /* device_to_device_messages.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498F2E15D33A0049937A /* device_to_device_messages.pb.swift */; }; + DA7C499F2E15D33A0049937A /* ukey.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49932E15D33A0049937A /* ukey.pb.swift */; }; + DA7C49A12E15D33A0049937A /* NearbyConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498A2E15D33A0049937A /* NearbyConnection.swift */; }; + DA7C49A22E15D33A0049937A /* offline_wire_formats.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49902E15D33A0049937A /* offline_wire_formats.pb.swift */; }; + DA7C49A32E15D33A0049937A /* securegcm.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49912E15D33A0049937A /* securegcm.pb.swift */; }; + DA7C49A52E15D34D0049937A /* SwiftECC in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49A42E15D34D0049937A /* SwiftECC */; }; + DA7C49A82E15D3660049937A /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49A72E15D3660049937A /* SwiftProtobuf */; }; + DA7C49AA2E15D3660049937A /* SwiftProtobufPluginLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49A92E15D3660049937A /* SwiftProtobufPluginLibrary */; }; + DA7C49AC2E15D3660049937A /* protoc-gen-swift in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49AB2E15D3660049937A /* protoc-gen-swift */; }; + DA7C49AD2E15D3800049937A /* libNearbyShare.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49802E15CCA50049937A /* libNearbyShare.dylib */; }; + DA9385462E17B443006C5361 /* DisplayServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9385452E17B443006C5361 /* DisplayServices.framework */; }; + DABC6CC02E16F57B00A5CF83 /* TransferDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABC6CBC2E16F53E00A5CF83 /* TransferDirection.swift */; }; + DABC6CDD2E17457A00A5CF83 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DABC6CDB2E17457700A5CF83 /* IOKit.framework */; }; + DABC6CDF2E17458500A5CF83 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49B92E15DB160049937A /* UserNotifications.framework */; }; + DABC6CE12E17458600A5CF83 /* UserNotificationsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49B82E15DB160049937A /* UserNotificationsUI.framework */; }; + DABC6CE32E1749CA00A5CF83 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DABC6CD72E17455F00A5CF83 /* CoreGraphics.framework */; }; + DACBB01D2E20321D00740C9B /* libNearbyShare.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49802E15CCA50049937A /* libNearbyShare.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + DAF7D8AB2E207BBC00AB0820 /* SwiftProtobufPluginLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = DAF7D8AA2E207BBC00AB0820 /* SwiftProtobufPluginLibrary */; }; + DAF7D8AE2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = DAF7D8AD2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + DA46CF882DCBCA0100F00EC5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DA46CF6E2DCBCA0000F00EC5 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DA46CF752DCBCA0000F00EC5; + remoteInfo = DynamicNotch; + }; + DA46CF922DCBCA0100F00EC5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DA46CF6E2DCBCA0000F00EC5 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DA46CF752DCBCA0000F00EC5; + remoteInfo = DynamicNotch; + }; + DA7C49AF2E15D3800049937A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DA46CF6E2DCBCA0000F00EC5 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DA7C497F2E15CCA50049937A; + remoteInfo = NearbyShare; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + DAE70B782E12300B001F0890 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + DA7C49642E15ACAA0049937A /* MediaRemoteAdapter in Embed Frameworks */, + DACBB01D2E20321D00740C9B /* libNearbyShare.dylib in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + DAF7D8AC2E207C5100AB0820 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + DAF7D8AE2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + DA46CF762DCBCA0000F00EC5 /* Sapphire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sapphire.app; sourceTree = BUILT_PRODUCTS_DIR; }; + DA46CF872DCBCA0100F00EC5 /* SapphireTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SapphireTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DA46CF912DCBCA0100F00EC5 /* SapphireUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SapphireUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DA5256782E162B9F00D8F42E /* NearDropDisplayState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearDropDisplayState.swift; sourceTree = ""; }; + DA52567A2E162FA900D8F42E /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; + DA52567C2E162FBE00D8F42E /* DeviceListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceListCell.swift; sourceTree = ""; }; + DA7C49802E15CCA50049937A /* libNearbyShare.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libNearbyShare.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + DA7C49892E15D33A0049937A /* InboundNearbyConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InboundNearbyConnection.swift; sourceTree = ""; }; + DA7C498A2E15D33A0049937A /* NearbyConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyConnection.swift; sourceTree = ""; }; + DA7C498B2E15D33A0049937A /* NearbyConnectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyConnectionManager.swift; sourceTree = ""; }; + DA7C498D2E15D33A0049937A /* OutboundNearbyConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutboundNearbyConnection.swift; sourceTree = ""; }; + DA7C498F2E15D33A0049937A /* device_to_device_messages.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = device_to_device_messages.pb.swift; sourceTree = ""; }; + DA7C49902E15D33A0049937A /* offline_wire_formats.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = offline_wire_formats.pb.swift; sourceTree = ""; }; + DA7C49912E15D33A0049937A /* securegcm.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = securegcm.pb.swift; sourceTree = ""; }; + DA7C49922E15D33A0049937A /* securemessage.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = securemessage.pb.swift; sourceTree = ""; }; + DA7C49932E15D33A0049937A /* ukey.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ukey.pb.swift; sourceTree = ""; }; + DA7C49942E15D33A0049937A /* wire_format.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = wire_format.pb.swift; sourceTree = ""; }; + DA7C49962E15D33A0049937A /* Data+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Extensions.swift"; sourceTree = ""; }; + DA7C49B82E15DB160049937A /* UserNotificationsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotificationsUI.framework; path = System/Library/Frameworks/UserNotificationsUI.framework; sourceTree = SDKROOT; }; + DA7C49B92E15DB160049937A /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; }; + DA9385432E17B2A4006C5361 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; + DA9385452E17B443006C5361 /* DisplayServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DisplayServices.framework; path = ../../../../System/Library/PrivateFrameworks/DisplayServices.framework; sourceTree = ""; }; + DABC6CBC2E16F53E00A5CF83 /* TransferDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransferDirection.swift; sourceTree = ""; }; + DABC6CCF2E173F0600A5CF83 /* BezelServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BezelServices.framework; path = ../../../../System/Library/PrivateFrameworks/BezelServices.framework; sourceTree = ""; }; + DABC6CD72E17455F00A5CF83 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + DABC6CDB2E17457700A5CF83 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + DABC6D012E177F6100A5CF83 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; + DAF7D8AD2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SwiftProtobuf_SwiftProtobuf.bundle; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + DA300BA42E1399620022B999 /* Exceptions for "Sapphire" folder in "Sapphire" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + App/Info.plist, + ); + target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; + }; + DA7C49BE2E15DC180049937A /* Exceptions for "ObjC" folder in "NearbyShare" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + "Bridging-Header.h", + NDNotificationCenterHackery.h, + NDNotificationCenterHackery.m, + PrivateAPI.h, + ); + target = DA7C497F2E15CCA50049937A /* NearbyShare */; + }; + DADB61FD2E1F774400238226 /* Exceptions for "ObjC" folder in "Sapphire" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + NDNotificationCenterHackery.m, + ); + target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + DA183FC92E122AF30056667D /* Sapphire */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + DA300BA42E1399620022B999 /* Exceptions for "Sapphire" folder in "Sapphire" target */, + ); + path = Sapphire; + sourceTree = ""; + }; + DA46CF8A2DCBCA0100F00EC5 /* SapphireNotchTests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = SapphireNotchTests; + sourceTree = ""; + }; + DA46CF942DCBCA0100F00EC5 /* SapphireNotchUITests */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = SapphireNotchUITests; + sourceTree = ""; + }; + DA7C49B62E15D7360049937A /* ObjC */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + DADB61FD2E1F774400238226 /* Exceptions for "ObjC" folder in "Sapphire" target */, + DA7C49BE2E15DC180049937A /* Exceptions for "ObjC" folder in "NearbyShare" target */, + ); + path = ObjC; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + DA46CF732DCBCA0000F00EC5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DABC6CE32E1749CA00A5CF83 /* CoreGraphics.framework in Frameworks */, + DABC6CE12E17458600A5CF83 /* UserNotificationsUI.framework in Frameworks */, + DA7C49632E15ACA60049937A /* MediaRemoteAdapter in Frameworks */, + DABC6CDF2E17458500A5CF83 /* UserNotifications.framework in Frameworks */, + DAF7D8AB2E207BBC00AB0820 /* SwiftProtobufPluginLibrary in Frameworks */, + DA7C49AD2E15D3800049937A /* libNearbyShare.dylib in Frameworks */, + DABC6CDD2E17457A00A5CF83 /* IOKit.framework in Frameworks */, + DA9385462E17B443006C5361 /* DisplayServices.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA46CF842DCBCA0100F00EC5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA46CF8E2DCBCA0100F00EC5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA7C497E2E15CCA50049937A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DA7C49AC2E15D3660049937A /* protoc-gen-swift in Frameworks */, + DA7C49AA2E15D3660049937A /* SwiftProtobufPluginLibrary in Frameworks */, + DA7C49A52E15D34D0049937A /* SwiftECC in Frameworks */, + DA7C49A82E15D3660049937A /* SwiftProtobuf in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + DA46CF6D2DCBCA0000F00EC5 = { + isa = PBXGroup; + children = ( + DAF7D8AD2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle */, + DA183FC92E122AF30056667D /* Sapphire */, + DA46CF8A2DCBCA0100F00EC5 /* SapphireNotchTests */, + DA46CF942DCBCA0100F00EC5 /* SapphireNotchUITests */, + DA46CFCE2DCE7B9E00F00EC5 /* Frameworks */, + DA46CF772DCBCA0000F00EC5 /* Products */, + DA7C498E2E15D33A0049937A /* Nearby */, + DA7C49952E15D33A0049937A /* ProtobufGenerated */, + DA7C49972E15D33A0049937A /* Util */, + DA7C49B62E15D7360049937A /* ObjC */, + ); + sourceTree = ""; + }; + DA46CF772DCBCA0000F00EC5 /* Products */ = { + isa = PBXGroup; + children = ( + DA46CF762DCBCA0000F00EC5 /* Sapphire.app */, + DA46CF872DCBCA0100F00EC5 /* SapphireTests.xctest */, + DA46CF912DCBCA0100F00EC5 /* SapphireUITests.xctest */, + DA7C49802E15CCA50049937A /* libNearbyShare.dylib */, + ); + name = Products; + sourceTree = ""; + }; + DA46CFCE2DCE7B9E00F00EC5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + DA9385452E17B443006C5361 /* DisplayServices.framework */, + DA9385432E17B2A4006C5361 /* AppKit.framework */, + DABC6D012E177F6100A5CF83 /* ApplicationServices.framework */, + DABC6CDB2E17457700A5CF83 /* IOKit.framework */, + DABC6CD72E17455F00A5CF83 /* CoreGraphics.framework */, + DABC6CCF2E173F0600A5CF83 /* BezelServices.framework */, + DA7C49B92E15DB160049937A /* UserNotifications.framework */, + DA7C49B82E15DB160049937A /* UserNotificationsUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + DA7C498E2E15D33A0049937A /* Nearby */ = { + isa = PBXGroup; + children = ( + DABC6CBC2E16F53E00A5CF83 /* TransferDirection.swift */, + DA7C49892E15D33A0049937A /* InboundNearbyConnection.swift */, + DA52567A2E162FA900D8F42E /* ShareViewController.swift */, + DA52567C2E162FBE00D8F42E /* DeviceListCell.swift */, + DA7C498A2E15D33A0049937A /* NearbyConnection.swift */, + DA7C498B2E15D33A0049937A /* NearbyConnectionManager.swift */, + DA5256782E162B9F00D8F42E /* NearDropDisplayState.swift */, + DA7C498D2E15D33A0049937A /* OutboundNearbyConnection.swift */, + ); + path = Nearby; + sourceTree = ""; + }; + DA7C49952E15D33A0049937A /* ProtobufGenerated */ = { + isa = PBXGroup; + children = ( + DA7C498F2E15D33A0049937A /* device_to_device_messages.pb.swift */, + DA7C49902E15D33A0049937A /* offline_wire_formats.pb.swift */, + DA7C49912E15D33A0049937A /* securegcm.pb.swift */, + DA7C49922E15D33A0049937A /* securemessage.pb.swift */, + DA7C49932E15D33A0049937A /* ukey.pb.swift */, + DA7C49942E15D33A0049937A /* wire_format.pb.swift */, + ); + path = ProtobufGenerated; + sourceTree = ""; + }; + DA7C49972E15D33A0049937A /* Util */ = { + isa = PBXGroup; + children = ( + DA7C49962E15D33A0049937A /* Data+Extensions.swift */, + ); + path = Util; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + DA7C497C2E15CCA50049937A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + DA46CF752DCBCA0000F00EC5 /* Sapphire */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA46CF9B2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "Sapphire" */; + buildPhases = ( + DA46CF722DCBCA0000F00EC5 /* Sources */, + DA46CF732DCBCA0000F00EC5 /* Frameworks */, + DA46CF742DCBCA0000F00EC5 /* Resources */, + DAE70B782E12300B001F0890 /* Embed Frameworks */, + DAF7D8AC2E207C5100AB0820 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + DA7C49B02E15D3800049937A /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + DA183FC92E122AF30056667D /* Sapphire */, + DA7C49B62E15D7360049937A /* ObjC */, + ); + name = Sapphire; + packageProductDependencies = ( + DA7C49622E15ACA60049937A /* MediaRemoteAdapter */, + DAF7D8AA2E207BBC00AB0820 /* SwiftProtobufPluginLibrary */, + ); + productName = DynamicNotch; + productReference = DA46CF762DCBCA0000F00EC5 /* Sapphire.app */; + productType = "com.apple.product-type.application"; + }; + DA46CF862DCBCA0100F00EC5 /* SapphireTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA46CF9E2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireTests" */; + buildPhases = ( + DA46CF832DCBCA0100F00EC5 /* Sources */, + DA46CF842DCBCA0100F00EC5 /* Frameworks */, + DA46CF852DCBCA0100F00EC5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DA46CF892DCBCA0100F00EC5 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + DA46CF8A2DCBCA0100F00EC5 /* SapphireNotchTests */, + ); + name = SapphireTests; + packageProductDependencies = ( + ); + productName = DynamicNotchTests; + productReference = DA46CF872DCBCA0100F00EC5 /* SapphireTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + DA46CF902DCBCA0100F00EC5 /* SapphireUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA46CFA12DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireUITests" */; + buildPhases = ( + DA46CF8D2DCBCA0100F00EC5 /* Sources */, + DA46CF8E2DCBCA0100F00EC5 /* Frameworks */, + DA46CF8F2DCBCA0100F00EC5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DA46CF932DCBCA0100F00EC5 /* PBXTargetDependency */, + ); + fileSystemSynchronizedGroups = ( + DA46CF942DCBCA0100F00EC5 /* SapphireNotchUITests */, + ); + name = SapphireUITests; + packageProductDependencies = ( + ); + productName = DynamicNotchUITests; + productReference = DA46CF912DCBCA0100F00EC5 /* SapphireUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + DA7C497F2E15CCA50049937A /* NearbyShare */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA7C49862E15CCA50049937A /* Build configuration list for PBXNativeTarget "NearbyShare" */; + buildPhases = ( + DA7C497C2E15CCA50049937A /* Headers */, + DA7C497D2E15CCA50049937A /* Sources */, + DA7C497E2E15CCA50049937A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NearbyShare; + packageProductDependencies = ( + DA7C49A42E15D34D0049937A /* SwiftECC */, + DA7C49A72E15D3660049937A /* SwiftProtobuf */, + DA7C49A92E15D3660049937A /* SwiftProtobufPluginLibrary */, + DA7C49AB2E15D3660049937A /* protoc-gen-swift */, + ); + productName = NearbyShare; + productReference = DA7C49802E15CCA50049937A /* libNearbyShare.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + DA46CF6E2DCBCA0000F00EC5 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1630; + LastUpgradeCheck = 1640; + TargetAttributes = { + DA46CF752DCBCA0000F00EC5 = { + CreatedOnToolsVersion = 16.3; + }; + DA46CF862DCBCA0100F00EC5 = { + CreatedOnToolsVersion = 16.3; + TestTargetID = DA46CF752DCBCA0000F00EC5; + }; + DA46CF902DCBCA0100F00EC5 = { + CreatedOnToolsVersion = 16.3; + TestTargetID = DA46CF752DCBCA0000F00EC5; + }; + DA7C497F2E15CCA50049937A = { + CreatedOnToolsVersion = 16.4; + }; + }; + }; + buildConfigurationList = DA46CF712DCBCA0000F00EC5 /* Build configuration list for PBXProject "Sapphire" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = DA46CF6D2DCBCA0000F00EC5; + minimizedProjectReferenceProxies = 1; + packageReferences = ( + DAD47CD22E13C3DB001B70C8 /* XCRemoteSwiftPackageReference "SwiftECC" */, + DA7C49612E15ACA60049937A /* XCRemoteSwiftPackageReference "mediaremote-adapter" */, + DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = DA46CF772DCBCA0000F00EC5 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + DA46CF752DCBCA0000F00EC5 /* Sapphire */, + DA46CF862DCBCA0100F00EC5 /* SapphireTests */, + DA46CF902DCBCA0100F00EC5 /* SapphireUITests */, + DA7C497F2E15CCA50049937A /* NearbyShare */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + DA46CF742DCBCA0000F00EC5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA46CF852DCBCA0100F00EC5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA46CF8F2DCBCA0100F00EC5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + DA46CF722DCBCA0000F00EC5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA46CF832DCBCA0100F00EC5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA46CF8D2DCBCA0100F00EC5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA7C497D2E15CCA50049937A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DA52567B2E162FA900D8F42E /* ShareViewController.swift in Sources */, + DA52567D2E162FBE00D8F42E /* DeviceListCell.swift in Sources */, + DA7C49982E15D33A0049937A /* OutboundNearbyConnection.swift in Sources */, + DA7C49992E15D33A0049937A /* wire_format.pb.swift in Sources */, + DA7C499A2E15D33A0049937A /* securemessage.pb.swift in Sources */, + DA7C499B2E15D33A0049937A /* InboundNearbyConnection.swift in Sources */, + DA7C499C2E15D33A0049937A /* NearbyConnectionManager.swift in Sources */, + DABC6CC02E16F57B00A5CF83 /* TransferDirection.swift in Sources */, + DA7C499D2E15D33A0049937A /* Data+Extensions.swift in Sources */, + DA7C499E2E15D33A0049937A /* device_to_device_messages.pb.swift in Sources */, + DA7C499F2E15D33A0049937A /* ukey.pb.swift in Sources */, + DA7C49A12E15D33A0049937A /* NearbyConnection.swift in Sources */, + DA5256792E162B9F00D8F42E /* NearDropDisplayState.swift in Sources */, + DA7C49A22E15D33A0049937A /* offline_wire_formats.pb.swift in Sources */, + DA7C49A32E15D33A0049937A /* securegcm.pb.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + DA46CF892DCBCA0100F00EC5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; + targetProxy = DA46CF882DCBCA0100F00EC5 /* PBXContainerItemProxy */; + }; + DA46CF932DCBCA0100F00EC5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; + targetProxy = DA46CF922DCBCA0100F00EC5 /* PBXContainerItemProxy */; + }; + DA7C49B02E15D3800049937A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DA7C497F2E15CCA50049937A /* NearbyShare */; + targetProxy = DA7C49AF2E15D3800049937A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + DA46CF992DCBCA0100F00EC5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 14.6; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + DA46CF9A2DCBCA0100F00EC5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 14.6; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + DA46CF9C2DCBCA0100F00EC5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = Sapphire/Sapphire.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = KVQFWJ7C7S; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = YES; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Sapphire/App/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Sapphire; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; + INFOPLIST_KEY_LSUIElement = YES; + INFOPLIST_KEY_NSAppleEventsUsageDescription = "Needed for HUD and music implmentation"; + INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Used to show new connections and battery low notifications"; + INFOPLIST_KEY_NSFocusStatusUsageDescription = "Needed to provide live focus updates"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Needed for nearby share functionality"; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "Needed to provide live weather updates"; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Needed to provide live weather updates"; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Used for Gemini Live"; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.shariq.sapphire; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "ObjC/Bridging-Header.h"; + SWIFT_VERSION = 5.0; + SYSTEM_FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + }; + name = Debug; + }; + DA46CF9D2DCBCA0100F00EC5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = Sapphire/Sapphire.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + DEVELOPMENT_TEAM = KVQFWJ7C7S; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_INCOMING_NETWORK_CONNECTIONS = YES; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + FRAMEWORK_SEARCH_PATHS = ""; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = Sapphire/App/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Sapphire; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; + INFOPLIST_KEY_LSUIElement = YES; + INFOPLIST_KEY_NSAppleEventsUsageDescription = "Needed for HUD and music implmentation"; + INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Used to show new connections and battery low notifications"; + INFOPLIST_KEY_NSFocusStatusUsageDescription = "Needed to provide live focus updates"; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Needed for nearby share functionality"; + INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "Needed to provide live weather updates"; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Needed to provide live weather updates"; + INFOPLIST_KEY_NSMainStoryboardFile = Main; + INFOPLIST_KEY_NSMicrophoneUsageDescription = "Used for Gemini Live"; + INFOPLIST_KEY_NSPrincipalClass = NSApplication; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MARKETING_VERSION = 1.0; + OTHER_LDFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.shariq.sapphire; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OBJC_BRIDGING_HEADER = "ObjC/Bridging-Header.h"; + SWIFT_VERSION = 5.0; + SYSTEM_FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + }; + name = Release; + }; + DA46CF9F2DCBCA0100F00EC5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 15.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sapphire.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Sapphire"; + }; + name = Debug; + }; + DA46CFA02DCBCA0100F00EC5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + GENERATE_INFOPLIST_FILE = YES; + MACOSX_DEPLOYMENT_TARGET = 15.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sapphire.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Sapphire"; + }; + name = Release; + }; + DA46CFA22DCBCA0100F00EC5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = DynamicNotch; + }; + name = Debug; + }; + DA46CFA32DCBCA0100F00EC5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = YES; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TEST_TARGET_NAME = DynamicNotch; + }; + name = Release; + }; + DA7C49872E15CCA50049937A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KVQFWJ7C7S; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = ""; + EXECUTABLE_PREFIX = lib; + LD_DYLIB_INSTALL_NAME = "@rpath/libNearbyShare.dylib"; + MACOSX_DEPLOYMENT_TARGET = 14.6; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + DA7C49882E15CCA50049937A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = KVQFWJ7C7S; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = ""; + EXECUTABLE_PREFIX = lib; + LD_DYLIB_INSTALL_NAME = "@rpath/libNearbyShare.dylib"; + MACOSX_DEPLOYMENT_TARGET = 14.6; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + DA46CF712DCBCA0000F00EC5 /* Build configuration list for PBXProject "Sapphire" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA46CF992DCBCA0100F00EC5 /* Debug */, + DA46CF9A2DCBCA0100F00EC5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DA46CF9B2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "Sapphire" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA46CF9C2DCBCA0100F00EC5 /* Debug */, + DA46CF9D2DCBCA0100F00EC5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DA46CF9E2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA46CF9F2DCBCA0100F00EC5 /* Debug */, + DA46CFA02DCBCA0100F00EC5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DA46CFA12DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA46CFA22DCBCA0100F00EC5 /* Debug */, + DA46CFA32DCBCA0100F00EC5 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DA7C49862E15CCA50049937A /* Build configuration list for PBXNativeTarget "NearbyShare" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA7C49872E15CCA50049937A /* Debug */, + DA7C49882E15CCA50049937A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + DA7C49612E15ACA60049937A /* XCRemoteSwiftPackageReference "mediaremote-adapter" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/ejbills/mediaremote-adapter.git"; + requirement = { + branch = master; + kind = branch; + }; + }; + DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/apple/swift-protobuf.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.30.0; + }; + }; + DAD47CD22E13C3DB001B70C8 /* XCRemoteSwiftPackageReference "SwiftECC" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/leif-ibsen/SwiftECC.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.5.0; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + DA7C49622E15ACA60049937A /* MediaRemoteAdapter */ = { + isa = XCSwiftPackageProductDependency; + package = DA7C49612E15ACA60049937A /* XCRemoteSwiftPackageReference "mediaremote-adapter" */; + productName = MediaRemoteAdapter; + }; + DA7C49A42E15D34D0049937A /* SwiftECC */ = { + isa = XCSwiftPackageProductDependency; + package = DAD47CD22E13C3DB001B70C8 /* XCRemoteSwiftPackageReference "SwiftECC" */; + productName = SwiftECC; + }; + DA7C49A72E15D3660049937A /* SwiftProtobuf */ = { + isa = XCSwiftPackageProductDependency; + package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; + productName = SwiftProtobuf; + }; + DA7C49A92E15D3660049937A /* SwiftProtobufPluginLibrary */ = { + isa = XCSwiftPackageProductDependency; + package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; + productName = SwiftProtobufPluginLibrary; + }; + DA7C49AB2E15D3660049937A /* protoc-gen-swift */ = { + isa = XCSwiftPackageProductDependency; + package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; + productName = "protoc-gen-swift"; + }; + DAF7D8AA2E207BBC00AB0820 /* SwiftProtobufPluginLibrary */ = { + isa = XCSwiftPackageProductDependency; + package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; + productName = SwiftProtobufPluginLibrary; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = DA46CF6E2DCBCA0000F00EC5 /* Project object */; +} diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..e09f56e8 --- /dev/null +++ b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,60 @@ +{ + "originHash" : "bbf74e37c041f8e77021c1d7c946dd6a4df5cfc4c317708e65974eb0e4b73cda", + "pins" : [ + { + "identity" : "asn1", + "kind" : "remoteSourceControl", + "location" : "https://github.com/leif-ibsen/ASN1", + "state" : { + "revision" : "e38d1b8b43d8b53ffadde9836f34289176bb7a0c", + "version" : "2.7.0" + } + }, + { + "identity" : "bigint", + "kind" : "remoteSourceControl", + "location" : "https://github.com/leif-ibsen/BigInt", + "state" : { + "revision" : "afb70a0038bfbba845271b60fa9a58d5840f8017", + "version" : "1.21.0" + } + }, + { + "identity" : "digest", + "kind" : "remoteSourceControl", + "location" : "https://github.com/leif-ibsen/Digest", + "state" : { + "revision" : "95ba89b494aaff5f3cd2933c03b9a890323dbf2c", + "version" : "1.13.0" + } + }, + { + "identity" : "mediaremote-adapter", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ejbills/mediaremote-adapter.git", + "state" : { + "branch" : "master", + "revision" : "3529aa25023082a2ceadebcd2c9c4a9430ee96b9" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "102a647b573f60f73afdce5613a51d71349fe507", + "version" : "1.30.0" + } + }, + { + "identity" : "swiftecc", + "kind" : "remoteSourceControl", + "location" : "https://github.com/leif-ibsen/SwiftECC.git", + "state" : { + "revision" : "85c529c9c56b649a8d8edcef60aab3925ab0f69f", + "version" : "5.5.0" + } + } + ], + "version" : 3 +} diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist new file mode 100644 index 00000000..5dd5da85 --- /dev/null +++ b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist @@ -0,0 +1,5 @@ + + + + + diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/UserInterfaceState.xcuserstate b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..d6f66518101597fcc0834002559f61a60fab28ef GIT binary patch literal 684944 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 z

KTL)GOfPq<>AK1Y>Iv<|0ED?cG9n_hH1>(_ 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%0AQ;eg3qA>XJSnUF-}POWx#8~MS0N6&VX_N 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 Eg3hy0`v3p{ literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x.png new file mode 100644 index 0000000000000000000000000000000000000000..37b36f1579225e5619147545a7d808bb4dd71cf4 GIT binary patch literal 32336 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

KTL)GOfPq<>AK1Y>Iv<|0ED?cG9n_hH1>(_ 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%0AQ;eg3qA>XJSnUF-}POWx#8~MS0N6&VX_N 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 Eg3hy0`v3p{ literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 2.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 2.png new file mode 100644 index 0000000000000000000000000000000000000000..9927569cdabb60b41169ea0f2dd7b028e20d9072 GIT binary patch literal 8675 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 ty5V>{zP7)=|MtCm_gT~*Ny1V|a`n$SD z+?}Rr4)^!>zZnb$AE@eWULnlvWHOmNJ~=u0GNm+<7~|pL;o*}I!rfPCcoU_R-$$d- z{cvz_@cqut&ik*^IDo3|g%A$p=;-KARo#Ex1OUwJRNs_w09CymUo=3LkC%k6y|&^4 z0g-A`1Vm(w#8tU?uj4rG)JA<@NC`5%2>bG7q6y{LODaFYKxzvWOlUNa;?mVc_M4@Yhu2GsG#85pVmy!_rk#+|& z$i+#;nI>ae<3VS&_*SOo+e&^8fPaLXO^95a)Js_<{@#+ zSA64wzaXg8-L_HLZIqi`V7Jq`C#oi{LcomW&Y!CR)f>4OxyamJ^}1tgEbU$X2ppj;E=L&9-JUvwbWZ?O#>oTY*B>c(=osPHsj#tkgjWJ zyN0%HXnHNS5pyG#Ov;H=GPxvD&dhRRmJ`Q+oN=RR+1(w?Pm~}%y{sQYsu2HrHsQUu zj`;4=PY8`7EzklTy}s0bSHCao7dJlp{0E-={0p(|E`(4w-6sxDkDu|?haVC2!q3-6 z2+Fr#f6UXpR(;RE+atJkNz$F>*0%?tu$;fm3sIHfKr|UomGI zj3~OirmuoUzRzx?V$95#79+dQ32aG3?qE~`xYY|qolvaS2iL3zY<}?+cd{ATd`{q! zdSDR(fDG7tf+EXeg{ t#}Ccy002ovPDHLkV1hm?2J-*_ literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 5.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 5.png new file mode 100644 index 0000000000000000000000000000000000000000..2401c28c584d89d3f08bc53759462cd6fbbda551 GIT binary patch literal 1075 zcmV-31kC%1P)T~*Ny1V|a`n$SD z+?}Rr4)^!>zZnb$AE@eWULnlvWHOmNJ~=u0GNm+<7~|pL;o*}I!rfPCcoU_R-$$d- z{cvz_@cqut&ik*^IDo3|g%A$p=;-KARo#Ex1OUwJRNs_w09CymUo=3LkC%k6y|&^4 z0g-A`1Vm(w#8tU?uj4rG)JA<@NC`5%2>bG7q6y{LODaFYKxzvWOlUNa;?mVc_M4@Yhu2GsG#85pVmy!_rk#+|& z$i+#;nI>ae<3VS&_*SOo+e&^8fPaLXO^95a)Js_<{@#+ zSA64wzaXg8-L_HLZIqi`V7Jq`C#oi{LcomW&Y!CR)f>4OxyamJ^}1tgEbU$X2ppj;E=L&9-JUvwbWZ?O#>oTY*B>c(=osPHsj#tkgjWJ zyN0%HXnHNS5pyG#Ov;H=GPxvD&dhRRmJ`Q+oN=RR+1(w?Pm~}%y{sQYsu2HrHsQUu zj`;4=PY8`7EzklTy}s0bSHCao7dJlp{0E-={0p(|E`(4w-6sxDkDu|?haVC2!q3-6 z2+Fr#f6UXpR(;RE+atJkNz$F>*0%?tu$;fm3sIHfKr|UomGI zj3~OirmuoUzRzx?V$95#79+dQ32aG3?qE~`xYY|qolvaS2iL3zY<}?+cd{ATd`{q! zdSDR(fDG7tf+EXeg{ t#}Ccy002ovPDHLkV1hm?2J-*_ literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 6.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 6.png new file mode 100644 index 0000000000000000000000000000000000000000..1cf328f4cc397518b295147db4300b8ca7dd08c1 GIT binary patch literal 473 zcmV;~0Ve*5P)DlD%$IK@f$%+1>j`>bCFu8(FW{ zKh8Bjg}DDU1B4K+1AqX|fp>y)AR@>KLouTi$i>KIhA^A!%5l*++S(DkAkPS9pxGE> zVLugOD&#T)yb~@O$Lg}; zmR(Em0Scr+NrN756~Jqt@-6pqq&$r=oAHn`y-n<*5}rpeOU)QG^Prh*_BSBrLN1AY zQbhRYBiS5fF(c3C2zZ1%7SEAW)$Q4?S*p7AF~+Z5*S&SlU7l<1`~Kz+^LfjRsTYkY P00000NkvXXu0mjf51`g1 literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..82fd87ac --- /dev/null +++ b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "filename" : "Artboard 6.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "filename" : "Artboard 5.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "filename" : "Artboard 4.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "filename" : "Artboard 3.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "filename" : "Artboard 2.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "filename" : "Artboard 1@0.5x 1.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "filename" : "Artboard 1@0.5x.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "filename" : "Artboard 1.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "filename" : "Frame 33.png", + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "filename" : "Frame 32.png", + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 32.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 32.png new file mode 100644 index 0000000000000000000000000000000000000000..8b9d3e0360dc3a72064bd0c8f90925bf988d0e61 GIT binary patch literal 181896 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
~|C-#l(OR6W(~Mr+R;_U#>h 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
9++=)CcVw?!*;*lT%?iNMZ<7K$2_9 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Ú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 literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 33.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 33.png new file mode 100644 index 0000000000000000000000000000000000000000..8b9d3e0360dc3a72064bd0c8f90925bf988d0e61 GIT binary patch literal 181896 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
~|C-#l(OR6W(~Mr+R;_U#>h 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
9++=)CcVw?!*;*lT%?iNMZ<7K$2_9 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Ú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
6OJiXCW0YIOJR7xlPUZ2JD^Q#QPe!^hx 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 literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json b/submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json new file mode 100644 index 00000000..2aa0709e --- /dev/null +++ b/submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "compression-type" : "lossless" + } +} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json b/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json new file mode 100644 index 00000000..dd24b520 --- /dev/null +++ b/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "Google-Gemini-Logo.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Google-Gemini-Logo.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Google-Gemini-Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..2eb2d323e1d76767d19a566d0a84b19a595bb0ef GIT binary patch literal 16697 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + Default + + + + + + + Left to Right + + + + + + + Right to Left + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/submissions/sapphire/Sapphire/App/Info.plist b/submissions/sapphire/Sapphire/App/Info.plist new file mode 100644 index 00000000..213b84d2 --- /dev/null +++ b/submissions/sapphire/Sapphire/App/Info.plist @@ -0,0 +1,25 @@ + + + + + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLName + com.shariq.sapphire + CFBundleURLSchemes + + sapphire + + + + NSCalendarsFullAccessUsageDescription + Needed to show events in calendar + NSHighResolutionCapable + + NSScreenCaptureUsageDescription + Needed for gemini live activity + + diff --git a/submissions/sapphire/Sapphire/App/OnboardingView.swift b/submissions/sapphire/Sapphire/App/OnboardingView.swift new file mode 100644 index 00000000..db9c5097 --- /dev/null +++ b/submissions/sapphire/Sapphire/App/OnboardingView.swift @@ -0,0 +1,233 @@ +// +// OnboardingView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-09. +// + +import SwiftUI + +struct OnboardingView: View { + enum OnboardingStep { + case welcome, permissions + } + + @State private var currentStep: OnboardingStep = .welcome + var onComplete: () -> Void + + var body: some View { + ZStack { + LinearGradient( + gradient: Gradient(colors: [Color.indigo.opacity(0.3), Color.black]), + startPoint: .top, + endPoint: .bottom + ) + .ignoresSafeArea() + + CustomWindowControls() + .padding(.horizontal, 16) + .padding(.top, 16) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) + .zIndex(2) + + switch currentStep { + case .welcome: + WelcomeStepView(onGetStarted: { + withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { + currentStep = .permissions + } + }) + .transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .leading).combined(with: .opacity))) + case .permissions: + PermissionsStepView(onComplete: onComplete) + .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .trailing).combined(with: .opacity))) + } + } + .background(.ultraThinMaterial) + .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous)) + } +} + + + +private struct WelcomeStepView: View { + var onGetStarted: () -> Void + + @State private var isHoveringGetStarted = false + + private var buttonGradient: LinearGradient { + LinearGradient( + gradient: Gradient(colors: [ + Color(red: 249/255, green: 165/255, blue: 154/255), + Color(red: 255/255, green: 197/255, blue: 158/255), + Color(red: 255/255, green: 247/255, blue: 174/255) + ]), + startPoint: .leading, + endPoint: .trailing + ) + } + + var body: some View { + VStack(spacing: 20) { + Spacer() + + Image(nsImage: NSApp.applicationIconImage) + .resizable() + .frame(width: 80, height: 80) + .clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous)) + + Text("Welcome to Sapphire") + .font(.largeTitle.weight(.bold)) + .multilineTextAlignment(.center) + + Text("A new way to experience your Mac's notch.\nLet's get started by setting up a few permissions.") + .font(.title3) + .multilineTextAlignment(.center) + .foregroundColor(.secondary) + .padding(.horizontal) + + Spacer() + + Button(action: onGetStarted) { + HStack { + Text("Get Started") + if isHoveringGetStarted { + Image(systemName: "arrow.right") + .transition(.opacity.animation(.easeInOut(duration: 0.2))) + } + } + .font(.headline) + .fontWeight(.semibold) + .foregroundColor(.black.opacity(0.8)) + .padding(.horizontal, 40) + .padding(.vertical, 12) + .background(buttonGradient) + .clipShape(Capsule()) + } + .buttonStyle(.plain) + .shadow(color: .black.opacity(0.3), radius: 10, y: 5) + .padding(.bottom, 50) + .onHover { hovering in + withAnimation(.easeInOut(duration: 0.2)) { + isHoveringGetStarted = hovering + } + } + } + } +} + + + +private struct PermissionsStepView: View { + @StateObject private var permissionsManager = PermissionsManager() + var onComplete: () -> Void + + + private var doneButtonGradient: LinearGradient { + LinearGradient( + gradient: Gradient(colors: [ + Color(red: 154/255, green: 249/255, blue: 165/255), + Color(red: 174/255, green: 255/255, blue: 247/255) + ]), + startPoint: .leading, + endPoint: .trailing + ) + } + + var body: some View { + VStack(spacing: 0) { + Text("Required Permissions") + .font(.largeTitle.weight(.bold)) + .padding(.top, 40).padding(.bottom, 10) + + Text("Sapphire needs a few permissions to provide live information and control your system. Your data is never collected or sent anywhere.") + .font(.body).multilineTextAlignment(.center).foregroundColor(.secondary) + .padding(.horizontal, 50).padding(.bottom, 30) + + ScrollView { + VStack(spacing: 15) { + ForEach(permissionsManager.allPermissions) { permission in + PermissionRowView(permission: permission, manager: permissionsManager) + } + }.padding(.horizontal, 50) + } + + Spacer() + + Button(action: onComplete) { + Text("Done") + .font(.headline).fontWeight(.semibold) + .foregroundColor(.black.opacity(0.8)) + .padding(.horizontal, 60).padding(.vertical, 12) + .background(doneButtonGradient) + .clipShape(Capsule()) + } + .buttonStyle(.plain) + .disabled(!permissionsManager.areAllPermissionsGranted) + .padding(.bottom, 50) + .animation(.easeInOut, value: permissionsManager.areAllPermissionsGranted) + } + .onAppear { + permissionsManager.checkAllPermissions() + } + } +} + + + +private struct PermissionRowView: View { + let permission: PermissionItem + @ObservedObject var manager: PermissionsManager + + var body: some View { + HStack(spacing: 15) { + Image(systemName: permission.iconName).font(.title2).frame(width: 40, height: 40) + .background(permission.iconColor.opacity(0.2)).clipShape(Circle()).foregroundColor(permission.iconColor) + VStack(alignment: .leading, spacing: 2) { + Text(permission.title).font(.headline) + Text(permission.description).font(.subheadline).foregroundColor(.secondary) + } + Spacer() + let status = manager.status(for: permission.type) + switch status { + case .granted: Image(systemName: "checkmark.circle.fill").font(.title2).foregroundColor(.green) + case .denied: Image(systemName: "xmark.circle.fill").font(.title2).foregroundColor(.red) + case .notRequested: Button("Request") { manager.requestPermission(permission.type) }.buttonStyle(.bordered).tint(.accentColor) + } + } + .padding().background(.black.opacity(0.15)) + .clipShape(RoundedRectangle(cornerRadius: 20)) + .overlay(RoundedRectangle(cornerRadius: 20).stroke(Color.white.opacity(0.1), lineWidth: 1)) + } +} + + + +private struct CustomWindowControls: View { + @Environment(\.window) private var window: NSWindow? + @State private var isHovering = false + + var body: some View { + HStack(spacing: 8) { + Button(action: { window?.close() }) { + Image(systemName: "xmark").font(.system(size: 9, weight: .bold, design: .rounded)) + } + .buttonStyle(TrafficLightButtonStyle(color: .red, isHovering: isHovering)) + + Button(action: { window?.miniaturize(nil) }) { + Image(systemName: "minus").font(.system(size: 9, weight: .bold, design: .rounded)) + } + .buttonStyle(TrafficLightButtonStyle(color: .yellow, isHovering: isHovering)) + + Button(action: { window?.zoom(nil) }) { + Image(systemName: "plus").font(.system(size: 9, weight: .bold, design: .rounded)) + } + .buttonStyle(TrafficLightButtonStyle(color: .green, isHovering: isHovering)) + } + .onHover { hovering in + withAnimation(.easeInOut(duration: 0.1)) { + isHovering = hovering + } + } + } +} diff --git a/submissions/sapphire/Sapphire/App/PermissionsManager.swift b/submissions/sapphire/Sapphire/App/PermissionsManager.swift new file mode 100644 index 00000000..8ddec97b --- /dev/null +++ b/submissions/sapphire/Sapphire/App/PermissionsManager.swift @@ -0,0 +1,185 @@ +// +// PermissionsManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI +import Combine +import CoreLocation +import EventKit +import AVFoundation +import UserNotifications +import ScreenCaptureKit +import CoreBluetooth +import Intents + +enum PermissionType: Identifiable { + case accessibility, notifications, location, calendar, bluetooth, focusStatus + var id: Self { self } +} + +enum PermissionStatus { case granted, denied, notRequested } + +struct PermissionItem: Identifiable { + let id = UUID() + let type: PermissionType, title: String, description: String, iconName: String + let iconColor: Color +} + +@MainActor +class PermissionsManager: NSObject, ObservableObject, CLLocationManagerDelegate, CBCentralManagerDelegate { + + @Published var accessibilityStatus: PermissionStatus = .notRequested + @Published var notificationsStatus: PermissionStatus = .notRequested + @Published var locationStatus: PermissionStatus = .notRequested + @Published var calendarStatus: PermissionStatus = .notRequested + @Published var bluetoothStatus: PermissionStatus = .notRequested + @Published var focusStatusStatus: PermissionStatus = .notRequested + + private var locationManager: CLLocationManager? + private var bluetoothManager: CBCentralManager? + + let allPermissions: [PermissionItem] = [ + .init(type: .accessibility, title: "Accessibility", description: "Needed to detect media key presses for music and volume control.", iconName: "figure.wave.circle.fill", iconColor: .purple), + .init(type: .notifications, title: "Notifications", description: "Needed to show custom alerts for messages and system events.", iconName: "bell.badge.fill", iconColor: .red), + .init(type: .location, title: "Location", description: "Needed to provide live weather updates for your current location.", iconName: "location.fill", iconColor: .blue), + .init(type: .calendar, title: "Calendar", description: "Needed to show your upcoming events.", iconName: "calendar", iconColor: .red), + .init(type: .bluetooth, title: "Bluetooth", description: "Needed to detect connected devices and their battery levels.", iconName: "ipad.landscape.and.iphone", iconColor: .blue), + .init(type: .focusStatus, title: "Focus Status", description: "Needed to show when a Focus mode is active.", iconName: "moon.fill", iconColor: .indigo) + ] + + var areAllPermissionsGranted: Bool { + accessibilityStatus == .granted && + notificationsStatus == .granted && + locationStatus == .granted && + calendarStatus == .granted && + bluetoothStatus == .granted && + focusStatusStatus == .granted + } + + override init() { + super.init() + self.locationManager = CLLocationManager() + self.locationManager?.delegate = self + self.bluetoothManager = CBCentralManager(delegate: self, queue: nil) + } + + func checkAllPermissions() { + + switch CBManager.authorization { + case .allowedAlways: + bluetoothStatus = .granted + case .denied, .restricted: + bluetoothStatus = .denied + case .notDetermined: + bluetoothStatus = .notRequested + @unknown default: + bluetoothStatus = .notRequested + } + } + + func status(for type: PermissionType) -> PermissionStatus { + switch type { + case .accessibility: return accessibilityStatus + case .notifications: return notificationsStatus + case .location: return locationStatus + case .calendar: return calendarStatus + case .bluetooth: return bluetoothStatus + case .focusStatus: return focusStatusStatus + } + } + + func requestPermission(_ type: PermissionType) { + switch type { + case .accessibility: + self.accessibilityStatus = .granted + + case .notifications: + UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in + DispatchQueue.main.async { self.notificationsStatus = granted ? .granted : .denied } + } + + case .location: + locationManager?.requestWhenInUseAuthorization() + + case .calendar: + EKEventStore().requestFullAccessToEvents { granted, _ in + DispatchQueue.main.async { self.calendarStatus = granted ? .granted : .denied } + } + + case .bluetooth: + + + if bluetoothManager?.state == .poweredOn { + + bluetoothManager?.scanForPeripherals(withServices: nil, options: nil) + } else { + + DispatchQueue.main.async { + self.bluetoothStatus = .denied + } + } + + case .focusStatus: + INFocusStatusCenter.default.requestAuthorization { status in + DispatchQueue.main.async { + switch status { + case .authorized: self.focusStatusStatus = .granted + case .denied: self.focusStatusStatus = .denied + case .notDetermined: self.focusStatusStatus = .notRequested + @unknown default: self.focusStatusStatus = .notRequested + } + } + } + } + } + + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { + updateLocationStatus(for: manager.authorizationStatus) + } + + private func updateLocationStatus(for status: CLAuthorizationStatus) { + switch status { + case .authorized, .authorizedAlways, .authorizedWhenInUse: + locationStatus = .granted + case .denied, .restricted: + locationStatus = .denied + case .notDetermined: + locationStatus = .notRequested + @unknown default: + locationStatus = .notRequested + } + } + + + func centralManagerDidUpdateState(_ central: CBCentralManager) { + switch central.state { + case .poweredOn: + + DispatchQueue.main.async { + self.bluetoothStatus = .granted + } + case .poweredOff: + + DispatchQueue.main.async { + self.bluetoothStatus = .denied + } + case .unauthorized: + + DispatchQueue.main.async { + self.bluetoothStatus = .denied + } + case .unknown, .resetting: + + DispatchQueue.main.async { + self.bluetoothStatus = .notRequested + } + @unknown default: + DispatchQueue.main.async { + self.bluetoothStatus = .notRequested + } + } + } +} diff --git a/submissions/sapphire/Sapphire/App/ViewController.swift b/submissions/sapphire/Sapphire/App/ViewController.swift new file mode 100644 index 00000000..25ef7691 --- /dev/null +++ b/submissions/sapphire/Sapphire/App/ViewController.swift @@ -0,0 +1,25 @@ +// +// ViewController.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-05-07. +// + +import Cocoa + +class ViewController: NSViewController { + + override func viewDidLoad() { + + + + } + + override var representedObject: Any? { + didSet { + + } + } + + +} diff --git a/submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift b/submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift new file mode 100644 index 00000000..8505f1c4 --- /dev/null +++ b/submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift @@ -0,0 +1,471 @@ +// +// LiveActivityComponents.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-06. +// + +import SwiftUI +import EventKit + +// MARK: - Music Components + +struct AlbumArtView: View { + let image: NSImage? + + var body: some View { + Group { + if let artwork = image { + Image(nsImage: artwork) + .resizable() + } else { + Image(systemName: "music.note") + .foregroundColor(.white.opacity(0.8)) + } + } + .aspectRatio(contentMode: .fill) + .frame(width: 20, height: 20) + .clipShape(RoundedRectangle(cornerRadius: 7, style: .continuous)) + .id(image) + } +} + +struct MusicLyricsView: View { + @EnvironmentObject var musicWidget: MusicWidget + @Binding var showLyrics: Bool + + init(_ showLyrics: Binding) { + self._showLyrics = showLyrics + } + + var body: some View { + let lyricText = (musicWidget.currentLyric?.translatedText ?? musicWidget.currentLyric?.text) + + if let text = lyricText, !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + Text(text) + .font(.system(size: 10, weight: .semibold, design: .rounded)) + .foregroundColor(musicWidget.accentColor.opacity(0.9)) + .lineLimit(1) + .truncationMode(.tail) + .frame(maxWidth: 200) + .transition(.opacity.animation(.easeInOut(duration: 0.3))) + .id("lyric-\(musicWidget.currentLyric?.id.uuidString ?? "")") + .onTapGesture { + showLyrics = true + } + } else { + EmptyView() + } + } +} + +struct NowPlayingTextView: View { + let title: String + + var body: some View { + Text(title) + .font(.system(size: 10, weight: .semibold, design: .rounded)) + .lineLimit(1) + .truncationMode(.tail) + .frame(maxWidth: 200) + .transition(.opacity.animation(.easeInOut(duration: 0.3))) + .opacity(0.5) + } +} + +// MARK: - Activity View Components + +struct AudioSwitchActivityView { + static func left(for event: AudioSwitchEvent) -> some View { + Image(systemName: "arrow.uturn.backward.circle.fill") + .font(.system(size: 18, weight: .semibold)) + .foregroundColor(.white) + .symbolRenderingMode(.hierarchical) + } + + static func right(for event: AudioSwitchEvent) -> some View { + let targetDeviceIcon = event.direction == .switchedToMac ? "desktopcomputer" : "iphone" + let targetDeviceName = event.direction == .switchedToMac ? "Mac" : "iPhone" + + return HStack(spacing: 8) { + VStack(alignment: .leading, spacing: 1) { + Text(event.deviceName) + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.white.opacity(0.9)) + .lineLimit(1) + Text("Connected to \(targetDeviceName)") + .font(.system(size: 11)) + .foregroundColor(.white.opacity(0.7)) + } + Image(systemName: targetDeviceIcon) + .font(.system(size: 16, weight: .semibold)) + .foregroundColor(.white) + } + } +} + +struct BatteryActivityView { + static func left(for state: BatteryState) -> some View { + let iconName = state.isLow ? "battery.25" : (state.isCharging ? "bolt.fill" : "powerplug.fill") + let iconColor = state.isLow ? Color.red : (state.isCharging ? .green : .white.opacity(0.9)) + + return Image(systemName: iconName) + .frame(width: 20, height: 20) + .foregroundColor(iconColor) + } + + static func right(for state: BatteryState) -> some View { + Text("\(state.level)%") + .font(.system(size: 13, weight: .semibold)) + } +} + +struct BatteryRingView: View { + let level: Int + + private var color: Color { + if level <= 20 { return .red } + if level <= 45 { return .yellow } + return .green + } + + var body: some View { + ZStack { + Circle().stroke(Color.white.opacity(0.2), lineWidth: 2.5) + Circle() + .trim(from: 0, to: CGFloat(level) / 100.0) + .stroke(color, style: StrokeStyle(lineWidth: 2.5, lineCap: .round)) + .rotationEffect(.degrees(-90)) + .animation(.easeOut, value: level) + } + .frame(width: 18, height: 18) + } +} + +struct BluetoothActivityView { + static func left(for device: BluetoothDeviceState) -> some View { + Image(systemName: device.iconName) + .font(.system(size: 18, weight: .semibold)) + .foregroundColor(.white) + .symbolRenderingMode(.hierarchical) + } + + static func right(for device: BluetoothDeviceState) -> some View { + HStack(spacing: 8) { + Text(device.name) + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.white.opacity(0.9)) + if let level = device.batteryLevel { + BatteryRingView(level: level) + } + } + } +} + +struct BluetoothBatteryActivityView { + static func left(for device: BluetoothDeviceState) -> some View { + Image(systemName: device.iconName) + .font(.system(size: 18, weight: .semibold)) + .foregroundColor(.white) + .symbolRenderingMode(.hierarchical) + } + + static func right(for device: BluetoothDeviceState) -> some View { + HStack(spacing: 8) { + if let level = device.batteryLevel { + BatteryRingView(level: level) + Text("\(level)%") + .font(.system(size: 13, weight: .semibold, design: .rounded)) + .foregroundColor(.white.opacity(0.9)) + } else { + Text("Low Battery") + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.red) + } + } + } +} + +struct BluetoothDisconnectedActivityView { + static func left(for device: BluetoothDeviceState) -> some View { + Image(systemName: "wifi.slash") + .font(.system(size: 18, weight: .semibold)) + .foregroundColor(.white.opacity(0.8)) + .symbolRenderingMode(.hierarchical) + } + + static func right(for device: BluetoothDeviceState) -> some View { + VStack(alignment: .leading, spacing: 1) { + Text(device.name) + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.white.opacity(0.9)) + .lineLimit(1) + Text("Disconnected") + .font(.system(size: 11)) + .foregroundColor(.white.opacity(0.6)) + } + } +} + +struct CalendarActivityView { + static func left(for event: EKEvent) -> some View { + Image(systemName: "calendar") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 18, height: 18) + .foregroundColor(.white.opacity(0.85)) + .padding(.vertical, 2) + } + + static func right(for event: EKEvent) -> some View { + VStack(alignment: .leading, spacing: 2) { + Text(event.title) + .lineLimit(1) + .font(.system(size: 13, weight: .semibold)) + Text(event.startDate, style: .relative) + .lineLimit(1) + .font(.system(size: 11, weight: .medium)) + .foregroundColor(.white.opacity(0.6)) + } + } +} + +struct DesktopActivityView { + static func left(for number: Int) -> some View { + Image(systemName: "rectangle.on.rectangle") + .font(.system(size: 14, weight: .semibold)) + .foregroundColor(.white.opacity(0.9)) + } + + static func right(for number: Int) -> some View { + Text("\(number)") + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.white.opacity(0.9)) + } +} + +struct EyeBreakActivityView { + static var left: some View { + Image(systemName: "eye.fill") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 18, height: 18) + .foregroundColor(.cyan) + } + + static var right: some View { + Text("Eye Break: Look 20ft away") + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.white.opacity(0.9)) + } + + static func bottom() -> some View { + EyeBreakButtonsView() + } +} + +fileprivate struct EyeBreakButtonsView: View { + @EnvironmentObject var eyeBreakManager: EyeBreakManager + + var body: some View { + HStack(spacing: 15) { + Button(action: { self.eyeBreakManager.dismissBreak() }) { + Text("Dismiss") + .fontWeight(.semibold) + .frame(minWidth: 80) + .padding(.vertical, 8) + .background(Color.white.opacity(0.15)) + .clipShape(Capsule()) + } + .buttonStyle(.plain) + + Button(action: { self.eyeBreakManager.completeBreak() }) { + Text(eyeBreakManager.isDoneButtonEnabled ? "Done" : "Done (\(Int(eyeBreakManager.timeRemainingInBreak))s)") + .fontWeight(.semibold) + .frame(minWidth: 80) + .padding(.vertical, 8) + .background(eyeBreakManager.isDoneButtonEnabled ? Color.blue : Color.white.opacity(0.15)) + .clipShape(Capsule()) + } + .buttonStyle(.plain) + .disabled(!eyeBreakManager.isDoneButtonEnabled) + .animation(.easeInOut, value: eyeBreakManager.isDoneButtonEnabled) + } + .foregroundColor(.white) + } +} + +struct FocusModeActivityView { + private static func color(for id: String) -> Color { + switch id { + case "moon.fill": return .purple + case "person.fill": return .blue + case "briefcase.fill": return .cyan + case "bed.double.fill": return .indigo + case "car.fill": return .gray + case "gamecontroller.fill": return .red + default: return .purple + } + } + + static func left(for mode: FocusModeInfo) -> some View { + Image(systemName: mode.identifier) + .font(.system(size: 14, weight: .semibold)) + .foregroundColor(color(for: mode.identifier)) + } + + static func right(for mode: FocusModeInfo) -> some View { + Text("Focus: \(mode.name)") + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.white.opacity(0.9)) + } +} + +struct TimerActivityView: View { + @EnvironmentObject var timerManager: TimerManager + + var body: some View { + TimelineView(.periodic(from: .now, by: 0.1)) { context in + HStack(spacing: 8) { + Image(systemName: "timer").foregroundColor(.orange) + Text(formatTime(timerManager.elapsedTime)) + } + .foregroundColor(.white.opacity(0.9)) + .font(.system(size: 13, weight: .semibold, design: .monospaced)) + } + } + + private func formatTime(_ time: TimeInterval) -> String { + let totalSeconds = Int(time) + let minutes = totalSeconds / 60 + let seconds = totalSeconds % 60 + let milliseconds = Int((time.truncatingRemainder(dividingBy: 1)) * 10) + return String(format: "%02d:%02d.%d", minutes, seconds, milliseconds) + } +} + +struct WeatherActivityView { + static func left(for data: ProcessedWeatherData) -> some View { + Image(systemName: WeatherIconMapper.map(from: data.iconCode)) + .font(.title3) + .symbolRenderingMode(.multicolor) + } + + static func right(for data: ProcessedWeatherData) -> some View { + RightView(data: data) + } + + private struct RightView: View { + @EnvironmentObject var settings: SettingsModel + let data: ProcessedWeatherData + + var body: some View { + let temp = settings.settings.weatherUseCelsius ? data.temperatureMetric : data.temperature + Text("\(temp)°") + .font(.system(size: 14, weight: .semibold, design: .rounded)) + .foregroundColor(.white) + } + } +} + +struct NotificationActivityView { + static func left(for payload: NotificationPayload) -> some View { + let iconName: String + let bgColor: Color + + switch payload.appIdentifier { + case "com.apple.facetime": + iconName = "video.fill" + bgColor = .green + case "com.apple.iChat": + iconName = "message.fill" + bgColor = .blue + case "com.apple.sharingd": + iconName = "square.and.arrow.down.on.square.fill" + bgColor = .cyan + default: + iconName = "app.badge.fill" + bgColor = .gray + } + + return Image(systemName: iconName) + .font(.system(size: 16)) + .frame(width: 28, height: 28) + .background(bgColor) + .foregroundColor(.white) + .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) + } + + static func right(for payload: NotificationPayload) -> some View { + VStack(alignment: .leading, spacing: 1) { + Text(payload.title) + .font(.system(size: 13, weight: .semibold)) + .foregroundColor(.white) + .lineLimit(1) + Text(payload.body) + .font(.system(size: 13)) + .foregroundColor(.white.opacity(0.8)) + .lineLimit(1) + } + } +} + +struct NotificationBottomView: View { + let payload: NotificationPayload + @EnvironmentObject var notificationManager: NotificationManager + + var body: some View { + HStack(spacing: 12) { + Button("Dismiss") { notificationManager.dismissLatestNotification() } + .buttonStyle(NotificationButtonStyle(color: .gray.opacity(0.4))) + + if payload.appIdentifier == "com.apple.sharingd" { + Button(action: { + if let url = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first { + NSWorkspace.shared.open(url) + } + notificationManager.dismissLatestNotification() + }) { + HStack { + Image(systemName: "folder.fill") + Text("Show") + } + } + .buttonStyle(NotificationButtonStyle(color: .cyan)) + } else if payload.hasAudioAttachment { + Button(action: { + NSWorkspace.shared.launchApplication("Messages") + notificationManager.dismissLatestNotification() + }) { + HStack { + Image(systemName: "play.fill") + Text("Play") + } + } + .buttonStyle(NotificationButtonStyle(color: .blue)) + } else { + Button("Reply") { + NSWorkspace.shared.launchApplication("Messages") + notificationManager.dismissLatestNotification() + } + .buttonStyle(NotificationButtonStyle(color: .gray.opacity(0.4))) + } + } + } +} + +struct NotificationButtonStyle: ButtonStyle { + var color: Color + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .fontWeight(.semibold) + .padding(.horizontal, 12) + .padding(.vertical, 6) + .background(color) + .foregroundColor(.white) + .clipShape(Capsule()) + .scaleEffect(configuration.isPressed ? 0.95 : 1.0) + .animation(.easeOut(duration: 0.2), value: configuration.isPressed) + } +} diff --git a/submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift b/submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift new file mode 100644 index 00000000..8f8e3adb --- /dev/null +++ b/submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift @@ -0,0 +1,273 @@ +// +// LiveActivityManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import Foundation +import SwiftUI +import Combine +import EventKit +import NearbyShare + +// MARK: - Enums and Structs + +enum ActivityType: Int, Equatable, Comparable, CaseIterable { + case none = 0, weather = 5, music = 10, timer = 20, desktopChange = 30, battery = 40, calendar = 50, focusModeChange = 55, bluetooth = 58, audioSwitch = 60, eyeBreak = 70, notification = 80, geminiLive = 85, nearbyShare = 90, systemHUD = 100 + static func < (lhs: ActivityType, rhs: ActivityType) -> Bool { return lhs.rawValue < rhs.rawValue } + init?(from settingsType: LiveActivityType) { + switch settingsType { + case .music: self = .music; case .weather: self = .weather; case .calendar: self = .calendar; case .timers: self = .timer; case .battery: self = .battery; case .eyeBreak: self = .eyeBreak; case .desktop: self = .desktopChange; case .focus: self = .focusModeChange + } + } +} + +private struct SystemHUDIdentifier: Hashable { + let type: HUDType + let style: HUDStyle +} + +// MARK: - LiveActivityManager + +@MainActor +class LiveActivityManager: ObservableObject { + + // MARK: - Published Properties + @Published private(set) var contentUpdateID = UUID() + @Published private(set) var currentActivity: ActivityType = .none + @Published private(set) var activityContent: LiveActivityContent = .none + @Published private(set) var currentNearDropPayload: NearDropPayload? + @Published private(set) var currentGeminiPayload: GeminiPayload? + + @Published private var showNowPlayingText: Bool = false + + // MARK: - Public Properties + var showLyricsBinding: Binding? + var isFullViewActivity: Bool { if case .full = activityContent { true } else { false } } + + // MARK: - Private Properties + private var dismissalTimer: Timer? + private var nowPlayingDismissalTimer: Timer? + private var cancellables = Set() + private var activityCheckers: [ActivityType: () -> (ActivityType, LiveActivityContent, TimeInterval?)?] = [:] + + // MARK: - State Tracking + private var hasShownPluggedInAlert = false, hasShownLowBatteryAlert = false, hasShownCurrentEyeBreak = false + private var lastShownCalendarEventID: String?, lastShownDesktopNumber: Int?, lastShownFocusModeID: String? + private var lastShownBluetoothEvent: BluetoothDeviceState?, lastShownAudioSwitchEventID: UUID? + + // MARK: - Dependencies + private let systemHUDManager: SystemHUDManager, notificationManager: NotificationManager, desktopManager: DesktopManager, focusModeManager: FocusModeManager, musicWidget: MusicWidget, calendarService: CalendarService, batteryMonitor: BatteryMonitor, bluetoothManager: BluetoothManager, audioDeviceManager: AudioDeviceManager, eyeBreakManager: EyeBreakManager, timerManager: TimerManager, weatherActivityViewModel: WeatherActivityViewModel, geminiLiveManager: GeminiLiveManager, settingsModel: SettingsModel, activeAppMonitor: ActiveAppMonitor + + // MARK: - Initialization + init(systemHUDManager: SystemHUDManager, notificationManager: NotificationManager, desktopManager: DesktopManager, focusModeManager: FocusModeManager, musicWidget: MusicWidget, calendarService: CalendarService, batteryMonitor: BatteryMonitor, bluetoothManager: BluetoothManager, audioDeviceManager: AudioDeviceManager, eyeBreakManager: EyeBreakManager, timerManager: TimerManager, weatherActivityViewModel: WeatherActivityViewModel, geminiLiveManager: GeminiLiveManager, settingsModel: SettingsModel, activeAppMonitor: ActiveAppMonitor) { + self.systemHUDManager = systemHUDManager; self.notificationManager = notificationManager; self.desktopManager = desktopManager; self.focusModeManager = focusModeManager; self.musicWidget = musicWidget; self.calendarService = calendarService; self.batteryMonitor = batteryMonitor; self.bluetoothManager = bluetoothManager; self.audioDeviceManager = audioDeviceManager; self.eyeBreakManager = eyeBreakManager; self.timerManager = timerManager; self.weatherActivityViewModel = weatherActivityViewModel; self.geminiLiveManager = geminiLiveManager; self.settingsModel = settingsModel; self.activeAppMonitor = activeAppMonitor + self.lastShownDesktopNumber = desktopManager.currentDesktopNumber + self.activityCheckers = [ .systemHUD: self.checkForSystemHUD, .nearbyShare: self.checkForNearDrop, .geminiLive: self.checkForGeminiLive, .notification: self.checkForNotification, .eyeBreak: self.checkForEyeBreak, .audioSwitch: self.checkForAudioSwitch, .bluetooth: self.checkForBluetooth, .focusModeChange: self.checkForFocusMode, .calendar: self.checkForCalendar, .battery: self.checkForBattery, .desktopChange: self.checkForDesktopChange, .timer: self.checkForTimer, .music: self.checkForMusic, .weather: self.checkForWeather ] + setupSubscriptions() + } + + // MARK: - Subscriptions + private func setupSubscriptions() { + geminiLiveManager.$isMicMuted.receive(on: DispatchQueue.main).sink { [weak self] newMuteState in guard let self, var payload = self.currentGeminiPayload, payload.isMicMuted != newMuteState else { return }; payload.isMicMuted = newMuteState; self.currentGeminiPayload = payload }.store(in: &cancellables) + geminiLiveManager.sessionDidEndPublisher.receive(on: DispatchQueue.main).sink { [weak self] in self?.finishGeminiLive() }.store(in: &cancellables) + musicWidget.playerActionPublisher.receive(on: DispatchQueue.main).sink { [weak self] action in if case .trackChanged = action { self?.triggerNowPlayingText() } }.store(in: &cancellables) + + let stateChangeTriggers: [AnyPublisher] = [ systemHUDManager.$currentHUD.mapToVoid(), $currentNearDropPayload.mapToVoid(), $currentGeminiPayload.mapToVoid(), notificationManager.$latestNotification.mapToVoid(), desktopManager.$currentDesktopNumber.mapToVoid(), focusModeManager.$currentFocusMode.mapToVoid(), calendarService.$nextEvent.mapToVoid(), batteryMonitor.$currentState.mapToVoid(), audioDeviceManager.$lastSwitchEvent.mapToVoid(), bluetoothManager.$lastEvent.mapToVoid(), eyeBreakManager.$isBreakTime.mapToVoid(), timerManager.$isRunning.mapToVoid(), weatherActivityViewModel.$weatherData.mapToVoid(), musicWidget.$shouldShowLiveActivity.mapToVoid(), musicWidget.$currentLyric.mapToVoid(), $showNowPlayingText.mapToVoid(), settingsModel.objectWillChange.mapToVoid(), activeAppMonitor.$isLyricsAllowedForActiveApp.mapToVoid() ] + Publishers.MergeMany(stateChangeTriggers).debounce(for: .milliseconds(50), scheduler: RunLoop.main).sink { [weak self] in self?.evaluateAndDisplayActivity() }.store(in: &cancellables) + } + + // MARK: - Activity Management + private func triggerNowPlayingText() { + nowPlayingDismissalTimer?.invalidate() + self.showNowPlayingText = true + + nowPlayingDismissalTimer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { [weak self] _ in + DispatchQueue.main.async { + guard let self = self else { return } + self.showNowPlayingText = false + self.evaluateAndDisplayActivity() + } + } + } + + private func evaluateAndDisplayActivity(ignoring ignoredType: ActivityType? = nil) { + if musicWidget.shouldShowLiveActivity == false { + nowPlayingDismissalTimer?.invalidate() + showNowPlayingText = false + } + + let highPriorityActivities: [ActivityType] = [.systemHUD, .nearbyShare, .geminiLive, .notification, .audioSwitch, .bluetooth] + let userOrderedActivities = settingsModel.settings.liveActivityOrder.compactMap { ActivityType(from: $0) } + let finalEvaluationOrder = highPriorityActivities + userOrderedActivities + for activityType in finalEvaluationOrder { + guard activityType != ignoredType, let checker = activityCheckers[activityType] else { continue } + if let (type, content, duration) = checker() { + setActivity(type: type, content: content, dismissAfter: duration) + return + } + } + setActivity(type: .none, content: .none) + } + + private func setActivity(type: ActivityType, content: LiveActivityContent, dismissAfter duration: TimeInterval? = nil) { + if self.currentActivity == type && self.activityContent == content { return } + dismissalTimer?.invalidate() + self.currentActivity = type; self.activityContent = content; self.contentUpdateID = UUID() + if let duration = duration { + dismissalTimer = Timer.scheduledTimer(withTimeInterval: duration, repeats: false) { [weak self] _ in + guard let self, self.currentActivity == type else { return } + switch type { + case .desktopChange: self.lastShownDesktopNumber = self.desktopManager.currentDesktopNumber + case .battery: if let state = self.batteryMonitor.currentState { if state.isLow { self.hasShownLowBatteryAlert = true } else if state.isPluggedIn { self.hasShownPluggedInAlert = true } } + case .focusModeChange: self.lastShownFocusModeID = self.focusModeManager.currentFocusMode?.identifier + case .calendar: self.lastShownCalendarEventID = self.calendarService.nextEvent?.eventIdentifier + case .eyeBreak: self.hasShownCurrentEyeBreak = true + case .bluetooth: self.lastShownBluetoothEvent = self.bluetoothManager.lastEvent + case .audioSwitch: self.lastShownAudioSwitchEventID = self.audioDeviceManager.lastSwitchEvent?.id + default: break + } + self.evaluateAndDisplayActivity(ignoring: type) + } + } + } + + // MARK: - Activity Checkers + private func checkForMusic() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard settingsModel.settings.musicLiveActivityEnabled, musicWidget.shouldShowLiveActivity else { return nil } + + let lyricsAllowed = activeAppMonitor.isLyricsAllowedForActiveApp + let activityView: AnyView + + // Conditionally create the view to avoid passing an EmptyView to the bottom parameter, + // which can cause unwanted padding. + if self.showNowPlayingText { + let view = StandardActivityView( + left: { AlbumArtView(image: musicWidget.artwork) }, + right: { WaveformView().environmentObject(musicWidget).environmentObject(settingsModel) }, + bottom: { NowPlayingTextView(title: self.musicWidget.title ?? "Now Playing") } + ) + activityView = AnyView(view) + } else if self.musicWidget.isPlaying && lyricsAllowed && self.settingsModel.settings.showLyricsInLiveActivity { + let view = StandardActivityView( + left: { AlbumArtView(image: musicWidget.artwork) }, + right: { WaveformView().environmentObject(musicWidget).environmentObject(settingsModel) }, + bottom: { MusicLyricsView(self.showLyricsBinding ?? .constant(false)) } + ) + activityView = AnyView(view) + } else { + // Use an initializer that does not take a bottom view. + let view = StandardActivityView( + left: { AlbumArtView(image: musicWidget.artwork) }, + right: { WaveformView().environmentObject(musicWidget).environmentObject(settingsModel) } + ) + activityView = AnyView(view) + } + + let identifier = (musicWidget.title ?? "") + (musicWidget.artist ?? "") + "\(showNowPlayingText)" + + return (.music, .standard(view: activityView, id: identifier), nil) + } + + private func checkForWeather() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard settingsModel.settings.weatherLiveActivityEnabled, let data = weatherActivityViewModel.weatherData else { return nil } + let view = StandardActivityView(left: { WeatherActivityView.left(for: data) }, right: { WeatherActivityView.right(for: data) }) + return (.weather, .standard(view: AnyView(view), id: data), nil) + } + + private func checkForCalendar() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard settingsModel.settings.calendarLiveActivityEnabled, let event = calendarService.nextEvent, event.startDate.timeIntervalSinceNow < 15 * 60, event.eventIdentifier != lastShownCalendarEventID else { return nil } + let view = StandardActivityView(left: { CalendarActivityView.left(for: event) }, right: { CalendarActivityView.right(for: event) }) + return (.calendar, .standard(view: AnyView(view), id: event.eventIdentifier), 15.0) + } + + private func checkForTimer() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard settingsModel.settings.timersLiveActivityEnabled, timerManager.isRunning else { return nil } + return (.timer, .standard(view: AnyView(StandardActivityView(left: { TimerActivityView().environmentObject(timerManager) })), id: "active_timer"), nil) + } + + private func checkForBattery() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard settingsModel.settings.batteryLiveActivityEnabled, let state = batteryMonitor.currentState else { return nil } + if !state.isLow { hasShownLowBatteryAlert = false }; if !state.isPluggedIn { hasShownPluggedInAlert = false } + let view = StandardActivityView(left: { BatteryActivityView.left(for: state) }, right: { BatteryActivityView.right(for: state) }) + if state.isLow, !hasShownLowBatteryAlert { return (.battery, .standard(view: AnyView(view), id: "low_battery_alert"), 10.0) } + if state.isPluggedIn, !state.isLow, !hasShownPluggedInAlert { return (.battery, .standard(view: AnyView(view), id: state), 5.0) } + return nil + } + + private func checkForEyeBreak() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + if !eyeBreakManager.isBreakTime { hasShownCurrentEyeBreak = false } + guard settingsModel.settings.eyeBreakLiveActivityEnabled, eyeBreakManager.isBreakTime, !hasShownCurrentEyeBreak else { return nil } + let view = StandardActivityView(left: { EyeBreakActivityView.left }, right: { EyeBreakActivityView.right }, bottom: { EyeBreakActivityView.bottom() }) + return (.eyeBreak, .standard(view: AnyView(view), id: "eye_break_active"), 60.0) + } + + private func checkForDesktopChange() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard settingsModel.settings.desktopLiveActivityEnabled, let desktopNum = desktopManager.currentDesktopNumber, desktopNum != lastShownDesktopNumber else { return nil } + let view = StandardActivityView(left: { DesktopActivityView.left(for: desktopNum) }, right: { DesktopActivityView.right(for: desktopNum) }) + return (.desktopChange, .standard(view: AnyView(view), id: desktopNum), 2.0) + } + + private func checkForFocusMode() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard settingsModel.settings.focusLiveActivityEnabled, let mode = focusModeManager.currentFocusMode, mode.identifier != lastShownFocusModeID else { return nil } + let view = StandardActivityView(left: { FocusModeActivityView.left(for: mode) }, right: { FocusModeActivityView.right(for: mode) }) + return (.focusModeChange, .standard(view: AnyView(view), id: mode.identifier), 4.0) + } + + private func checkForSystemHUD() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard let hudType = systemHUDManager.currentHUD else { return nil } + let style: HUDStyle; switch hudType { case .volume: guard settingsModel.settings.enableVolumeHUD else { return nil }; style = settingsModel.settings.volumeHUDStyle; case .brightness: guard settingsModel.settings.enableBrightnessHUD else { return nil }; style = settingsModel.settings.brightnessHUDStyle } + let id = SystemHUDIdentifier(type: hudType, style: style) + let content: LiveActivityContent = (style == .default) ? .full(view: AnyView(SystemHUDView(type: hudType)), id: id) : .standard(view: AnyView(StandardActivityView(left: { SystemHUDSlimActivityView.left(type: hudType) }, right: { SystemHUDSlimActivityView.right(type: hudType) })), id: id) + return (.systemHUD, content, nil) + } + + private func checkForNearDrop() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard let payload = currentNearDropPayload else { return nil } + let content: LiveActivityContent = (payload.state == .waitingForConsent) ? .full(view: AnyView(NearDropLiveActivityView(payload: payload)), id: payload) : .standard(view: AnyView(StandardActivityView(left: { NearDropCompactActivityView.left() }, right: { NearDropCompactActivityView.right(payload: payload) })), id: payload) + return (.nearbyShare, content, (payload.state == .waitingForConsent) ? 60.0 : nil) + } + + private func checkForGeminiLive() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard let payload = currentGeminiPayload else { return nil } + let rightView = GeminiActiveActivityView.right(isMuted: payload.isMicMuted) { self.geminiLiveManager.isMicMuted.toggle(); if self.geminiLiveManager.isMicMuted { self.geminiLiveManager.signalEndOfUserTurn() } } + let view = StandardActivityView(left: { GeminiActiveActivityView.left() }, right: { rightView }) + return (.geminiLive, .standard(view: AnyView(view), id: payload), nil) + } + + private func checkForNotification() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard let notification = notificationManager.latestNotification else { return nil } + let view = StandardActivityView(left: { NotificationActivityView.left(for: notification) }, right: { NotificationActivityView.right(for: notification) }, bottom: { NotificationBottomView(payload: notification) }) + return (.notification, .standard(view: AnyView(view), id: notification.id), 15.0) + } + + private func checkForAudioSwitch() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard let event = audioDeviceManager.lastSwitchEvent, event.id != lastShownAudioSwitchEventID else { return nil } + let view = StandardActivityView(left: { AudioSwitchActivityView.left(for: event) }, right: { AudioSwitchActivityView.right(for: event) }) + return (.audioSwitch, .standard(view: AnyView(view), id: event.id), 5.0) + } + + private func checkForBluetooth() -> (ActivityType, LiveActivityContent, TimeInterval?)? { + guard let event = bluetoothManager.lastEvent, event != lastShownBluetoothEvent else { return nil } + let view: AnyView, duration: TimeInterval; switch event.eventType { case .connected: view = AnyView(StandardActivityView(left: { BluetoothActivityView.left(for: event) }, right: { BluetoothActivityView.right(for: event) })); duration = 6.0; case .disconnected: view = AnyView(StandardActivityView(left: { BluetoothDisconnectedActivityView.left(for: event) }, right: { BluetoothDisconnectedActivityView.right(for: event) })); duration = 5.0; case .batteryLow: view = AnyView(StandardActivityView(left: { BluetoothBatteryActivityView.left(for: event) }, right: { BluetoothBatteryActivityView.right(for: event) })); duration = 12.0 } + return (.bluetooth, .standard(view: view, id: event), duration) + } + + // MARK: - Public Control Functions + func startGeminiLive() { guard currentGeminiPayload == nil else { return }; self.currentGeminiPayload = GeminiPayload(isMicMuted: geminiLiveManager.isMicMuted); evaluateAndDisplayActivity() } + func finishGeminiLive() { self.currentGeminiPayload = nil; evaluateAndDisplayActivity() } + func startNearDropActivity(transfer: TransferMetadata, device: RemoteDeviceInfo, fileURLs: [URL]) { self.currentNearDropPayload = NearDropPayload(id: transfer.id, device: device, transfer: transfer, destinationURLs: fileURLs); evaluateAndDisplayActivity() } + func updateNearDropState(to newState: NearDropTransferState) { guard var payload = self.currentNearDropPayload else { return }; payload.state = newState; if newState == .inProgress { payload.progress = 0.0 }; self.currentNearDropPayload = payload; evaluateAndDisplayActivity() } + func declineNearDropTransfer(id: String) { NearbyConnectionManager.shared.submitUserConsent(transferID: id, accept: false); clearNearDropActivity(id: id) } + func updateNearDropProgress(id: String, progress: Double) { guard var payload = self.currentNearDropPayload, payload.id == id else { return }; payload.progress = progress; self.currentNearDropPayload = payload } + func finishNearDropTransfer(id: String, error: Error?) { guard var payload = self.currentNearDropPayload, payload.id == id, (payload.state == .waitingForConsent || payload.state == .inProgress) else { return }; if let error { let errorString: String; if let nearbyError = error as? NearbyError, case .canceled(let reason) = nearbyError { switch reason { case .userRejected: errorString = "Declined"; case .userCanceled: errorString = "Canceled"; case .notEnoughSpace: errorString = "Not enough space"; case .unsupportedType: errorString = "Unsupported type"; case .timedOut: errorString = "Timed out"; default: errorString = "Canceled" } } else { errorString = error.localizedDescription }; payload.state = .failed(errorString.isEmpty ? "Unknown Error" : errorString) } else { payload.state = .finished }; payload.progress = nil; self.currentNearDropPayload = payload; DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) { self.clearNearDropActivity(id: id) } } + func clearNearDropActivity(id: String? = nil) { if id == nil || self.currentNearDropPayload?.id == id { self.currentNearDropPayload = nil; evaluateAndDisplayActivity() } } +} + +// MARK: - Publisher Extension +extension Publisher { + func mapToVoid() -> AnyPublisher { + self.map { _ in () }.catch { _ in Empty() }.eraseToAnyPublisher() + } +} diff --git a/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift b/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift new file mode 100644 index 00000000..626a220f --- /dev/null +++ b/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift @@ -0,0 +1,81 @@ +// +// NearDropCompactActivityView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-03. +// + +import SwiftUI +import NearbyShare + + +struct NearDropCompactActivityView { + + + static func left() -> some View { + ZStack { + Image(privateName: "shareplay") + .font(.system(size: 14, weight: .semibold)) + .foregroundColor(.white) + } + .frame(width: 20, height: 20) + } + + + static func right(payload: NearDropPayload) -> some View { + ZStack { + switch payload.state { + case .inProgress: + + CustomCircularProgressView(progress: payload.progress ?? 0) + .transition(.opacity.combined(with: .scale(scale: 0.8))) + + case .finished: + Image(systemName: "checkmark.circle.fill") + .foregroundColor(.green) + .transition(.opacity.combined(with: .scale(scale: 0.8))) + + case .failed: + Image(systemName: "xmark.circle.fill") + .foregroundColor(.red) + .transition(.opacity.combined(with: .scale(scale: 0.8))) + + case .waitingForConsent: + Image(systemName: "hourglass") + .foregroundColor(.secondary) + .transition(.opacity.combined(with: .scale(scale: 0.8))) + } + } + .frame(width: 15, height: 15) + .animation(.spring(response: 0.4, dampingFraction: 0.7), value: payload.state) + } +} + + + + + +private struct CustomCircularProgressView: View { + let progress: Double + private let lineWidth: CGFloat = 3.0 + + var body: some View { + ZStack { + + Circle() + .stroke(lineWidth: lineWidth) + .foregroundColor(.accentColor) + .opacity(0.3) + + + Circle() + .trim(from: 0.0, to: min(progress, 1.0)) + .stroke(style: StrokeStyle(lineWidth: lineWidth, lineCap: .round, lineJoin: .round)) + .foregroundColor(.accentColor) + .rotationEffect(Angle(degrees: 270.0)) + } + + + .animation(.linear(duration: 0.2), value: progress) + } +} diff --git a/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift b/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift new file mode 100644 index 00000000..247e0ef1 --- /dev/null +++ b/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift @@ -0,0 +1,257 @@ +// +// NearDropLiveActivityView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import SwiftUI +import NearbyShare + + +struct NearDropLiveActivityView: View { + let payload: NearDropPayload + @EnvironmentObject var liveActivityManager: LiveActivityManager + + + @State private var isShowing = false + + var body: some View { + HStack(spacing: 16) { + + previewIconView + + + VStack(alignment: .leading, spacing: 10) { + + VStack(alignment: .leading, spacing: 2) { + Text("From \(payload.device.name)") + .font(.headline) + .fontWeight(.bold) + .foregroundColor(.primary) + + Text(fileInfoText) + .font(.subheadline) + .foregroundColor(.secondary) + .lineLimit(1) + .truncationMode(.middle) + } + + + actionView + .frame(height: 36) + } + + .animation(.spring(response: 0.3, dampingFraction: 0.8), value: payload.state) + } + .padding(12) + .padding(.horizontal) + .padding(.top, 25) + + + .scaleEffect(isShowing ? 1 : 0.95) + .opacity(isShowing ? 1 : 0) + .onAppear { + withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) { + isShowing = true + } + } + } + + + + @ViewBuilder + private var previewIconView: some View { + ZStack { + RoundedRectangle(cornerRadius: 18, style: .continuous) + .fill(Color.accentColor) + + Image(systemName: iconName(for: payload.transfer)) + .font(.system(size: 36, weight: .regular)) + .foregroundColor(.white) + .shadow(color: .black.opacity(0.15), radius: 3, y: 2) + } + .frame(width: 72, height: 72) + } + + @ViewBuilder + private var actionView: some View { + switch payload.state { + case .waitingForConsent: + IntegratedActionIconButtonsView(payload: payload) + .environmentObject(liveActivityManager) + + .transition(.opacity) + + case .inProgress: + ModernLinearProgressView(progress: payload.progress ?? 0) + .transition(.opacity) + + case .finished: + StatusTagView(text: "Transfer Complete", color: .green) + .transition(.opacity) + + case .failed(let reason): + StatusTagView(text: "Failed: \(reason)", color: .red) + .transition(.opacity) + } + } + + + + private var fileInfoText: String { + if let textTitle = payload.transfer.textDescription { + return textTitle + } + if payload.transfer.files.count == 1 { return payload.transfer.files[0].name } + return String.localizedStringWithFormat(NSLocalizedString("NFiles", comment: ""), payload.transfer.files.count) + } + + private func extractURL(from string: String) -> URL? { + if let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) { + if let match = detector.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) { + return match.url + } + } + return nil + } + + private func iconName(for transfer: TransferMetadata) -> String { + if let desc = transfer.textDescription, extractURL(from: desc) != nil { return "link" } + if transfer.textDescription != nil { return "text.quote" } + guard let firstFile = transfer.files.first else { return "questionmark" } + if transfer.files.count > 1 { return "doc.on.doc.fill" } + let mimeType = firstFile.mimeType.lowercased() + if mimeType.starts(with: "image/") { return "photo" } + if mimeType.starts(with: "video/") { return "video.fill" } + if mimeType.starts(with: "audio/") { return "music.note" } + if mimeType.contains("pdf") { return "doc.richtext.fill" } + if mimeType.contains("zip") || mimeType.contains("archive") { return "archivebox.fill" } + return "doc.fill" + } +} + + + +private struct IntegratedActionIconButtonsView: View { + let payload: NearDropPayload + @EnvironmentObject var liveActivityManager: LiveActivityManager + + private func submitConsent(accept: Bool, action: NearDropUserAction = .save) { + if accept { liveActivityManager.updateNearDropState(to: .inProgress) } + NearbyConnectionManager.shared.submitUserConsent(transferID: payload.id, accept: accept, action: action) + } + + var body: some View { + HStack(spacing: 10) { + let declineButton = Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } + .buttonStyle(ModernIconActionButtonStyle(type: .destructive)) + .accessibilityLabel("Decline") + + if let textContent = payload.transfer.textDescription { + if let _ = URL(string: textContent) { + declineButton + Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } + .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) + .accessibilityLabel("Copy Link") + Button { submitConsent(accept: true, action: .open) } label: { Image(systemName: "arrow.up.right.square") } + .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) + .accessibilityLabel("Open Link") + } else { + declineButton + Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } + .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) + .accessibilityLabel("Copy Text") + Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "square.and.arrow.down") } + .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) + .accessibilityLabel("Save Text") + } + } else { + declineButton + Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "checkmark") } + .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) + .accessibilityLabel("Accept") + } + Spacer() + } + } +} + +private struct ModernLinearProgressView: View { + let progress: Double + + var body: some View { + GeometryReader { geometry in + ZStack(alignment: .leading) { + Capsule().fill(Color.primary.opacity(0.1)) + Capsule().fill(Color.accentColor).frame(width: geometry.size.width * progress) + Text("\(Int(progress * 100))%") + .font(.caption.bold()) + .foregroundColor(.white) + .padding(.horizontal, 8) + } + } + .animation(.easeOut, value: progress) + } +} + +private struct StatusTagView: View { + let text: String + let color: Color + + var body: some View { + HStack(spacing: 6) { + Image(systemName: color == .green ? "checkmark.circle.fill" : "xmark.circle.fill") + Text(text).lineLimit(1) + } + .font(.caption.bold()) + .padding(.horizontal, 10) + .padding(.vertical, 6) + .background(color.opacity(0.2)) + .foregroundStyle(color) + .clipShape(Capsule()) + .frame(maxWidth: .infinity, alignment: .leading) + } +} + + + + +enum ModernButtonType { + case prominent, normal, destructive +} + +private struct ModernIconActionButtonStyle: ButtonStyle { + var type: ModernButtonType + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(.system(size: 16, weight: .semibold)) + .foregroundColor(foregroundColor) + .frame(width: 36, height: 36) + .background(backgroundColor) + .clipShape(Circle()) + .scaleEffect(configuration.isPressed ? 0.90 : 1.0) + .animation(.spring(response: 0.2, dampingFraction: 0.6), value: configuration.isPressed) + } + + private var backgroundColor: Color { + switch type { + case .prominent: + return .accentColor + case .normal: + return .secondary.opacity(0.2) + case .destructive: + return .red + } + } + + private var foregroundColor: Color { + switch type { + case .prominent, .destructive: + return .white + case .normal: + return .primary + } + } +} diff --git a/submissions/sapphire/Sapphire/Models/AppModels.swift b/submissions/sapphire/Sapphire/Models/AppModels.swift new file mode 100644 index 00000000..9dff04fc --- /dev/null +++ b/submissions/sapphire/Sapphire/Models/AppModels.swift @@ -0,0 +1,121 @@ +// +// AppModels.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-06. +// + +import SwiftUI +import NearbyShare + +enum LiveActivityContent: Equatable { + case none + case full(view: AnyView, id: AnyHashable) + case standard(view: AnyView, id: AnyHashable) + + static func == (lhs: LiveActivityContent, rhs: LiveActivityContent) -> Bool { + switch (lhs, rhs) { + case (.none, .none): return true + case let (.full(_, lhsId), .full(_, rhsId)): return lhsId == rhsId + case let (.standard(_, lhsId), .standard(_, rhsId)): return lhsId == rhsId + default: return false + } + } +} + +struct StandardActivityView: View { + let leftContent: LeftContent? + let rightContent: RightContent? + let bottomContent: BottomContent? + let onBottomContentTapped: (() -> Void)? + + init( + @ViewBuilder left: () -> LeftContent, + @ViewBuilder right: () -> RightContent, + @ViewBuilder bottom: () -> BottomContent, + onBottomContentTapped: (() -> Void)? = nil + ) { + self.leftContent = left() + self.rightContent = right() + self.bottomContent = bottom() + self.onBottomContentTapped = onBottomContentTapped + } + + var body: some View { + VStack(spacing: 0) { + HStack(spacing: NotchConfiguration.initialSize.width) { + leftContent.padding(.leading, 10) + rightContent.padding(.trailing, 10) + } + .frame(minHeight: NotchConfiguration.initialSize.height) + .modifier(SizeLoggingViewModifier(label: "StandardActivityView Internal HStack")) + + if !(bottomContent is EmptyView) { + VStack { + Divider().opacity(0.3) + bottomContent + .padding(.bottom, 10) + .contentShape(Rectangle()) + .onTapGesture { onBottomContentTapped?() } + } + } + } + .fixedSize() + } +} + +extension StandardActivityView where BottomContent == EmptyView { + init( + @ViewBuilder left: () -> LeftContent, + @ViewBuilder right: () -> RightContent, + onBottomContentTapped: (() -> Void)? = nil + ) { + self.init(left: left, right: right, bottom: { EmptyView() }, onBottomContentTapped: onBottomContentTapped) + } +} + +extension StandardActivityView where RightContent == EmptyView, BottomContent == EmptyView { + init( + @ViewBuilder left: () -> LeftContent, + onBottomContentTapped: (() -> Void)? = nil + ) { + self.init(left: left, right: { EmptyView() }, bottom: { EmptyView() }, onBottomContentTapped: onBottomContentTapped) + } +} + + + +struct NotificationPayload: Identifiable, Equatable { + let id: String, appIdentifier: String, title: String, body: String + var hasAudioAttachment: Bool { body.contains("Audio Message") || body.contains("sent an audio message") } + var hasImageAttachment: Bool { body.contains("sent an image") } + var appName: String { + switch appIdentifier { + case "com.apple.iChat": "Messages"; case "com.apple.facetime": "FaceTime"; case "com.apple.sharingd": "AirDrop"; default: "Notification" + } + } +} + +enum NearDropTransferState: Equatable, Hashable { case waitingForConsent, inProgress, finished, failed(String) } +struct NearDropPayload: Identifiable, Hashable { + let id: String, device: RemoteDeviceInfo, transfer: TransferMetadata, destinationURLs: [URL] + var state: NearDropTransferState = .waitingForConsent; var progress: Double? + static func == (lhs: NearDropPayload, rhs: NearDropPayload) -> Bool { lhs.id == rhs.id && lhs.state == rhs.state && lhs.progress == rhs.progress } + func hash(into hasher: inout Hasher) { hasher.combine(id); hasher.combine(state); hasher.combine(progress) } +} + +enum GeminiLiveState: Equatable, Hashable { case active } +struct GeminiPayload: Identifiable, Hashable { + let id = UUID(); var state: GeminiLiveState = .active; var isMicMuted: Bool = true +} + +struct LyricLine: Identifiable, Hashable { + let id = UUID(); let text: String; let timestamp: TimeInterval; var translatedText: String? +} + +struct BatteryState: Equatable, Hashable { + let level: Int, isCharging: Bool, isPluggedIn: Bool + var isLow: Bool { level <= 20 && !isCharging } +} + +struct FocusModeInfo: Equatable, Hashable { let name: String, identifier: String } diff --git a/submissions/sapphire/Sapphire/Models/SpotifyModels.swift b/submissions/sapphire/Sapphire/Models/SpotifyModels.swift new file mode 100644 index 00000000..d490e2c6 --- /dev/null +++ b/submissions/sapphire/Sapphire/Models/SpotifyModels.swift @@ -0,0 +1,125 @@ +// +// SpotifyModels.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import Foundation + + +struct SpotifyImage: Codable { + let url: String +} + +struct SpotifyAlbum: Codable { + let images: [SpotifyImage] +} + +struct SpotifyArtist: Codable { + let name: String +} + + + +struct PlaybackState: Codable { + let device: SpotifyDevice + let item: SpotifyTrack? + let isPlaying: Bool + let progressMs: Int? + + enum CodingKeys: String, CodingKey { + case device, item, progressMs = "progress_ms", isPlaying = "is_playing" + } +} + +struct UserProfile: Codable, Identifiable { + let id: String + let displayName: String + let product: String + + enum CodingKeys: String, CodingKey { + case id, product, displayName = "display_name" + } +} + + +struct SpotifyUserSimple: Codable, Identifiable { + let id: String + let displayName: String + + enum CodingKeys: String, CodingKey { + case id, displayName = "display_name" + } +} + +struct SpotifyTrack: Codable, Identifiable { + let id: String + let name: String + let uri: String + let album: SpotifyAlbum + let artists: [SpotifyArtist] + + var imageURL: URL? { + guard let urlString = images.first?.url else { return nil } + return URL(string: urlString) + } + + private var images: [SpotifyImage] { + return album.images + } +} + +struct SpotifyPlaylist: Codable, Identifiable { + let id: String + let name: String + let uri: String + let images: [SpotifyImage] + + let owner: SpotifyUserSimple + + var imageURL: URL? { + guard let urlString = images.first?.url else { return nil } + return URL(string: urlString) + } +} + +struct SpotifyDevice: Codable, Identifiable { + let id: String? + let name: String + let type: String + let isActive: Bool + let volumePercent: Int? + enum CodingKeys: String, CodingKey { case id, name, type, isActive = "is_active", volumePercent = "volume_percent" } +} + +struct SpotifyQueue: Codable { + let currentlyPlaying: SpotifyTrack? + let queue: [SpotifyTrack] + enum CodingKeys: String, CodingKey { case currentlyPlaying = "currently_playing", queue } +} + + +struct AudioAnalysis: Codable { + let segments: [AnalysisSegment] +} + +struct AnalysisSegment: Codable { + let start: Double + let duration: Double + let loudness_max: Double + + enum CodingKeys: String, CodingKey { + case start, duration + case loudness_max = "loudness_max" + } +} + + +struct SearchResponse: Codable { + let tracks: TrackSearchResult +} + +struct TrackSearchResult: Codable { + let items: [SpotifyTrack] +} diff --git a/submissions/sapphire/Sapphire/Models/WeatherModels.swift b/submissions/sapphire/Sapphire/Models/WeatherModels.swift new file mode 100644 index 00000000..02bcb94d --- /dev/null +++ b/submissions/sapphire/Sapphire/Models/WeatherModels.swift @@ -0,0 +1,148 @@ +// +// WeatherModels.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import Foundation + + +struct WeatherApiResponse: Codable { + var conditionsshort: ConditionsShort? + var fcstdaily10short: FcstDaily10Short? + var fcsthourly24short: FcstHourly24Short? + var nowlinks: Nowlinks? +} + +struct ConditionsShort: Codable { + var observation: Observation? +} + +struct Observation: Codable { + var imperial: ImperialObservation? + var metric: ImperialObservation? + var wx_phrase: String? + var wx_icon: Int? + var rh: Int? + var uv_index: Int? + var uv_desc: String? + var vis: Double? + var pressure: Double? +} + +struct ImperialObservation: Codable { + var temp: Int? + var feels_like: Int? + var wspd: Int? +} + +struct FcstDaily10Short: Codable { + var forecasts: [DailyForecast]? +} + +struct DailyForecast: Codable { + var dow: String? + var imperial: ImperialForecast? + var metric: ImperialForecast? + var day: DayPart? + var night: DayPart? + var sunrise: String? + var sunset: String? +} + +struct ImperialForecast: Codable { + var max_temp: Int? + var min_temp: Int? +} + +struct DayPart: Codable { + var icon_cd: Int? + var pop: Int? +} + +struct FcstHourly24Short: Codable { + var forecasts: [HourlyForecast]? +} + +struct HourlyForecast: Codable { + var fcst_valid: Int? + var icon_cd: Int? + var imperial: ImperialHourlyForecast? + var metric: ImperialHourlyForecast? +} + +struct ImperialHourlyForecast: Codable { + var temp: Int? +} + +struct Nowlinks: Codable { + var nowlink: [Nowlink]? +} + +struct Nowlink: Codable { + var url: String? +} + + +struct ProcessedWeatherData: Hashable { + let locationName: String + let temperature: Int + let temperatureMetric: Int + let highTemp: Int + let highTempMetric: Int + let lowTemp: Int + let lowTempMetric: Int + let conditionDescription: String + let iconCode: Int + let feelsLike: Int + let feelsLikeMetric: Int + let windInfo: String + let humidity: String + let precipChance: Int + let uvIndex: String + let sunriseTime: String + let sunsetTime: String + let visibility: String + let pressure: String + let dailyForecasts: [DailyForecastUIData] + let hourlyForecasts: [HourlyForecastUIData] + + static func empty() -> ProcessedWeatherData { + .init(locationName: "N/A", temperature: 0, temperatureMetric: 0, highTemp: 0, highTempMetric: 0, lowTemp: 0, lowTempMetric: 0, conditionDescription: "N/A", iconCode: 44, feelsLike: 0, feelsLikeMetric: 0, windInfo: "N/A", humidity: "N/A", precipChance: 0, uvIndex: "N/A", sunriseTime: "N/A", sunsetTime: "N/A", visibility: "N/A", pressure: "N/A", dailyForecasts: [], hourlyForecasts: []) + } +} + +struct DailyForecastUIData: Identifiable, Hashable { + let id = UUID() + let dayOfWeek: String + let iconName: String + let highTemp: Int + let lowTemp: Int + let highTempMetric: Int + let lowTempMetric: Int + + static func == (lhs: DailyForecastUIData, rhs: DailyForecastUIData) -> Bool { + lhs.dayOfWeek == rhs.dayOfWeek + } + + func hash(into hasher: inout Hasher) { + hasher.combine(dayOfWeek) + } +} + +struct HourlyForecastUIData: Identifiable, Hashable { + let id = UUID() + let time: String + let iconName: String + let temperature: String + let temperatureMetric: String + + static func == (lhs: HourlyForecastUIData, rhs: HourlyForecastUIData) -> Bool { + lhs.time == rhs.time + } + + func hash(into hasher: inout Hasher) { + hasher.combine(time) + } +} diff --git a/submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift b/submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift new file mode 100644 index 00000000..a4e70a23 --- /dev/null +++ b/submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift @@ -0,0 +1,36 @@ +// +// weatherActivityViewModel.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-28. +// + +import Foundation +import SwiftUI +import CoreLocation + +class WeatherActivityViewModel: ObservableObject { + private let service = WeatherService() + @Published var weatherData: ProcessedWeatherData? + + init() { + fetch() + + Timer.scheduledTimer(withTimeInterval: 60 * 15, repeats: true) { [weak self] _ in + self?.fetch() + } + } + + func fetch() { + service.fetchWeather { [weak self] result in + DispatchQueue.main.async { + switch result { + case .success(let data): + self?.weatherData = data + case .failure(let error): + self?.weatherData = nil + } + } + } + } +} diff --git a/submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift b/submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift new file mode 100644 index 00000000..09b17ee4 --- /dev/null +++ b/submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift @@ -0,0 +1,64 @@ +// +// CustomNotchShape.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-05-12. +// + +import SwiftUI + +struct CustomNotchShape: Shape { + var cornerRadius: CGFloat + + + var animatableData: CGFloat { + get { cornerRadius } + set { cornerRadius = newValue } + } + + + + func path(in rect: CGRect) -> Path { + + + let radii = Self.calculateRadii(cornerRadius: cornerRadius, in: rect) + let topRadius = radii.top + let safeBottomRadius = radii.bottom + + + var path = Path() + path.move(to: CGPoint(x: rect.minX, y: rect.minY)) + path.addQuadCurve(to: CGPoint(x: rect.minX + topRadius, y: rect.minY + topRadius), control: CGPoint(x: rect.minX + topRadius, y: rect.minY)) + path.addLine(to: CGPoint(x: rect.minX + topRadius, y: rect.maxY - safeBottomRadius)) + if safeBottomRadius > 0 { path.addArc(center: CGPoint(x: rect.minX + topRadius + safeBottomRadius, y: rect.maxY - safeBottomRadius), radius: safeBottomRadius, startAngle: Angle(degrees: 180), endAngle: Angle(degrees: 90), clockwise: true) } else { path.addLine(to: CGPoint(x: rect.minX + topRadius, y: rect.maxY)) } + path.addLine(to: CGPoint(x: rect.maxX - topRadius - safeBottomRadius, y: rect.maxY)) + if safeBottomRadius > 0 { path.addArc(center: CGPoint(x: rect.maxX - topRadius - safeBottomRadius, y: rect.maxY - safeBottomRadius), radius: safeBottomRadius, startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 0), clockwise: true) } else { path.addLine(to: CGPoint(x: rect.maxX - topRadius, y: rect.maxY)) } + path.addLine(to: CGPoint(x: rect.maxX - topRadius, y: rect.minY + topRadius)) + path.addQuadCurve(to: CGPoint(x: rect.maxX, y: rect.minY), control: CGPoint(x: rect.maxX - topRadius, y: rect.minY)) + path.closeSubpath() + return path + } + + + + + + + + + + static func calculateRadii(cornerRadius: CGFloat, in rect: CGRect) -> (top: CGFloat, bottom: CGFloat) { + + let derivedTopRadiusBase = cornerRadius > 15 ? cornerRadius - 5 : 5 + let maxPossibleTopRadiusFromHeight = rect.height > 0 ? rect.height / 2.0 : 0 + let derivedTopRadius = min(derivedTopRadiusBase, maxPossibleTopRadiusFromHeight) + let topRadius = max(0.0, min(derivedTopRadius, rect.width / 2.0)) + + + let availableWidthForBottomRadii = rect.width - 2 * topRadius + let availableHeightForBottomRadius = rect.height - topRadius + let safeBottomRadius = max(0.0, min(cornerRadius, availableWidthForBottomRadii / 2.0, availableHeightForBottomRadius)) + + return (top: topRadius, bottom: safeBottomRadius) + } +} diff --git a/submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift b/submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift new file mode 100644 index 00000000..c44d5a68 --- /dev/null +++ b/submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift @@ -0,0 +1,55 @@ +// +// NotchConfiguration.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-05-08. +// + +import SwiftUI + +struct NotchConfiguration { + + static let universalWidth: CGFloat = 195 + static let universalHeight: CGFloat = 32 + static let initialSize = CGSize(width: universalWidth, height: universalHeight) + static let initialCornerRadius: CGFloat = 10 + + + static let scaleFactor: CGFloat = 1.12 + static let hoverExpandedSize = CGSize(width: universalWidth * scaleFactor, height: universalHeight * scaleFactor) + static let hoverExpandedCornerRadius: CGFloat = 10 + + static let autoExpandedCornerRadius: CGFloat = 14 + static let autoExpandedTallHeight: CGFloat = 80 + + static let autoExpandedContentVerticalPadding: CGFloat = 8 + + static let clickExpandedCornerRadius: CGFloat = 40 + + + static let collapseDelay: TimeInterval = 0.07 + + + + static let expandAnimation = Animation.spring(response: 0.45, dampingFraction: 0.625, blendDuration: 0) + + + + + + + static let collapseAnimation = Animation.spring(response: 0.35, dampingFraction: 1, blendDuration: 0) + + static let autoExpandAnimation = Animation.spring(response: 0.6, dampingFraction: 0.6, blendDuration: 0) + + + static let expandedShadowColor = Color.black.opacity(0.4) + static let expandedShadowRadius: CGFloat = 18 + static let expandedShadowOffset = CGPoint(x: 0, y: 8) + + + static let contentTopPadding: CGFloat = 10 + static let contentBottomPadding: CGFloat = 10 + static let contentHorizontalPadding: CGFloat = 35 + static let contentVisibilityThresholdHeight: CGFloat = universalHeight + 1 +} diff --git a/submissions/sapphire/Sapphire/Notch/NotchController.swift b/submissions/sapphire/Sapphire/Notch/NotchController.swift new file mode 100644 index 00000000..257323dc --- /dev/null +++ b/submissions/sapphire/Sapphire/Notch/NotchController.swift @@ -0,0 +1,507 @@ +// +// NotchController.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import SwiftUI +import Combine +import ScreenCaptureKit + + +fileprivate class SettingsWindowDelegate: NSObject, NSWindowDelegate { + var onClose: () -> Void + init(onClose: @escaping () -> Void) { self.onClose = onClose } + func windowWillClose(_ notification: Notification) { onClose() } +} + +struct NotchController: View { + let notchWindow: NSWindow? + + enum NotchState { + case initial, autoExpanded, hoverExpanded, clickExpanded + } + + + @EnvironmentObject var liveActivityManager: LiveActivityManager + @EnvironmentObject var geminiLiveManager: GeminiLiveManager + @EnvironmentObject var pickerHelper: ContentPickerHelper + @EnvironmentObject var settings: SettingsModel + + + @State private var notchState: NotchState = .initial + @State private var isHovered: Bool = false + @State private var collapseTimer: Timer? + @State private var widgetChangeState: Bool = false + @State private var isPinned = false + + + @State private var settingsWindow: NSWindow? + @State private var settingsDelegate: SettingsWindowDelegate? + + + @State private var isGeminiHovered = false + + + @State private var animatedWidth: CGFloat = NotchConfiguration.initialSize.width + @State private var animatedHeight: CGFloat = NotchConfiguration.initialSize.height + @State private var animatedCornerRadius: CGFloat = NotchConfiguration.initialCornerRadius + @State private var shadowOpacity: Double = 0 + + + @State private var measuredClickContentSize: CGSize = .zero + @State private var measuredAutoContentSize: CGSize = .zero + + + @State private var widgetMode: NotchWidgetMode = .defaultWidgets + + + @State private var clickContentOpacity: Double = 0 + @State private var autoContentOpacity: Double = 0 + + + private var isLiveActivityActive: Bool { liveActivityManager.currentActivity != .none } + private var isFullViewActivity: Bool { liveActivityManager.isFullViewActivity } + + private var activeScaleFactor: CGFloat { + guard notchState == .hoverExpanded && !isFullViewActivity else { return 1.0 } + return NotchConfiguration.scaleFactor + } + + public init(notchWindow: NSWindow?) { + self.notchWindow = notchWindow + } + + + var body: some View { + ZStack(alignment: .top) { + CustomNotchShape(cornerRadius: animatedCornerRadius) + .fill(Color.black) + .shadow( + color: NotchConfiguration.expandedShadowColor.opacity(shadowOpacity), + radius: notchState == .clickExpanded ? NotchConfiguration.expandedShadowRadius : 12, + y: notchState == .clickExpanded ? NotchConfiguration.expandedShadowOffset.y : 6 + ) + .onTapGesture(perform: handleTap) + + ZStack(alignment: .top) { + contentView + if notchState == .clickExpanded { + expandedOverlayIcons + .transition(.opacity.animation(.easeInOut(duration: 0.2))) + .zIndex(1) + } + } + .mask(CustomNotchShape(cornerRadius: animatedCornerRadius)) + } + .frame(width: animatedWidth, height: animatedHeight) + .contentShape(CustomNotchShape(cornerRadius: animatedCornerRadius)) + .onHover(perform: handleHover) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .background(measurementView.hidden()) + .onAppear(perform: updateMouseEventHandling) + .onChange(of: liveActivityManager.currentActivity, perform: handleActivityChange) + .onChange(of: notchState, perform: handleStateChange) + .onChange(of: isHovered, perform: { _ in updateMouseEventHandling() }) + .onChange(of: widgetMode, perform: handleWidgetModeChange) + .onChange(of: measuredClickContentSize) { newSize in + if notchState == .clickExpanded { + withAnimation(NotchConfiguration.expandAnimation) { + animatedWidth = newSize.width + animatedHeight = newSize.height + } + } + } + .onChange(of: measuredAutoContentSize) { newSize in + let scale = activeScaleFactor + let targetHeight = newSize.height * scale + let isShrinking = targetHeight < self.animatedHeight + let expandAnimation = (notchState == .hoverExpanded) ? NotchConfiguration.expandAnimation : NotchConfiguration.autoExpandAnimation + let animationToUse = isShrinking ? NotchConfiguration.collapseAnimation : expandAnimation + + if notchState == .autoExpanded || (notchState == .hoverExpanded && isLiveActivityActive) { + withAnimation(animationToUse) { + animatedWidth = newSize.width * scale + animatedHeight = targetHeight + } + } + } + .onReceive(pickerHelper.pickerResultPublisher) { result in + switch result { + case .success(let filter): + geminiLiveManager.startSession(with: filter) + liveActivityManager.startGeminiLive() + case .failure(let error): + if let error = error { + } else { + } + } + } + } + + + + @ViewBuilder + private var contentView: some View { + if notchState == .clickExpanded { + NotchWidgetView(mode: $widgetMode) + .padding(.top, NotchConfiguration.contentTopPadding) + .padding(.bottom, NotchConfiguration.contentBottomPadding) + .padding(.horizontal, NotchConfiguration.contentHorizontalPadding) + .opacity(clickContentOpacity) + .frame(width: animatedWidth, height: animatedHeight) + .clipped() + .allowsHitTesting(true) + } else if isLiveActivityActive && (notchState == .autoExpanded || notchState == .hoverExpanded) { + Group { + autoActivityView + } + .id(liveActivityManager.contentUpdateID) + .transition(.asymmetric( + insertion: .opacity.combined(with: .scale(scale: 0.98, anchor: .top)), + removal: .opacity.combined(with: .scale(scale: 1.02, anchor: .top)) + )) + .animation(NotchConfiguration.autoExpandAnimation, value: liveActivityManager.contentUpdateID) + .opacity(autoContentOpacity) + .scaleEffect(activeScaleFactor) + .animation(NotchConfiguration.expandAnimation, value: notchState) + .frame(width: animatedWidth, height: animatedHeight) + .clipped() + .allowsHitTesting(isHovered) + .transition(.opacity.animation(.easeInOut(duration: 0.2))) + } + } + + @ViewBuilder + private var autoActivityView: some View { + switch liveActivityManager.activityContent { + case .standard(let view, _): + view + case .full(let view, _): + view + case .none: + EmptyView() + } + } + + @ViewBuilder + private var measurementView: some View { + ZStack { + NotchWidgetView(mode: $widgetMode) + .padding(.top, NotchConfiguration.contentTopPadding) + .padding(.bottom, NotchConfiguration.contentBottomPadding) + .padding(.horizontal, NotchConfiguration.contentHorizontalPadding) + .fixedSize() + .background(GeometryReader { geo in Color.clear.onSizeChange(of: geo.size) { measuredClickContentSize = $0 } }) + + autoActivityView + .fixedSize() + .background(GeometryReader { geo in Color.clear.onSizeChange(of: geo.size) { measuredAutoContentSize = $0 } }) + } + } + + @ViewBuilder + private var expandedOverlayIcons: some View { + if widgetMode == .defaultWidgets { + defaultModeIcons + } else { + backButton + } + } + + @ViewBuilder + private var defaultModeIcons: some View { + HStack { + HStack(spacing: 0) { + SubtleIconButton(systemName: "gearshape", action: openSettingsWindow) + if settings.settings.geminiEnabled { geminiButton } + } + Spacer() + HStack(spacing: 0) { + if settings.settings.dropboxIconEnabled { + SubtleIconButton(systemName: "arrow.down.circle", action: { widgetMode = .nearDrop }) + } + if settings.settings.batteryEstimatorEnabled { + SubtleIconButton(systemName: "battery.100", action: { print("Battery tapped") }) + } + if settings.settings.pinEnabled { + SubtleIconButton(systemName: isPinned ? "pin.fill" : "pin", action: { isPinned.toggle(); if isPinned { collapseTimer?.invalidate() } }) + } + } + } + .padding(.horizontal, 40) + .frame(height: NotchConfiguration.initialSize.height) + .frame(width: animatedWidth) + .offset(y: -4) + } + + @ViewBuilder + private var backButton: some View { + HStack { + Button(action: { + withAnimation(NotchConfiguration.expandAnimation) { + widgetMode = .defaultWidgets + } + }) { + + ZStack(alignment: .leading) { + + Rectangle() + .fill(Color.clear) + .frame(width: 100, height: 60) + + + Image(systemName: "chevron.left.circle.fill") + .font(.title2) + .foregroundStyle(.secondary) + .symbolRenderingMode(.hierarchical) + .padding(.leading, 40) + } + } + .buttonStyle(.plain) + + Spacer() + } + .frame(height: NotchConfiguration.initialSize.height) + .frame(width: animatedWidth) + } + + @ViewBuilder + private var geminiButton: some View { + let baseSize: CGFloat = 25 + let geminiGradient = LinearGradient( + gradient: Gradient(colors: [Color.purple.opacity(0.8), Color.indigo.opacity(0.6)]), + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + + Button(action: { + pickerHelper.showPicker() + }) { + HStack(spacing: 4) { + Image(systemName: "sparkle") + .font(.system(size: isGeminiHovered ? 12 : 14, weight: .medium)) + .rotationEffect(.degrees(isGeminiHovered ? 90 : 0)) + .foregroundStyle( + isGeminiHovered ? + LinearGradient(gradient: Gradient(colors: [Color.white, Color.white.opacity(0.5)]), startPoint: .topLeading, endPoint: .bottomTrailing) : + LinearGradient(gradient: Gradient(colors: [Color.blue, Color.pink]), startPoint: .topLeading, endPoint: .bottomTrailing) + ) + .animation(.spring(response: 0.5, dampingFraction: 0.6), value: isGeminiHovered) + + if isGeminiHovered { + Text("Go live") + .font(.system(size: 10, weight: .semibold)) + .fixedSize() + .foregroundColor(.white) + .transition(.opacity.combined(with: .move(edge: .leading))) + } + } + .padding(.horizontal, isGeminiHovered ? 10 : 0) + .frame(width: isGeminiHovered ? nil : baseSize, height: baseSize) + .background(isGeminiHovered ? geminiGradient : nil) + .clipShape(Capsule()) + } + .buttonStyle(.plain) + .onHover { hovering in + withAnimation(.spring(response: 0.5, dampingFraction: 1)) { + isGeminiHovered = hovering + } + } + } + + + + private func handleTap() { + collapseTimer?.invalidate() + if isPinned { return } + + if isLiveActivityActive && (notchState == .autoExpanded || notchState == .hoverExpanded) { + let activityType = liveActivityManager.currentActivity + if activityType == .music, settings.settings.musicOpenOnClick { + notchState = .clickExpanded; widgetMode = .musicPlayer; return + } + if activityType == .weather, settings.settings.weatherOpenOnClick { + notchState = .clickExpanded; widgetMode = .weatherPlayer; return + } + } + + switch notchState { + case .initial, .hoverExpanded, .autoExpanded: notchState = .clickExpanded + case .clickExpanded: notchState = isLiveActivityActive ? .autoExpanded : .initial + } + } + + private func handleHover(hovering: Bool) { + isHovered = hovering + if hovering { + collapseTimer?.invalidate() + if notchState == .initial || notchState == .autoExpanded { + notchState = .hoverExpanded + } + } else if !widgetChangeState { + let delay = (widgetMode == .defaultWidgets) ? 0.0 : NotchConfiguration.collapseDelay + scheduleCollapse(after: delay) + } + } + + private func handleActivityChange(_ newActivity: ActivityType) { + guard notchState != .clickExpanded else { return } + notchState = newActivity != .none ? .autoExpanded : .initial + } + + private func handleStateChange(newState: NotchState) { + updateMouseEventHandling() + + switch newState { + case .initial: + withAnimation(NotchConfiguration.collapseAnimation) { + animatedWidth = NotchConfiguration.initialSize.width + animatedHeight = NotchConfiguration.initialSize.height + animatedCornerRadius = NotchConfiguration.initialCornerRadius + widgetMode = .defaultWidgets + autoContentOpacity = 0 + shadowOpacity = 0 + isPinned = false + } + withAnimation(.easeOut(duration: 0.1)) { clickContentOpacity = 0 } + + case .hoverExpanded: + let scale = activeScaleFactor + let targetWidth = isLiveActivityActive ? measuredAutoContentSize.width * scale : NotchConfiguration.hoverExpandedSize.width + let targetHeight = isLiveActivityActive ? measuredAutoContentSize.height * scale : NotchConfiguration.hoverExpandedSize.height + let targetRadius = (scale > 1.0 && self.isLiveActivityActive) ? NotchConfiguration.autoExpandedCornerRadius : NotchConfiguration.hoverExpandedCornerRadius + + withAnimation(NotchConfiguration.expandAnimation) { + animatedWidth = targetWidth; animatedHeight = targetHeight; animatedCornerRadius = targetRadius + widgetMode = .defaultWidgets + if isLiveActivityActive { autoContentOpacity = 1 } + shadowOpacity = 1 + } + withAnimation(.easeOut(duration: 0.1)) { clickContentOpacity = 0 } + + case .clickExpanded: + withAnimation(NotchConfiguration.expandAnimation) { + animatedWidth = measuredClickContentSize.width + animatedHeight = measuredClickContentSize.height + animatedCornerRadius = NotchConfiguration.clickExpandedCornerRadius + autoContentOpacity = 0 + shadowOpacity = 1 + } + DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { + withAnimation(.easeIn(duration: 0.6)) { clickContentOpacity = 1 } + } + + case .autoExpanded: + let isShrinking = measuredAutoContentSize.height < self.animatedHeight + let animationToUse = isShrinking ? NotchConfiguration.collapseAnimation : NotchConfiguration.autoExpandAnimation + + + withAnimation(animationToUse) { + animatedWidth = measuredAutoContentSize.width + animatedHeight = measuredAutoContentSize.height + animatedCornerRadius = NotchConfiguration.autoExpandedCornerRadius + widgetMode = .defaultWidgets + shadowOpacity = 0 + autoContentOpacity = 1 + } + } + } + + private func handleWidgetModeChange(_ newMode: NotchWidgetMode) { + guard notchState == .clickExpanded else { return } + widgetChangeState = true + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { + widgetChangeState = false + if !isHovered { scheduleCollapse() } + } + } + + private func updateMouseEventHandling() { + let isInteractive = notchState == .clickExpanded || isHovered + notchWindow?.ignoresMouseEvents = !isInteractive + } + + private func scheduleCollapse(after delay: TimeInterval = NotchConfiguration.collapseDelay) { + collapseTimer?.invalidate() + guard !isPinned else { return } + collapseTimer = Timer.scheduledTimer(withTimeInterval: delay, repeats: false) { _ in if !self.isHovered { self.notchState = self.isLiveActivityActive ? .autoExpanded : .initial } } + } + + final class KeyWindow: NSWindow { + override var canBecomeKey: Bool { true } + override var canBecomeMain: Bool { true } + } + + private func openSettingsWindow() { + if let window = settingsWindow { + window.makeKeyAndOrderFront(nil) + NSApp.activate(ignoringOtherApps: true) + return + } + + let newWindow = KeyWindow( + contentRect: NSRect(x: 0, y: 0, width: 950, height: 650), + styleMask: [.borderless, .resizable, .closable], + backing: .buffered, + defer: false + ) + newWindow.center() + newWindow.isMovableByWindowBackground = false + newWindow.backgroundColor = .clear + newWindow.isOpaque = false + newWindow.hasShadow = true + newWindow.isReleasedWhenClosed = false + + let settingsView = SettingsView() + let hostingView = NSHostingView(rootView: settingsView + .environmentObject(settings) + .environment(\.window, newWindow)) + hostingView.autoresizingMask = [.width, .height] + newWindow.contentView = hostingView + + newWindow.makeKeyAndOrderFront(nil) + newWindow.makeFirstResponder(hostingView) + NSApp.activate(ignoringOtherApps: true) + + let delegate = SettingsWindowDelegate { + self.settingsWindow = nil + + } + newWindow.delegate = delegate + self.settingsWindow = newWindow + self.settingsDelegate = delegate + } + +} + +fileprivate struct SubtleIconButton: View { + let systemName: String + let action: () -> Void + @State private var isHovering = false + + var body: some View { + Button(action: action) { + Image(systemName: systemName) + .font(.system(size: 14, weight: .medium)) + .foregroundColor(.white.opacity(isHovering ? 1.0 : 0.7)) + .padding(12) + } + .buttonStyle(.plain) + .contentShape(Circle()) + .onHover { hovering in + withAnimation(.easeInOut(duration: 0.15)) { isHovering = hovering } + } + .scaleEffect(isHovering ? 1.1 : 1.0) + .animation(.spring(response: 0.4, dampingFraction: 0.6), value: isHovering) + } +} + + +fileprivate extension View { + func onSizeChange(of size: CGSize, perform action: @escaping (CGSize) -> Void) -> some View { + self.onAppear { action(size) } + .onChange(of: size) { newSize in action(newSize) } + } +} diff --git a/submissions/sapphire/Sapphire/Sapphire.entitlements b/submissions/sapphire/Sapphire/Sapphire.entitlements new file mode 100644 index 00000000..26a24f31 --- /dev/null +++ b/submissions/sapphire/Sapphire/Sapphire.entitlements @@ -0,0 +1,16 @@ + + + + + com.apple.security.automation.apple-events + + com.apple.security.cs.disable-library-validation + + com.apple.security.device.audio-input + + com.apple.security.personal-information.calendars + + com.apple.security.personal-information.location + + + diff --git a/submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift b/submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift new file mode 100644 index 00000000..05c0f497 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift @@ -0,0 +1,47 @@ +// +// CalendarService.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-28. +// + +import Foundation +import EventKit + +class CalendarService: ObservableObject { + private let eventStore = EKEventStore() + + @Published var nextEvent: EKEvent? + + init() { + requestAccess() + } + + func requestAccess() { + eventStore.requestFullAccessToEvents { [weak self] (granted, error) in + if granted && error == nil { + DispatchQueue.main.async { + self?.fetchNextEvent() + + Timer.scheduledTimer(withTimeInterval: 60 * 5, repeats: true) { _ in + self?.fetchNextEvent() + } + } + } + } + } + + private func fetchNextEvent() { + let calendars = eventStore.calendars(for: .event) + let now = Date() + let oneDayFromNow = Date(timeIntervalSinceNow: 24 * 60 * 60) + + let predicate = eventStore.predicateForEvents(withStart: now, end: oneDayFromNow, calendars: calendars) + + let events = eventStore.events(matching: predicate).filter { !$0.isAllDay } + + DispatchQueue.main.async { + self.nextEvent = events.first + } + } +} diff --git a/submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift b/submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift new file mode 100644 index 00000000..60d2a4a2 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift @@ -0,0 +1,38 @@ +// +// CalendarViewModel.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import Foundation +import SwiftUI + + +class InteractiveCalendarViewModel: ObservableObject { + @Published var dates: [Date] = [] + @Published var selectedDate: Date = Date() + let today: Date = Date() + + var selectedMonthAbbreviated: String { + selectedDate.format(as: "MMM") + } + + init() { + generateDates() + } + + private func generateDates() { + let calendar = Calendar.current + let today = Date() + let dateRange = -90...90 + + self.dates = dateRange.compactMap { dayOffset in + calendar.date(byAdding: .day, value: dayOffset, to: today) + } + } + + func selectDate(_ date: Date) { + self.selectedDate = date + } +} diff --git a/submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift b/submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift new file mode 100644 index 00000000..d346a1aa --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift @@ -0,0 +1,137 @@ +// +// GeminiAPI.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-06. +// + +import Foundation + + +struct GeminiAPI { + static func webSocketURL() -> URL? { + + let settings = SettingsModel() + let apiKey = settings.settings.geminiApiKey + + guard !apiKey.isEmpty else { + return nil + } + + let host = "preprod-generativelanguage.googleapis.com" + let urlString = "wss://\(host)/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent?key=\(apiKey)" + return URL(string: urlString) + } + static let modelName = "models/gemini-2.0-flash-exp" +} + + + + + +enum GeminiWebSocketMessage { + + + + struct Setup: Encodable { + let setup: Payload + struct Payload: Encodable { + let model: String + } + } + + + + struct AudioInput: Encodable { + let realtimeInput: Payload + struct Payload: Encodable { + let mediaChunks: [MediaChunk] + } + struct MediaChunk: Encodable { + let mimeType: String + let data: String + } + } + + + + + struct ContentInput: Encodable { + let clientContent: Payload + + struct Payload: Encodable { + let turns: [Turn] + let turnComplete: Bool + } + + struct Turn: Encodable { + let role: String = "user" + let parts: [Part] + } + + struct Part: Encodable { + let text: String? + let inlineData: InlineData? + + + private enum CodingKeys: String, CodingKey { case text, inlineData } + func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + if let text = text { + try container.encode(text, forKey: .text) + } else if let inlineData = inlineData { + try container.encode(inlineData, forKey: .inlineData) + } + } + + init(text: String) { self.text = text; self.inlineData = nil } + init(inlineData: InlineData) { self.text = nil; self.inlineData = inlineData } + } + + struct InlineData: Encodable { + let mimeType: String + let data: String + } + } +} + + + + +struct ServerSetupComplete: Decodable { + var setupComplete: EmptyObject + struct EmptyObject: Decodable {} +} + +struct ServerAudioOutput: Decodable { + var serverContent: ServerContent + struct ServerContent: Decodable { + var modelTurn: ModelTurn + struct ModelTurn: Decodable { + var parts: [Part] + struct Part: Decodable { + var inlineData: PartInlineData + struct PartInlineData: Decodable { var data: String } + } + } + } +} + +struct ServerInterrupted: Decodable { + var serverContent: ServerContent + struct ServerContent: Decodable { + var interrupted: Bool + } +} + +struct ServerTurnComplete: Decodable { + var serverContent: ServerContent + struct ServerContent: Decodable { + var turnComplete: Bool + } + var usageMetadata: UsageMetadata + struct UsageMetadata: Decodable { + var promptTokenCount: Int + var responseTokenCount: Int + } +} diff --git a/submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift b/submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift new file mode 100644 index 00000000..ba7ae244 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift @@ -0,0 +1,42 @@ +// +// GeminiLive.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import SwiftUI +import AppKit +import CoreGraphics + + + + +struct GeminiActiveActivityViewRight: View { + let isMuted: Bool + let action: () -> Void + + var body: some View { + Button(action: action) { + Image(systemName: isMuted ? "mic.slash.fill" : "mic.fill") + .font(.system(size: 14)) + .foregroundStyle(isMuted ? .white.opacity(0.7) : .red) + .contentTransition(.symbolEffect(.replace)) + } + .buttonStyle(.plain) + .foregroundStyle(.white.opacity(0.9)) + } +} + +struct GeminiActiveActivityView { + static func left() -> some View { + Image(systemName: "sparkle") + .font(.system(size: 18, weight: .semibold)) + .foregroundStyle(.purple) + } + + + static func right(isMuted: Bool, action: @escaping () -> Void) -> some View { + GeminiActiveActivityViewRight(isMuted: isMuted, action: action) + } +} diff --git a/submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift b/submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift new file mode 100644 index 00000000..51d7f8b9 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift @@ -0,0 +1,432 @@ +// +// GeminiLiveManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import Foundation +import ScreenCaptureKit +import AVFoundation +import Combine +import CoreImage +import AppKit + +@MainActor +class GeminiLiveManager: NSObject, ObservableObject, SCStreamOutput, SCStreamDelegate { + + @Published var isSessionRunning = false + @Published var isMicMuted = true { + didSet { + } + } + + + private var webSocketTask: URLSessionWebSocketTask? + private let urlSession = URLSession(configuration: .default) + private var sessionTask: Task? + + + private let playbackEngine = AVAudioEngine() + private var captureEngine: AVAudioEngine? + private let audioPlayer = AVAudioPlayerNode() + private let geminiAudioFormat = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 24000, channels: 1, interleaved: false)! + private var playerAudioFormat: AVAudioFormat! + private var audioConverter_Playback: AVAudioConverter! + private let audioProcessingQueue = DispatchQueue(label: "com.sapphire.AudioProcessingQueue") + + + private var isSendingUserAudio = false + private let vadThreshold: Float = 0.01 + + + private var stream: SCStream? + private let videoFrameOutputQueue = DispatchQueue(label: "com.sapphire.VideoOutputQueue") + private let imageContext = CIContext() + + let sessionDidEndPublisher = PassthroughSubject() + + override init() { + super.init() + setupPlaybackEngine() + } + + func startSession(with filter: SCContentFilter) { + guard !isSessionRunning else { return } + isSessionRunning = true + isMicMuted = true + isSendingUserAudio = false + + guard let url = GeminiAPI.webSocketURL() else { + isSessionRunning = false + return + } + + webSocketTask = self.urlSession.webSocketTask(with: url) + + sessionTask = Task { + do { + if !self.playbackEngine.isRunning { + try self.playbackEngine.start() + if !self.audioPlayer.isPlaying { self.audioPlayer.play() } + } + + try self.startCaptureAudio() + + webSocketTask?.resume() + + try await Task.sleep(for: .milliseconds(100)) + + try await self.sendSetupMessage() + + try await withThrowingTaskGroup(of: Void.self) { group in + group.addTask { try await self.receiveMessages() } + group.addTask { try await self.captureAndSendScreen(with: filter) } + try await group.waitForAll() + } + + } catch { + if !(error is CancellationError) { + } + await self.cleanupSession() + } + } + } + + public func signalEndOfUserTurn() { + Task { + do { + + self.isMicMuted = true + self.isSendingUserAudio = false + + let finalPart = GeminiWebSocketMessage.ContentInput.Part(text: "That's all, please respond based on what you've seen and heard.") + let turn = GeminiWebSocketMessage.ContentInput.Turn(parts: [finalPart]) + let payload = GeminiWebSocketMessage.ContentInput.Payload(turns: [turn], turnComplete: true) + let message = GeminiWebSocketMessage.ContentInput(clientContent: payload) + try await send(message: message) + } catch { + } + } + } + + func stopSession() async { + sessionTask?.cancel() + await cleanupSession() + } + + private func cleanupSession() async { + if isSessionRunning { + isSessionRunning = false + webSocketTask?.cancel(with: .goingAway, reason: nil) + webSocketTask = nil + + if let stream = stream { try? await stream.stopCapture() } + stream = nil + + stopCaptureAudio() + + audioPlayer.stop() + audioPlayer.reset() + playbackEngine.stop() + playbackEngine.reset() + + sessionDidEndPublisher.send() + } + } + + + + private func send(message: T) async throws { + guard let webSocketTask = webSocketTask, webSocketTask.closeCode == .invalid else { + return + } + + let encoder = JSONEncoder() + let jsonData = try encoder.encode(message) + guard let jsonString = String(data: jsonData, encoding: .utf8) else { return } + + try await webSocketTask.send(.string(jsonString)) + } + + private func sendSetupMessage() async throws { + let payload = GeminiWebSocketMessage.Setup.Payload(model: GeminiAPI.modelName) + let message = GeminiWebSocketMessage.Setup(setup: payload) + try await send(message: message) + } + + private func sendContentPart(_ part: GeminiWebSocketMessage.ContentInput.Part) async throws { + let turn = GeminiWebSocketMessage.ContentInput.Turn(parts: [part]) + let payload = GeminiWebSocketMessage.ContentInput.Payload(turns: [turn], turnComplete: false) + let message = GeminiWebSocketMessage.ContentInput(clientContent: payload) + try await send(message: message) + } + + private func receiveMessages() async throws { + guard let webSocketTask = webSocketTask else { return } + + while !Task.isCancelled { + do { + let message = try await webSocketTask.receive() + switch message { + case .data(let data): + try self.handleReceivedJSONData(data) + case .string(let text): + try self.handleReceivedJSONData(Data(text.utf8)) + @unknown default: + fatalError("Received unknown WebSocket message type.") + } + } catch { + if !Task.isCancelled { + await cleanupSession() + } + break + } + } + } + + private func handleReceivedJSONData(_ data: Data) throws { + let decoder = JSONDecoder() + if (try? decoder.decode(ServerSetupComplete.self, from: data)) != nil { + Task { + let initialPart = GeminiWebSocketMessage.ContentInput.Part(text: "Please say 'Hi, what can I help you with?'") + let turn = GeminiWebSocketMessage.ContentInput.Turn(parts: [initialPart]) + let payload = GeminiWebSocketMessage.ContentInput.Payload(turns: [turn], turnComplete: true) + let message = GeminiWebSocketMessage.ContentInput(clientContent: payload) + try await self.send(message: message) + } + } else if let audioOutput = try? decoder.decode(ServerAudioOutput.self, from: data), + let audioDataB64 = audioOutput.serverContent.modelTurn.parts.first?.inlineData.data, + let audioData = Data(base64Encoded: audioDataB64) { + self.playAudioData(audioData) + + } else if let interruptedMessage = try? decoder.decode(ServerInterrupted.self, from: data), + interruptedMessage.serverContent.interrupted { + self.stopAndClearPlayback() + + } else if let turnComplete = try? decoder.decode(ServerTurnComplete.self, from: data) { + if turnComplete.serverContent.turnComplete { + + self.isMicMuted = false + self.isSendingUserAudio = false + } + } else { + let jsonString = String(data: data, encoding: .utf8) ?? "Undecodable binary" + } + } + + + + private func setupPlaybackEngine() { + playerAudioFormat = AVAudioFormat(standardFormatWithSampleRate: geminiAudioFormat.sampleRate, channels: geminiAudioFormat.channelCount)! + audioConverter_Playback = AVAudioConverter(from: geminiAudioFormat, to: playerAudioFormat)! + playbackEngine.attach(audioPlayer) + playbackEngine.connect(audioPlayer, to: playbackEngine.outputNode, format: playerAudioFormat) + playbackEngine.prepare() + } + + private func playAudioData(_ data: Data) { + guard let geminiBuffer = data.toPCMBuffer(format: geminiAudioFormat) else { return } + let playerBuffer = AVAudioPCMBuffer(pcmFormat: playerAudioFormat, frameCapacity: geminiBuffer.frameCapacity)! + isMicMuted = true + do { + try audioConverter_Playback.convert(to: playerBuffer, from: geminiBuffer) + if !playbackEngine.isRunning { try playbackEngine.start() } + if !audioPlayer.isPlaying { audioPlayer.play() } + audioPlayer.scheduleBuffer(playerBuffer) + } catch { print("[ERROR] Playback audio conversion error: \(error)") } + } + + private func stopAndClearPlayback() { + isMicMuted = false + audioPlayer.stop() + audioPlayer.reset() + } + + private func startCaptureAudio() throws { + captureEngine = AVAudioEngine() + + guard let captureEngine = captureEngine else { return } + + let inputNode = captureEngine.inputNode + + + + + + + + + + + + + let sourceFormat = inputNode.outputFormat(forBus: 0) + let targetFormat = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 48000, channels: 1, interleaved: false)! + + guard let converter = AVAudioConverter(from: sourceFormat, to: targetFormat) else { + throw NSError(domain: "GeminiLiveManager", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to create audio converter"]) + } + + inputNode.installTap(onBus: 0, bufferSize: 1024, format: sourceFormat) { [weak self] inputBuffer, _ in + guard let self = self else { return } + self.audioProcessingQueue.async { + guard self.isSessionRunning, !self.isMicMuted else { return } + + + if self.isSendingUserAudio { + + self.convertAndSend(buffer: inputBuffer, using: converter) + } else { + + let level = self.calculateRMSAudioLevel(fromBuffer: inputBuffer) + if level > self.vadThreshold { + self.isSendingUserAudio = true + self.convertAndSend(buffer: inputBuffer, using: converter) + } + } + } + } + captureEngine.prepare() + try captureEngine.start() + } + + private func convertAndSend(buffer: AVAudioPCMBuffer, using converter: AVAudioConverter) { + let targetFormat = converter.outputFormat + let ratio = targetFormat.sampleRate / buffer.format.sampleRate + let outputFrameCount = AVAudioFrameCount(ceil(Double(buffer.frameLength) * ratio)) + + guard let outputBuffer = AVAudioPCMBuffer(pcmFormat: targetFormat, frameCapacity: outputFrameCount) else { + return + } + + var error: NSError? + var providedInput = false + + let inputBlock: AVAudioConverterInputBlock = { _, outStatus in + if providedInput { + outStatus.pointee = .noDataNow + return nil + } + outStatus.pointee = .haveData + providedInput = true + return buffer + } + + let status = converter.convert(to: outputBuffer, error: &error, withInputFrom: inputBlock) + + + if status == .error { + if let e = error { + } + return + } + + + guard let pcmData = outputBuffer.toData(), !pcmData.isEmpty else { return } + + let base64String = pcmData.base64EncodedString() + let chunk = GeminiWebSocketMessage.AudioInput.MediaChunk(mimeType: "audio/pcm;rate=16000", data: base64String) + let payload = GeminiWebSocketMessage.AudioInput.Payload(mediaChunks: [chunk]) + let message = GeminiWebSocketMessage.AudioInput(realtimeInput: payload) + + Task { + do { + try await self.send(message: message) + } catch { + } + } + } + + private func stopCaptureAudio() { + guard let captureEngine = captureEngine else { return } + captureEngine.stop() + captureEngine.inputNode.removeTap(onBus: 0) + self.captureEngine = nil + } + + + + private func captureAndSendScreen(with filter: SCContentFilter) async throws { + let config = SCStreamConfiguration() + config.width = 1024; config.height = 768 + config.minimumFrameInterval = CMTime(value: 1, timescale: 1) + config.queueDepth = 5 + stream = SCStream(filter: filter, configuration: config, delegate: self) + try stream?.addStreamOutput(self, type: .screen, sampleHandlerQueue: videoFrameOutputQueue) + try await stream?.startCapture() + } + + func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) { + guard type == .screen, sampleBuffer.isValid, isSessionRunning else { return } + guard let pixelBuffer = sampleBuffer.imageBuffer else { return } + + let ciImage = CIImage(cvPixelBuffer: pixelBuffer) + guard let cgImage = imageContext.createCGImage(ciImage, from: ciImage.extent), + let jpegData = NSBitmapImageRep(cgImage: cgImage).representation(using: .jpeg, properties: [.compressionFactor: 0.7]) else { return } + + let base64String = jpegData.base64EncodedString() + let inlineData = GeminiWebSocketMessage.ContentInput.InlineData(mimeType: "image/jpeg", data: base64String) + let part = GeminiWebSocketMessage.ContentInput.Part(inlineData: inlineData) + + Task { + try? await self.sendContentPart(part) + } + } + + func stream(_ stream: SCStream, didStopWithError error: Error) { + Task { await cleanupSession() } + } + + + private func calculateRMSAudioLevel(fromBuffer buffer: AVAudioPCMBuffer) -> Float { + guard let floatChannelData = buffer.floatChannelData else { + + + return 0.0 + } + + let channelCount = Int(buffer.format.channelCount) + let frameLength = Int(buffer.frameLength) + + var rms: Float = 0.0 + for channel in 0.. AVAudioPCMBuffer? { + let frameCapacity = UInt32(self.count) / format.streamDescription.pointee.mBytesPerFrame + guard frameCapacity > 0, let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: frameCapacity) else { return nil } + buffer.frameLength = frameCapacity + self.withUnsafeBytes { srcBuffer in + if let baseAddress = srcBuffer.baseAddress, let dest = buffer.int16ChannelData?[0] { + memcpy(dest, baseAddress, self.count) + } + } + return buffer + } +} + +fileprivate extension AVAudioPCMBuffer { + func toData() -> Data? { + + let frameLength = Int(self.frameLength) + let channelCount = Int(self.format.channelCount) + let bytesPerFrame = Int(self.format.streamDescription.pointee.mBytesPerFrame) + let dataSize = frameLength * bytesPerFrame + + guard dataSize > 0, channelCount == 1, let channelData = self.int16ChannelData else { return nil } + + return Data(bytes: channelData[0], count: dataSize) + } +} diff --git a/submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift b/submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift new file mode 100644 index 00000000..5e55b5cb --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift @@ -0,0 +1,149 @@ +// +// LyricsFetcher.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import Foundation + +class LyricsFetcher { + + + func fetchSyncedLyrics(for title: String, artist: String, album: String) async -> [LyricLine]? { + + var components = URLComponents(string: "https://lrclib.net/api/get")! + components.queryItems = [ + URLQueryItem(name: "track_name", value: title), + URLQueryItem(name: "artist_name", value: artist), + URLQueryItem(name: "album_name", value: album) + ] + + guard let url = components.url else { return nil } + + do { + let (data, _) = try await URLSession.shared.data(from: url) + + struct LrcLibResponse: Decodable { + let syncedLyrics: String? + } + + let response = try JSONDecoder().decode(LrcLibResponse.self, from: data) + + if let lrcString = response.syncedLyrics, !lrcString.isEmpty { + return parseLRC(lrcString) + } else { + return nil + } + } catch { + return nil + } + } + + private func parseLRC(_ lrcString: String) -> [LyricLine] { + var lyrics: [LyricLine] = [] + let lines = lrcString.components(separatedBy: .newlines) + + for line in lines { + if line.hasPrefix("[") && line.contains("]") { + let components = line.components(separatedBy: "]") + if components.count > 1 { + let timestampString = String(components[0].dropFirst()) + let text = components[1].trimmingCharacters(in: .whitespaces) + + let timeComponents = timestampString.components(separatedBy: ":") + if timeComponents.count == 2, + let minutes = Double(timeComponents[0]), + let seconds = Double(timeComponents[1]) { + + let timestamp = (minutes * 60) + seconds + lyrics.append(LyricLine(text: text, timestamp: timestamp)) + } + } + } + } + return lyrics.sorted { $0.timestamp < $1.timestamp } + } + + + func detectLanguage(for text: String) async -> String? { + + let trimmedText = text.trimmingCharacters(in: .whitespacesAndNewlines) + guard !trimmedText.isEmpty else { + return nil + } + + var components = URLComponents(string: "https://translate.googleapis.com/translate_a/single")! + components.queryItems = [ + URLQueryItem(name: "client", value: "gtx"), + URLQueryItem(name: "sl", value: "auto"), + URLQueryItem(name: "tl", value: "en"), + URLQueryItem(name: "dt", value: "t"), + URLQueryItem(name: "q", value: trimmedText.prefix(500).description) + ] + + guard let url = components.url else { return nil } + + struct UnofficialGoogleDetectionResponse: Decodable { + let detectedLanguage: String? + init(from decoder: Decoder) throws { + var container = try decoder.unkeyedContainer() + _ = try? container.nestedUnkeyedContainer() + _ = try? container.decode(String?.self) + self.detectedLanguage = try? container.decode(String.self) + } + } + + do { + let (data, _) = try await URLSession.shared.data(from: url) + let unofficialResponse = try JSONDecoder().decode(UnofficialGoogleDetectionResponse.self, from: data) + if let lang = unofficialResponse.detectedLanguage { + return lang + } + } catch { + } + return nil + } + + + func translate(lyrics: inout [LyricLine], from sourceLanguage: String, to targetLanguage: String) async { + + struct UnofficialGoogleTranslateResponse: Decodable { + let translatedText: String? + init(from decoder: Decoder) throws { + var container = try decoder.unkeyedContainer() + if var outerArray = try? container.nestedUnkeyedContainer(), + var firstInnerArray = try? outerArray.nestedUnkeyedContainer() { + self.translatedText = try? firstInnerArray.decode(String.self) + } else { + self.translatedText = nil + } + } + } + + for i in 0..() + + + @Published var title: String? + @Published var artist: String? + @Published var album: String? + @Published var artwork: NSImage? + @Published var isPlaying: Bool = false + @Published var playbackProgress: Double = 0.0 + @Published var currentElapsedTime: TimeInterval = 0 + @Published var totalDuration: TimeInterval = 0 + @Published var lyrics: [LyricLine] = [] + @Published var currentLyric: LyricLine? + @Published var accentColor: Color = .white + @Published var leftGradientColor: Color = .white + @Published var rightGradientColor: Color = .white + @Published var appIcon: NSImage? + @Published var systemVolume: Float = 0.0 + @Published var isDisplayingTransientIcon: Bool = false + @Published var shouldShowLiveActivity: Bool = false + + + @Published var lyricsTapped: Bool = false + + + private var volumeListener: AudioObjectPropertyListenerBlock? + private var currentTrackDuration: TimeInterval = 0 + private var lastFetchedTitle: String? + private var lastKnownBundleID: String? + private var cancellables = Set() + private var justSkipped = false + private var skipDebounceTimer: Timer? + + init() { + setupHandlers() + setupNotificationObservers() + setupVolumeListener() + setupDerivedStatePublisher() + mediaController.startListening() + } + + deinit { + mediaController.stop() + removeVolumeListener() + NotificationCenter.default.removeObserver(self) + skipDebounceTimer?.invalidate() + } + + private func setupDerivedStatePublisher() { + Publishers.CombineLatest($isPlaying, $isDisplayingTransientIcon) + .map { isPlaying, isDisplayingIcon in return isPlaying || isDisplayingIcon } + .removeDuplicates().assign(to: \.shouldShowLiveActivity, on: self).store(in: &cancellables) + } + + private func setupNotificationObservers() { + NotificationCenter.default.addObserver(self, selector: #selector(handlePlayPause), name: .mediaKeyPlayPausePressed, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(handleNextTrack), name: .mediaKeyNextPressed, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(handlePreviousTrack), name: .mediaKeyPreviousPressed, object: nil) + } + + private func setupHandlers() { + mediaController.onTrackInfoReceived = { [weak self] trackInfo in + guard let self = self else { return } + let payload = trackInfo.payload + DispatchQueue.main.async { + let hasTrackChanged = payload.title != self.lastFetchedTitle + self.title = payload.title; self.artist = payload.artist; self.album = payload.album + if let newArtwork = payload.artwork { + self.artwork = newArtwork + if let edgeColors = newArtwork.getEdgeColors() { self.accentColor = edgeColors.accent; self.leftGradientColor = edgeColors.left; self.rightGradientColor = edgeColors.right } + else { self.resetColorsToDefault() } + } else { self.artwork = nil; self.resetColorsToDefault() } + if let newIsPlaying = payload.isPlaying { + if self.isPlaying && !newIsPlaying { self.playerActionPublisher.send(.paused) } + else if !self.isPlaying && newIsPlaying { self.playerActionPublisher.send(.played) } + self.isPlaying = newIsPlaying + } + self.currentTrackDuration = TimeInterval(payload.durationMicros ?? 0) / 1_000_000 + self.totalDuration = self.currentTrackDuration + if hasTrackChanged { + self.lastFetchedTitle = payload.title + self.fetchAndTranslateLyricsIfNeeded() + if !self.justSkipped { self.playerActionPublisher.send(.trackChanged) } + } + if payload.bundleIdentifier != self.lastKnownBundleID { + self.lastKnownBundleID = payload.bundleIdentifier + self.fetchAppIcon(for: payload.bundleIdentifier) + } + } + } + mediaController.onPlaybackTimeUpdate = { [weak self] elapsedTime in + guard let self = self, self.currentTrackDuration > 0 else { return } + DispatchQueue.main.async { + self.playbackProgress = max(0.0, min(1.0, elapsedTime / self.currentTrackDuration)) + self.currentElapsedTime = elapsedTime + self.updateCurrentLyric(for: elapsedTime) + } + } + mediaController.onListenerTerminated = { print("[MusicWidget] Error: The media listener process was terminated.") } + mediaController.onDecodingError = { error, data in print("[MusicWidget] Decoding Error: \(error)") } + } + + private func setupVolumeListener() { + self.systemVolume = SystemControl.getVolume() + guard let deviceID = getDefaultOutputDeviceID() else { return } + var address = AudioObjectPropertyAddress(mSelector: kAudioDevicePropertyVolumeScalar, mScope: kAudioObjectPropertyScopeOutput, mElement: kAudioObjectPropertyElementMain) + self.volumeListener = { [weak self] _, _ in DispatchQueue.main.async { self?.systemVolume = SystemControl.getVolume() } } + AudioObjectAddPropertyListenerBlock(deviceID, &address, nil, self.volumeListener!) + } + + private func removeVolumeListener() { + guard let deviceID = getDefaultOutputDeviceID(), let listener = self.volumeListener else { return } + var address = AudioObjectPropertyAddress(mSelector: kAudioDevicePropertyVolumeScalar, mScope: kAudioObjectPropertyScopeOutput, mElement: kAudioObjectPropertyElementMain) + AudioObjectRemovePropertyListenerBlock(deviceID, &address, nil, listener) + } + + private func getDefaultOutputDeviceID() -> AudioDeviceID? { + var deviceID: AudioDeviceID = kAudioObjectUnknown, size = UInt32(MemoryLayout.size) + var address = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDefaultOutputDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMain) + return AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &address, 0, nil, &size, &deviceID) == noErr ? deviceID : nil + } + + private func fetchAppIcon(for bundleIdentifier: String?) { + guard let bundleId = bundleIdentifier, !bundleId.isEmpty, let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleId) else { DispatchQueue.main.async { self.appIcon = nil }; return } + DispatchQueue.main.async { self.appIcon = NSWorkspace.shared.icon(forFile: url.path) } + } + + private func fetchAndTranslateLyricsIfNeeded() { + guard let title = self.title, let artist = self.artist, let album = self.album else { return } + self.lyrics = []; self.currentLyric = nil + Task { + guard var fetchedLyrics = await lyricsFetcher.fetchSyncedLyrics(for: title, artist: artist, album: album), !fetchedLyrics.isEmpty else { return } + await MainActor.run { self.lyrics = fetchedLyrics } + let sampleText = fetchedLyrics.prefix(5).map { $0.text }.joined(separator: " ") + guard !sampleText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty, let lang = await lyricsFetcher.detectLanguage(for: sampleText) else { return } + if lang != "en" { await lyricsFetcher.translate(lyrics: &fetchedLyrics, from: lang, to: "en"); await MainActor.run { self.lyrics = fetchedLyrics } } + } + } + + private func updateCurrentLyric(for elapsedTime: TimeInterval) { + let newLyric = lyrics.last { $0.timestamp <= elapsedTime } + if newLyric?.id != self.currentLyric?.id { self.currentLyric = newLyric } + } + + private func resetColorsToDefault() { + let defaultAccent = Color(red: 0.53, green: 0.73, blue: 0.88) + self.accentColor = defaultAccent; self.leftGradientColor = defaultAccent; self.rightGradientColor = defaultAccent.opacity(0.7) + } + + private func handleSkipAction(isForward: Bool) { + justSkipped = true + skipDebounceTimer?.invalidate() + skipDebounceTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] _ in self?.justSkipped = false } + if isForward { mediaController.nextTrack() } + else { mediaController.previousTrack() } + } + + + func play() { mediaController.play(); playerActionPublisher.send(.played) } + func pause() { mediaController.pause(); playerActionPublisher.send(.paused) } + func nextTrack() { handleSkipAction(isForward: true) } + func previousTrack() { handleSkipAction(isForward: false) } + func seek(to seconds: Double) { mediaController.setTime(seconds: seconds) } + + + @objc private func handlePlayPause() { isPlaying ? pause() : play() } + @objc private func handleNextTrack() { nextTrack() } + @objc private func handlePreviousTrack() { previousTrack() } +} diff --git a/submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift b/submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift new file mode 100644 index 00000000..39c5db7e --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift @@ -0,0 +1,137 @@ +// +// SystemAudioMonitor.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-01. +// + +import Foundation +import AVFoundation +import Combine +import CoreAudio +import Accelerate + +class SystemAudioMonitor: ObservableObject { + @Published var audioLevel: Float = 0.0 + + private let engine = AVAudioEngine() + private var isMonitoring = false + + init() {} + + func start() { + guard !isMonitoring else { return } + setupAndStartEngine() + } + + func stop() { + guard isMonitoring else { return } + engine.inputNode.removeTap(onBus: 0) + engine.stop() + isMonitoring = false + } + + private func setupAndStartEngine() { + let inputNode = engine.inputNode + + guard let blackHoleDeviceID = findBlackHoleDeviceID() else { + return + } + + do { + var deviceID = blackHoleDeviceID + guard let audioUnit = inputNode.audioUnit else { + print("[SystemAudioMonitor] ❌ Could not get AudioUnit for input node."); return + } + let error = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceID, UInt32(MemoryLayout.size)) + if error != noErr { + print("[SystemAudioMonitor] ❌ Failed to set input device. Error: \(error)"); return + } + try engine.start() + } catch { + print("[SystemAudioMonitor] ❌ Failed to start audio engine: \(error.localizedDescription)"); return + } + + inputNode.installTap(onBus: 0, bufferSize: 1024, format: inputNode.outputFormat(forBus: 0)) { [weak self] buffer, _ in + let level = self?.calculateRMS(from: buffer) ?? 0.0 + DispatchQueue.main.async { self?.audioLevel = level } + } + + isMonitoring = true + } + + private func findBlackHoleDeviceID() -> AudioDeviceID? { + var deviceID: AudioDeviceID = 0 + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioHardwarePropertyDefaultInputDevice, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMain + ) + var propertySize = UInt32(MemoryLayout.size) + + let status = AudioObjectGetPropertyData( + AudioObjectID(kAudioObjectSystemObject), + &propertyAddress, + 0, + nil, + &propertySize, + &deviceID + ) + + if status == noErr, let deviceName = getDeviceName(deviceID), deviceName.contains("BlackHole") { + return deviceID + } + + + var devicesPropertyAddress = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDevices, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMain) + var devicesPropertySize: UInt32 = 0 + guard AudioObjectGetPropertyDataSize(AudioObjectID(kAudioObjectSystemObject), &devicesPropertyAddress, 0, nil, &devicesPropertySize) == noErr else { return nil } + + let deviceCount = Int(devicesPropertySize) / MemoryLayout.size + var deviceIDs = [AudioDeviceID](repeating: 0, count: deviceCount) + guard AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &devicesPropertyAddress, 0, nil, &devicesPropertySize, &deviceIDs) == noErr else { return nil } + + for id in deviceIDs { + if let name = getDeviceName(id), name.contains("BlackHole") { + return id + } + } + + return nil + } + + private func getDeviceName(_ deviceID: AudioDeviceID) -> String? { + var name: CFString = "" as CFString + var propertySize = UInt32(MemoryLayout.size) + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyDeviceNameCFString, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMain + ) + guard AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &name) == noErr else { return nil } + return name as String + } + + + private func calculateRMS(from buffer: AVAudioPCMBuffer) -> Float { + guard let channelData = buffer.floatChannelData else { return 0 } + let frameLength = Int(buffer.frameLength) + guard frameLength > 0 else { return 0 } + + let channelCount = Int(buffer.format.channelCount) + var rms: Float = 0.0 + + for channel in 0.. some View { + let lowHeight = minHeight + (maxHeight - minHeight) * low + let highHeight = minHeight + (maxHeight - minHeight) * high + + return Capsule() + .fill(musicWidget.accentColor) + .shadow(color: musicWidget.accentColor.opacity(0.6), radius: 4, y: 2) + .frame(height: drawingHeight ? highHeight : lowHeight) + // Align to center for symmetrical expansion + .frame(height: maxHeight, alignment: .center) + } + + private var staticWaveformBody: some View { + HStack(spacing: 3) { + ForEach(0.. some View { + Image(systemName: systemName) + .font(.system(size: 16, weight: .semibold)) + .foregroundColor(musicWidget.accentColor) + .transition(.opacity.animation(.easeOut(duration: 0.2))) + } +} diff --git a/submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift b/submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift new file mode 100644 index 00000000..22033121 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift @@ -0,0 +1,338 @@ +// +// SpotifyAPIManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import Foundation +import Combine +import AppKit + + +enum PlaybackResult { + case success + case failure(reason: String) + case requiresPremium + case requiresSpotifyAppOpen +} + +class SpotifyAPIManager: ObservableObject { + static let shared = SpotifyAPIManager() + + + private var clientId = "79b4d096a6f8415f8c7fc678647f4482" + private var clientSecret = "fe9a27b5e3324a949d94f67ecc86d791" + private let redirectURI = "sapphire://callback" + + @Published var isAuthenticated = false + @Published var userProfile: UserProfile? + @Published var isPremiumUser = false + + private var accessToken: String? + private var refreshToken: String? + + private let settingsModel = SettingsModel() + + private init() { + clientId = settingsModel.settings.spotifyClientId + clientSecret = settingsModel.settings.spotifyClientSecret + } + + + + func login() { + + let scope = "user-read-playback-state user-modify-playback-state user-read-currently-playing playlist-read-private user-read-private" + + var components = URLComponents(string: "https://accounts.spotify.com/authorize")! + components.queryItems = [ + URLQueryItem(name: "response_type", value: "code"), + URLQueryItem(name: "client_id", value: clientId), + URLQueryItem(name: "scope", value: scope), + URLQueryItem(name: "redirect_uri", value: redirectURI), + ] + guard let url = components.url else { return } + NSWorkspace.shared.open(url) + } + + func handleRedirect(url: URL) { + guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true), + let code = components.queryItems?.first(where: { $0.name == "code" })?.value else { + return + } + Task { await self.exchangeCodeForToken(code: code) } + } + + private struct TokenResponse: Decodable { + let accessToken: String, refreshToken: String?, expiresIn: Int + enum CodingKeys: String, CodingKey { case accessToken = "access_token", refreshToken = "refresh_token", expiresIn = "expires_in" } + } + + private func exchangeCodeForToken(code: String) async { + guard let url = URL(string: "https://accounts.spotify.com/api/token") else { return } + var request = URLRequest(url: url) + request.httpMethod = "POST" + var components = URLComponents() + components.queryItems = [ + URLQueryItem(name: "grant_type", value: "authorization_code"), + URLQueryItem(name: "code", value: code), + URLQueryItem(name: "redirect_uri", value: redirectURI), + ] + request.httpBody = components.query?.data(using: .utf8) + let authHeader = "\(clientId):\(clientSecret)".data(using: .utf8)!.base64EncodedString() + request.setValue("Basic \(authHeader)", forHTTPHeaderField: "Authorization") + request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") + + do { + let (data, _) = try await URLSession.shared.data(for: request) + let tokenResponse = try JSONDecoder().decode(TokenResponse.self, from: data) + await MainActor.run { + self.accessToken = tokenResponse.accessToken + self.refreshToken = tokenResponse.refreshToken + self.isAuthenticated = true + Task { await self.fetchUserProfile() } + } + } catch { print("--> TOKEN ERROR: \(error)") } + } + + + private func makeAPIRequest(url: URL, method: String = "GET", body: Data? = nil) async -> T? { + guard isAuthenticated, let token = accessToken else { + return nil + } + + + #if DEBUG + if url.path.contains("audio-analysis") { + } + #endif + + var request = URLRequest(url: url) + request.httpMethod = method + request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization") + if let body = body { request.httpBody = body; request.addValue("application/json", forHTTPHeaderField: "Content-Type") } + + do { + let (data, response) = try await URLSession.shared.data(for: request) + + guard let httpResponse = response as? HTTPURLResponse else { + return nil + } + + if (200...299).contains(httpResponse.statusCode) && url.path.contains("audio-analysis") { + } else if let jsonString = String(data: data, encoding: .utf8), !jsonString.isEmpty { + } + + guard (200...299).contains(httpResponse.statusCode) else { + if httpResponse.statusCode == 403 && url.path.contains("audio-analysis") { + } else { + let errorBody = String(data: data, encoding: .utf8) ?? "No error body" + } + return nil + } + + if data.isEmpty, T.self == Bool.self { return true as? T } + return try JSONDecoder().decode(T.self, from: data) + } catch { + return nil + } + } + + + private func isSpotifyAppRunning() -> Bool { + return NSWorkspace.shared.runningApplications.contains { $0.bundleIdentifier == "com.spotify.client" } + } + + private func runAppleScript(_ script: String) -> Bool { + guard isSpotifyAppRunning() else { return false } + var error: NSDictionary? + if let scriptObject = NSAppleScript(source: script) { + scriptObject.executeAndReturnError(&error) + if let err = error { print("--> AppleScript Error: \(err)"); return false } + return true + } + return false + } + + func getLocalVolume() -> Int? { + guard isSpotifyAppRunning() else { return nil } + let script = "if application \"Spotify\" is running then tell application \"Spotify\" to get sound volume" + var error: NSDictionary? + if let scriptObject = NSAppleScript(source: script) { + let result = scriptObject.executeAndReturnError(&error) + if error == nil, let volume = result.int32Value as? Int { + return volume + } + } + return nil + } + + + + private struct PlayBody: Encodable { var context_uri: String? = nil; var uris: [String]? = nil } + private struct TransferPlaybackBody: Encodable { let device_ids: [String]; let play: Bool } + + func fetchUserProfile() async { + guard isAuthenticated, let url = URL(string: "https://api.spotify.com/v1/me") else { return } + let profile: UserProfile? = await makeAPIRequest(url: url) + await MainActor.run { + self.userProfile = profile + self.isPremiumUser = (profile?.product == "premium") + } + } + + func playTrack(uri: String) async -> PlaybackResult { + if isPremiumUser { + guard let url = URL(string: "https://api.spotify.com/v1/me/player/play") else { return .failure(reason: "Invalid URL") } + let body = PlayBody(uris: [uri]) + guard let bodyData = try? JSONEncoder().encode(body) else { return .failure(reason: "Encoding failed") } + let success: Bool? = await makeAPIRequest(url: url, method: "PUT", body: bodyData) + return success == true ? .success : .failure(reason: "API request failed") + } else { + if isSpotifyAppRunning() { + guard let url = URL(string: uri) else { return .failure(reason: "Invalid URI") } + await MainActor.run { NSWorkspace.shared.open(url) } + return .success + } else { return .requiresSpotifyAppOpen } + } + } + + private func getLocalCurrentTrack() -> SpotifyTrack? { + guard isSpotifyAppRunning() else { return nil } + + let script = """ + if application "Spotify" is running then + tell application "Spotify" + if player state is playing or player state is paused then + return (get name of current track) & "|" & (get artist of current track) & "|" & (get album of current track) & "|" & (get spotify url of current track) & "|" & (get id of current track) + else + return "" + end if + end tell + end if + return "" + """ + var error: NSDictionary? + if let scriptObject = NSAppleScript(source: script) { + let result = scriptObject.executeAndReturnError(&error) + if error == nil, let resultString = result.stringValue, !resultString.isEmpty { + let parts = resultString.components(separatedBy: "|") + if parts.count == 5 { + + let mockAlbum = SpotifyAlbum(images: []) + return SpotifyTrack( + id: parts[4], + name: parts[0], + uri: parts[3], + album: mockAlbum, + artists: [SpotifyArtist(name: parts[1])] + ) + } + } + } + return nil + } + + + func playPlaylist(contextUri: String) async -> PlaybackResult { + if isPremiumUser { + guard let url = URL(string: "https://api.spotify.com/v1/me/player/play") else { return .failure(reason: "Invalid URL") } + let body = PlayBody(context_uri: contextUri) + guard let bodyData = try? JSONEncoder().encode(body) else { return .failure(reason: "Encoding failed") } + let success: Bool? = await makeAPIRequest(url: url, method: "PUT", body: bodyData) + return success == true ? .success : .failure(reason: "API request failed") + } else { + if isSpotifyAppRunning() { + guard let url = URL(string: contextUri) else { return .failure(reason: "Invalid URI") } + await MainActor.run { NSWorkspace.shared.open(url) } + return .success + } else { return .requiresSpotifyAppOpen } + } + } + + func setVolume(percent: Int) async -> PlaybackResult { + if isPremiumUser { + guard var components = URLComponents(string: "https://api.spotify.com/v1/me/player/volume") else { return .failure(reason: "Invalid URL") } + components.queryItems = [URLQueryItem(name: "volume_percent", value: "\(percent)")] + guard let url = components.url else { return .failure(reason: "Invalid URL") } + let success: Bool? = await makeAPIRequest(url: url, method: "PUT") + return success == true ? .success : .failure(reason: "API request failed") + } else { + if isSpotifyAppRunning() { + let script = "tell application \"Spotify\" to set sound volume to \(percent)" + let success = runAppleScript(script) + return success ? .success : .failure(reason: "AppleScript failed") + } else { return .requiresSpotifyAppOpen } + } + } + + func transferPlayback(to deviceId: String) async -> PlaybackResult { + guard isPremiumUser else { return .requiresPremium } + guard let url = URL(string: "https://api.spotify.com/v1/me/player") else { return .failure(reason: "Invalid URL") } + let body = TransferPlaybackBody(device_ids: [deviceId], play: true) + guard let bodyData = try? JSONEncoder().encode(body) else { return .failure(reason: "Encoding failed") } + let success: Bool? = await makeAPIRequest(url: url, method: "PUT", body: bodyData) + return success == true ? .success : .failure(reason: "API request failed") + } + + func fetchQueue() async -> SpotifyQueue? { + + guard isPremiumUser else { + return nil + } + + guard let url = URL(string: "https://api.spotify.com/v1/me/player/queue") else { return nil } + + + let queue: SpotifyQueue? = await makeAPIRequest(url: url) + + if queue == nil { + } else { + } + return queue + } + + + func fetchPlaylists() async -> [SpotifyPlaylist] { + guard isAuthenticated, let url = URL(string: "https://api.spotify.com/v1/me/playlists") else { return [] } + struct PlaylistResponse: Decodable { let items: [SpotifyPlaylist] } + let response: PlaylistResponse? = await makeAPIRequest(url: url) + return response?.items ?? [] + } + + func fetchDevices() async -> [SpotifyDevice] { + guard isPremiumUser, let url = URL(string: "https://api.spotify.com/v1/me/player/devices") else { return [] } + struct DevicesResponse: Decodable { let devices: [SpotifyDevice] } + let response: DevicesResponse? = await makeAPIRequest(url: url) + return response?.devices ?? [] + } + + func fetchPlaybackState() async -> PlaybackState? { + guard isPremiumUser, let url = URL(string: "https://api.spotify.com/v1/me/player") else { return nil } + return await makeAPIRequest(url: url) + } + + func fetchAudioAnalysis(for trackId: String) async -> AudioAnalysis? { + guard isAuthenticated, let url = URL(string: "https://api.spotify.com/v1/audio-analysis/\(trackId)") else { + return nil + } + return await makeAPIRequest(url: url) + } + + func searchForTrack(title: String, artist: String) async -> SpotifyTrack? { + guard isAuthenticated else { return nil } + var components = URLComponents(string: "https://api.spotify.com/v1/search")! + + let query = "track:\"\(title.trimmingCharacters(in: .whitespacesAndNewlines))\" artist:\"\(artist.trimmingCharacters(in: .whitespacesAndNewlines))\"" + components.queryItems = [ + URLQueryItem(name: "q", value: query), + URLQueryItem(name: "type", value: "track"), + URLQueryItem(name: "limit", value: "1") + ] + guard let url = components.url else { return nil } + + let response: SearchResponse? = await makeAPIRequest(url: url) + return response?.tracks.items.first + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift b/submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift new file mode 100644 index 00000000..d9c983b0 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift @@ -0,0 +1,85 @@ +// +// ActiveAppMonitor.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-09. +// + +import AppKit +import Combine + +@MainActor +class ActiveAppMonitor: ObservableObject { + + static let shared = ActiveAppMonitor() + + @Published private(set) var isLyricsAllowedForActiveApp: Bool = true + + private var activeAppBundleID: String? + private let settingsModel: SettingsModel + private var cancellables = Set() + + private init() { + self.settingsModel = SettingsModel() + + NSWorkspace.shared.notificationCenter + .publisher(for: NSWorkspace.didActivateApplicationNotification) + .compactMap { ($0.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication)?.bundleIdentifier } + .removeDuplicates() + .receive(on: DispatchQueue.main) + .sink { [weak self] bundleID in + self?.activeAppBundleID = bundleID + self?.updateLyricPermission() + } + .store(in: &cancellables) + + settingsModel.objectWillChange + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + self?.updateLyricPermission() + } + .store(in: &cancellables) + + if let initialApp = NSWorkspace.shared.frontmostApplication { + self.activeAppBundleID = initialApp.bundleIdentifier + self.updateLyricPermission() + } + } + + private func updateLyricPermission() { + var newPermissionState = true + + + + + guard settingsModel.settings.showLyricsInLiveActivity else { + newPermissionState = false + if isLyricsAllowedForActiveApp != newPermissionState { isLyricsAllowedForActiveApp = newPermissionState } + return + } + + guard let activeBundleID = activeAppBundleID else { + newPermissionState = true + if isLyricsAllowedForActiveApp != newPermissionState { isLyricsAllowedForActiveApp = newPermissionState } + return + } + + if let isAllowed = settingsModel.settings.musicAppStates[activeBundleID] { + newPermissionState = isAllowed + if isLyricsAllowedForActiveApp != newPermissionState { isLyricsAllowedForActiveApp = newPermissionState } + return + } + + if let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: activeBundleID), + let bundle = Bundle(url: appURL), + let urlTypes = bundle.infoDictionary?["CFBundleURLTypes"] as? [[String: Any]] { + + let isBrowser = urlTypes.contains { ($0["CFBundleURLSchemes"] as? [String])?.contains("http") ?? false } + newPermissionState = !isBrowser + } + + if isLyricsAllowedForActiveApp != newPermissionState { + isLyricsAllowedForActiveApp = newPermissionState + } + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift b/submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift new file mode 100644 index 00000000..96bf5deb --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift @@ -0,0 +1,160 @@ +// +// BluetoothManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-07. +// + +import Foundation +import Combine +import IOBluetooth +import AppKit +import IOKit.hid +import IOKit + +struct BluetoothDeviceState: Hashable { + enum EventType: Hashable { + case connected, disconnected, batteryLow + } + let eventUUID = UUID() + let id: String, name: String, iconName: String, eventType: EventType + var batteryLevel: Int? = nil + static func == (lhs: Self, rhs: Self) -> Bool { lhs.eventUUID == rhs.eventUUID } + func hash(into hasher: inout Hasher) { hasher.combine(eventUUID) } +} + +class BluetoothManager: ObservableObject { + @Published var lastEvent: BluetoothDeviceState? + + private var batteryCheckTimer: Timer? + private var lowBatteryNotifiedDevices = Set() + + + private let privateMonitor = PrivateBluetoothMonitor() + private var cancellables = Set() + + private let lowBatteryThreshold = 20 + private let lowBatteryRefreshThreshold = 30 + + init() { + setupPrivateListener() + setupBatteryMonitor() + } + + private func setupPrivateListener() { + privateMonitor.eventPublisher + .sink { [weak self] event in + self?.processPrivateEvent(event) + } + .store(in: &cancellables) + } + + private func processPrivateEvent(_ event: PrivateBluetoothEvent) { + + guard let device = IOBluetoothDevice(addressString: event.address), + let deviceName = device.name else { return } + + let batteryLevel = (event.type == .connected) ? self.getBatteryLevel(for: device) : nil + + + if event.type == .disconnected { + lowBatteryNotifiedDevices.remove(event.address) + } + + let deviceState = BluetoothDeviceState( + id: event.address, + name: deviceName, + iconName: Self.getIconName(for: device), + eventType: (event.type == .connected) ? .connected : .disconnected, + batteryLevel: batteryLevel + ) + + DispatchQueue.main.async { + self.lastEvent = deviceState + } + } + + private func setupBatteryMonitor() { + batteryCheckTimer = Timer.scheduledTimer(timeInterval: 300.0, target: self, selector: #selector(checkForLowBattery), userInfo: nil, repeats: true) + batteryCheckTimer?.fireDate = Date(timeIntervalSinceNow: 15.0) + } + + @objc private func checkForLowBattery() { + guard let pairedDevices = IOBluetoothDevice.pairedDevices() as? [IOBluetoothDevice] else { return } + for device in pairedDevices where device.isConnected() { + guard let addressString = device.addressString, let level = self.getBatteryLevel(for: device) else { continue } + if level <= lowBatteryThreshold { + if !lowBatteryNotifiedDevices.contains(addressString) { + let deviceState = BluetoothDeviceState(id: addressString, name: device.name ?? "Device", iconName: Self.getIconName(for: device), eventType: .batteryLow, batteryLevel: level) + DispatchQueue.main.async { self.lastEvent = deviceState; NSSound(named: "Tink")?.play() } + lowBatteryNotifiedDevices.insert(addressString) + } + } else if level >= lowBatteryRefreshThreshold { + lowBatteryNotifiedDevices.remove(addressString) + } + } + } + + private func getBatteryLevel(for device: IOBluetoothDevice) -> Int? { + guard let deviceName = device.name else { return nil } + let batteryKeys = ["BatteryPercent", "battery-level", "device-battery-level", "Battery Level"] + var batteryLevel: Int? + let matchingDict = IOServiceMatching(kIOHIDDeviceKey) + var iterator: io_iterator_t = 0 + guard IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &iterator) == KERN_SUCCESS else { return nil } + var service = IOIteratorNext(iterator) + while service != 0 { + var properties: Unmanaged? + guard IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS, + let serviceProperties = properties?.takeRetainedValue() as? [String: Any] else { + IOObjectRelease(service); service = IOIteratorNext(iterator); continue + } + if let productName = serviceProperties[kIOHIDProductKey] as? String, productName.caseInsensitiveCompare(deviceName) == .orderedSame { + for key in batteryKeys { + if let level = serviceProperties[key] as? Int { batteryLevel = level; break } + } + } + IOObjectRelease(service) + if batteryLevel != nil { break } + service = IOIteratorNext(iterator) + } + IOObjectRelease(iterator) + if batteryLevel == nil { print("--> BluetoothManager: No standard battery level key found for '\(deviceName)'.") } + return batteryLevel + } + + private static func getIconName(for device: IOBluetoothDevice) -> String { + let majorClass = device.deviceClassMajor + let minorClass = device.deviceClassMinor + let deviceName = device.name?.lowercased() ?? "" + if deviceName.contains("keyboard") || deviceName.contains("keys") { return "keyboard.fill" } + switch majorClass { + case UInt32(kBluetoothDeviceClassMajorPeripheral): + switch minorClass { + case UInt32(kBluetoothDeviceClassMinorPeripheral1Keyboard): return "keyboard.fill" + case UInt32(kBluetoothDeviceClassMinorPeripheral1Pointing): + if deviceName.contains("trackpad") { return "magictrackpad.gen2.fill" } + if deviceName.contains("mouse") { return "magicmouse.fill" } + return "cursorarrow.click.2" + default: + if deviceName.contains("controller") { return "gamecontroller.fill" } + return "platter.filled.top.applewatch.case" + } + case UInt32(kBluetoothDeviceClassMajorAudio): + if deviceName.contains("airpods max") { return "airpods.max" } + if deviceName.contains("airpods pro") { return "airpodspro.right" } + if deviceName.contains("airpods") { return "airpods" } + if deviceName.contains("homepod") { return "homepod.fill" } + if deviceName.contains("beats") { return "beats.headphones" } + switch minorClass { + case UInt32(kBluetoothDeviceClassMinorAudioHeadphones): return "headphones" + case UInt32(kBluetoothDeviceClassMinorAudioLoudspeaker): return "speaker.wave.2.fill" + default: return "headphones" + } + case UInt32(kBluetoothDeviceClassMajorComputer): return "desktopcomputer" + case UInt32(kBluetoothDeviceClassMajorPhone): return "iphone" + case UInt32(kBluetoothDeviceClassMajorWearable): return "applewatch" + default: return "b.circle.fill" + } + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift b/submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift new file mode 100644 index 00000000..782a3f6e --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift @@ -0,0 +1,86 @@ +// +// EyeBreakManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import Foundation +import Combine +import AppKit + +class EyeBreakManager: ObservableObject { + private let settingsModel = SettingsModel() + + private var workInterval: TimeInterval { TimeInterval(settingsModel.settings.eyeBreakWorkInterval * 60) } + private var breakInterval: TimeInterval { TimeInterval(settingsModel.settings.eyeBreakBreakDuration) } + private var soundAlertsEnabled: Bool { settingsModel.settings.eyeBreakSoundAlerts } + + @Published var isBreakTime: Bool = false + @Published var timeUntilNextBreak: TimeInterval + @Published var timeRemainingInBreak: TimeInterval = 0 + @Published var isDoneButtonEnabled: Bool = false + + private var timer: Timer? + + init() { + + self.timeUntilNextBreak = 20 * 60 + + startWorkTimer() + } + + private func startWorkTimer() { + isBreakTime = false + isDoneButtonEnabled = false + timeRemainingInBreak = 0 + + timer?.invalidate() + timeUntilNextBreak = workInterval + + timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in + guard let self = self else { return } + + if self.timeUntilNextBreak > 0 { + self.timeUntilNextBreak -= 1 + } else { + self.startBreakTimer() + } + } + } + + private func startBreakTimer() { + timer?.invalidate() + + if soundAlertsEnabled { + NSSound(named: "Glass")?.play() + } + + isBreakTime = true + isDoneButtonEnabled = false + timeRemainingInBreak = breakInterval + + timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in + guard let self = self else { return } + + if self.timeRemainingInBreak > 0 { + self.timeRemainingInBreak -= 1 + } else { + self.isDoneButtonEnabled = true + self.timer?.invalidate() + } + } + } + + func dismissBreak() { + resetAndStartWork() + } + + func completeBreak() { + resetAndStartWork() + } + + private func resetAndStartWork() { + self.startWorkTimer() + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/NotificationManager.swift b/submissions/sapphire/Sapphire/Services/System/NotificationManager.swift new file mode 100644 index 00000000..0ebb4730 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/NotificationManager.swift @@ -0,0 +1,173 @@ +// +// NotificationManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import Foundation +import Combine +import SQLite3 + + + +class NotificationManager: ObservableObject { + + @Published var latestNotification: NotificationPayload? + + private var dbPath: String? + private var fileMonitor: DispatchSourceFileSystemObject? + private var db: OpaquePointer? + private var lastNotificationUUID: String? + + init() { + DispatchQueue.global(qos: .background).async { + self.dbPath = self.getNotificationDbPath() + self.setupDatabaseMonitoring() + } + } + + deinit { + fileMonitor?.cancel() + if db != nil { + sqlite3_close(db) + } + } + + func dismissLatestNotification() { + DispatchQueue.main.async { + self.latestNotification = nil + } + } + + private func setupDatabaseMonitoring() { + guard let dbPath = dbPath else { + return + } + + let url = URL(fileURLWithPath: dbPath) + let fileDescriptor = open(url.path, O_EVTONLY) + guard fileDescriptor != -1 else { + return + } + + fileMonitor = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor, eventMask: .write, queue: .global(qos: .background)) + + fileMonitor?.setEventHandler { [weak self] in + self?.queryLatestNotification() + } + + fileMonitor?.setCancelHandler { + close(fileDescriptor) + } + + fileMonitor?.resume() + } + + private func queryLatestNotification() { + guard let dbPath = dbPath else { return } + + if sqlite3_open(dbPath, &db) != SQLITE_OK { + return + } + defer { sqlite3_close(db) } + + let query = "SELECT uuid, app_id, title, body, request_data FROM record WHERE presented = 0 ORDER BY delivered_date DESC LIMIT 1;" + + var statement: OpaquePointer? + if sqlite3_prepare_v2(db, query, -1, &statement, nil) != SQLITE_OK { + return + } + defer { sqlite3_finalize(statement) } + + if sqlite3_step(statement) == SQLITE_ROW { + + guard let uuid_c = sqlite3_column_text(statement, 0), + let app_id_c = sqlite3_column_text(statement, 1) else { + return + } + + let uuid = String(cString: uuid_c) + if uuid == lastNotificationUUID { return } + lastNotificationUUID = uuid + + let appIdentifier = String(cString: app_id_c) + + + let allowedIdentifiers = ["com.apple.iChat", "com.apple.facetime", "com.apple.sharingd", "com.apple.controlcenter"] + guard allowedIdentifiers.contains(appIdentifier) else { return } + + preemptSystemNotification(uuid: uuid) + + + + if appIdentifier == "com.apple.controlcenter" { + return + } + + let title_c = sqlite3_column_text(statement, 2) + let body_c = sqlite3_column_text(statement, 3) + + var finalTitle = title_c != nil ? String(cString: title_c!) : "" + var finalBody = body_c != nil ? String(cString: body_c!) : "" + + + if appIdentifier == "com.apple.sharingd" { + if let dataBlob = sqlite3_column_blob(statement, 4) { + let dataSize = sqlite3_column_bytes(statement, 4) + let requestData = Data(bytes: dataBlob, count: Int(dataSize)) + + if let plist = try? PropertyListSerialization.propertyList(from: requestData, options: [], format: nil) as? [String: Any], + let aps = plist["aps"] as? [String: Any], + let alert = aps["alert"] as? [String: Any] { + + if let titleArgs = alert["title-loc-args"] as? [String], let senderName = titleArgs.first { + finalTitle = senderName + } + + if let bodyArgs = alert["body-loc-args"] as? [String], let fileName = bodyArgs.first { + finalBody = fileName + } + } + } + } + + let payload = NotificationPayload(id: uuid, appIdentifier: appIdentifier, title: finalTitle, body: finalBody) + + DispatchQueue.main.async { + self.latestNotification = payload + } + } + } + + private func preemptSystemNotification(uuid: String) { + guard let dbPath = dbPath else { return } + var write_db: OpaquePointer? + + if sqlite3_open_v2(dbPath, &write_db, SQLITE_OPEN_READWRITE, nil) != SQLITE_OK { + return + } + defer { sqlite3_close(write_db) } + + let updateQuery = "UPDATE record SET presented = 1 WHERE uuid = ?;" + var statement: OpaquePointer? + + if sqlite3_prepare_v2(write_db, updateQuery, -1, &statement, nil) == SQLITE_OK { + sqlite3_bind_text(statement, 1, (uuid as NSString).utf8String, -1, nil) + + if sqlite3_step(statement) == SQLITE_DONE { + } + } + sqlite3_finalize(statement) + } + + private func getNotificationDbPath() -> String? { + let basePath = ("~/Library/Application Support/NotificationCenter" as NSString).expandingTildeInPath + do { + let files = try FileManager.default.contentsOfDirectory(atPath: basePath) + return files.first { $0.hasSuffix(".db") }.map { (basePath as NSString).appendingPathComponent($0) } + } catch { + return nil + } + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/TimerManager.swift b/submissions/sapphire/Sapphire/Services/System/TimerManager.swift new file mode 100644 index 00000000..e4266af5 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/TimerManager.swift @@ -0,0 +1,34 @@ +// +// TimerManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-28. +// + +import Foundation + + + +class TimerManager: ObservableObject { + @Published var isRunning: Bool = false + @Published var elapsedTime: TimeInterval = 0 + private var timer: Timer? + + func start() { + guard !isRunning else { return } + isRunning = true + timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in + self?.elapsedTime += 0.1 + } + } + + func stop() { + isRunning = false + timer?.invalidate() + } + + func reset() { + stop() + elapsedTime = 0 + } +} diff --git a/submissions/sapphire/Sapphire/System/PrivateAPIs.swift b/submissions/sapphire/Sapphire/System/PrivateAPIs.swift new file mode 100644 index 00000000..fa26d126 --- /dev/null +++ b/submissions/sapphire/Sapphire/System/PrivateAPIs.swift @@ -0,0 +1,254 @@ +// +// PrivateAPIs.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import SwiftUI +import Cocoa +import AudioToolbox + + + +fileprivate typealias CGSConnectionID = Int +fileprivate typealias CGSSpaceID = UInt64 + + +@_silgen_name("_CGSDefaultConnection") +fileprivate func _CGSDefaultConnection() -> CGSConnectionID + + +@_silgen_name("CGSSpaceCreate") +fileprivate func CGSSpaceCreate(_ cid: CGSConnectionID, _ unknown: Int, _ options: NSDictionary?) -> CGSSpaceID +@_silgen_name("CGSSpaceDestroy") +fileprivate func CGSSpaceDestroy(_ cid: CGSConnectionID, _ space: CGSSpaceID) +@_silgen_name("CGSSpaceSetAbsoluteLevel") +fileprivate func CGSSpaceSetAbsoluteLevel(_ cid: CGSConnectionID, _ space: CGSSpaceID, _ level: Int) +@_silgen_name("CGSAddWindowsToSpaces") +fileprivate func CGSAddWindowsToSpaces(_ cid: CGSConnectionID, _ windows: NSArray, _ spaces: NSArray) +@_silgen_name("CGSRemoveWindowsFromSpaces") +fileprivate func CGSRemoveWindowsFromSpaces(_ cid: CGSConnectionID, _ windows: NSArray, _ spaces: NSArray) +@_silgen_name("CGSHideSpaces") +fileprivate func CGSHideSpaces(_ cid: CGSConnectionID, _ spaces: NSArray) +@_silgen_name("CGSShowSpaces") +fileprivate func CGSShowSpaces(_ cid: CGSConnectionID, _ spaces: NSArray) +@_silgen_name("CGSGetActiveSpace") +private func CGSGetActiveSpace(_ cid: CGSConnectionID) -> CGSSpaceID +@_silgen_name("CGSCopyManagedDisplaySpaces") +private func CGSCopyManagedDisplaySpaces(_ cid: CGSConnectionID) -> CFArray + + + +@_silgen_name("DisplayServicesGetBrightness") +private func DisplayServicesGetBrightness(_ display: CGDirectDisplayID, _ brightness: UnsafeMutablePointer) -> Int32 +@_silgen_name("DisplayServicesSetBrightness") +private func DisplayServicesSetBrightness(_ display: CGDirectDisplayID, _ brightness: Float) -> Int32 + + + +@_silgen_name("$s7SwiftUI5ImageV19_internalSystemNameACSS_tcfC") +private func _swiftUI_image(internalSystemName: String) -> Image? + +extension Image { + + init?(privateName: String) { + guard let systemImage = _swiftUI_image(internalSystemName: privateName) else { + return nil + } + self = systemImage + } +} + + + + +public final class CGSSpace { + private let identifier: CGSSpaceID + private let createdByInit: Bool + private let connectionID: CGSConnectionID + + public var windows: Set = [] { + didSet { + let remove = oldValue.subtracting(self.windows) + let add = self.windows.subtracting(oldValue) + + if connectionID != 0 { + if !remove.isEmpty { + CGSRemoveWindowsFromSpaces(connectionID, remove.map { $0.windowNumber } as NSArray, [self.identifier] as NSArray) + } + if !add.isEmpty { + CGSAddWindowsToSpaces(connectionID, add.map { $0.windowNumber } as NSArray, [self.identifier] as NSArray) + } + } else { + } + } + } + + + public init(level: Int = 0) { + self.connectionID = _CGSDefaultConnection() + let flag = 0x1 + + self.identifier = CGSSpaceCreate(connectionID, flag, nil as NSDictionary?) + CGSSpaceSetAbsoluteLevel(connectionID, self.identifier, level) + CGSShowSpaces(connectionID, [self.identifier] as NSArray) + self.createdByInit = true + } + + deinit { + if connectionID != 0 && identifier != 0 { + CGSHideSpaces(connectionID, [self.identifier] as NSArray) + if createdByInit { + CGSSpaceDestroy(connectionID, self.identifier) + } + } + } +} + + + + +class OSDManager { + static func disableSystemHUD() { + let kickstart = Process() + kickstart.launchPath = "/bin/launchctl" + kickstart.arguments = ["kickstart", "gui/\(getuid())/com.apple.OSDUIHelper"] + + do { + try kickstart.run() + kickstart.waitUntilExit() + } catch { + } + + let stopProcess = Process() + stopProcess.launchPath = "/usr/bin/killall" + stopProcess.arguments = ["-STOP", "OSDUIHelper"] + + do { + try stopProcess.run() + } catch { + } + } + + static func enableSystemHUD() { + let continueProcess = Process() + continueProcess.launchPath = "/usr/bin/killall" + continueProcess.arguments = ["-CONT", "OSDUIHelper"] + + do { + try continueProcess.run() + } catch { + } + } +} + + + + +struct SystemControl { + + + private static func getDefaultOutputDeviceID() -> AudioDeviceID? { + var deviceID: AudioDeviceID = kAudioObjectUnknown + var propertySize = UInt32(MemoryLayout.size) + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioHardwarePropertyDefaultOutputDevice, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMain + ) + let status = AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &propertyAddress, 0, nil, &propertySize, &deviceID) + return status == noErr ? deviceID : nil + } + + static func getVolume() -> Float { + guard let deviceID = getDefaultOutputDeviceID() else { return 0.5 } + var volume: Float32 = 0.0 + var propertySize = UInt32(MemoryLayout.size) + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyVolumeScalar, + mScope: kAudioObjectPropertyScopeOutput, + mElement: kAudioObjectPropertyElementMain + ) + AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &volume) + return Float(volume) + } + + static func setVolume(to level: Float) { + guard let deviceID = getDefaultOutputDeviceID() else { return } + var newVolume = Float32(max(0.0, min(1.0, level))) + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyVolumeScalar, + mScope: kAudioObjectPropertyScopeOutput, + mElement: kAudioObjectPropertyElementMain + ) + AudioObjectSetPropertyData(deviceID, &propertyAddress, 0, nil, UInt32(MemoryLayout.size(ofValue: newVolume)), &newVolume) + } + + static func isMuted() -> Bool { + guard let deviceID = getDefaultOutputDeviceID() else { return false } + var isMuted: UInt32 = 0 + var propertySize = UInt32(MemoryLayout.size) + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyMute, + mScope: kAudioObjectPropertyScopeOutput, + mElement: kAudioObjectPropertyElementMain + ) + AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &isMuted) + return isMuted == 1 + } + + static func setMuted(to isMuted: Bool) { + guard let deviceID = getDefaultOutputDeviceID() else { return } + var muteVal: UInt32 = isMuted ? 1 : 0 + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyMute, + mScope: kAudioObjectPropertyScopeOutput, + mElement: kAudioObjectPropertyElementMain + ) + AudioObjectSetPropertyData(deviceID, &propertyAddress, 0, nil, UInt32(MemoryLayout.size(ofValue: muteVal)), &muteVal) + } + + + static func getBrightness() -> Float { + var brightness: Float = 0.0 + guard let screen = NSScreen.main else { return 0.5 } + let displayID = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID ?? 0 + if DisplayServicesGetBrightness(displayID, &brightness) != 0 { + return 0.5 + } + return brightness + } + + static func setBrightness(to level: Float) { + let clampedLevel = min(1.0, max(0.0, level)) + for screen in NSScreen.screens { + let displayID = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID ?? 0 + DisplayServicesSetBrightness(displayID, clampedLevel) + } + } +} + + + + +struct CGSHelper { + private static let connection = _CGSDefaultConnection() + + + static func getActiveDesktopNumber() -> Int? { + let activeSpaceID = CGSGetActiveSpace(connection) + + guard let displaySpaces = CGSCopyManagedDisplaySpaces(connection) as? [[String: Any]], + let mainDisplay = displaySpaces.first, + let spacesForMainDisplay = mainDisplay["Spaces"] as? [[String: Any]] else { + return nil + } + + if let index = spacesForMainDisplay.firstIndex(where: { ($0["id64"] as? CGSSpaceID) == activeSpaceID }) { + return index + 1 + } + + return nil + } +} diff --git a/submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift b/submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift new file mode 100644 index 00000000..c88b70dd --- /dev/null +++ b/submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift @@ -0,0 +1,52 @@ +// +// PrivateBluetoothMonitor.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-07. +// + +import Foundation +import Combine + +class PrivateBluetoothMonitor { + private var diagnosticObserver: NSObjectProtocol? + + init() { + + let dnc = DistributedNotificationCenter.default() + + + diagnosticObserver = dnc.addObserver( + forName: nil, + object: nil, + queue: nil + ) { notification in + + } + + + DispatchQueue.main.asyncAfter(deadline: .now() + 30) { [weak self] in + if let observer = self?.diagnosticObserver { + DistributedNotificationCenter.default().removeObserver(observer) + } + } + } + + deinit { + if let observer = diagnosticObserver { + DistributedNotificationCenter.default().removeObserver(observer) + } + } + + + let eventPublisher = PassthroughSubject() +} + + +struct PrivateBluetoothEvent { + enum EventType { + case connected, disconnected + } + let address: String + let type: EventType +} diff --git a/submissions/sapphire/Sapphire/System/SystemHUD.swift b/submissions/sapphire/Sapphire/System/SystemHUD.swift new file mode 100644 index 00000000..424274fa --- /dev/null +++ b/submissions/sapphire/Sapphire/System/SystemHUD.swift @@ -0,0 +1,357 @@ +// +// SystemHUD.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-06. +// + +import SwiftUI +import AppKit +import Combine + + +fileprivate func eventTapCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged? { + guard type.rawValue == NX_SYSDEFINED else { + return Unmanaged.passRetained(event) + } + + + if SystemHUDManager.shared.handleMediaKeyEvent(event) { + return nil + } + + return Unmanaged.passRetained(event) +} + + +extension Notification.Name { + static let mediaKeyPlayPausePressed = Notification.Name("mediaKeyPlayPausePressed") + static let mediaKeyNextPressed = Notification.Name("mediaKeyNextPressed") + static let mediaKeyPreviousPressed = Notification.Name("mediaKeyPreviousPressed") +} + + + +enum HUDType: Hashable { + case volume(level: Float) + case brightness(level: Float) + + var caseIdentifier: CaseIdentifier { + switch self { + case .volume: return .volume + case .brightness: return .brightness + } + } + enum CaseIdentifier { case volume, brightness } +} + +private enum MediaKeyAction { + case volumeUp, volumeDown + case brightnessUp, brightnessDown +} + + +class SystemHUDManager: ObservableObject { + static let shared = SystemHUDManager() + + @Published private(set) var currentHUD: HUDType? + var style: HUDStyle = .default + + private var eventTap: CFMachPort? + private var hudDismissalTimer: Timer? + private var changeAnimator: Timer? + private var currentAction: MediaKeyAction? + private var isFineTuning: Bool = false + private var keyPressStartTime: Date? + + private let initialStepAmount: Float = 1.0 / 16.0 + private let keyRepeatDelay: TimeInterval = 0.2 + private let animationInterval: TimeInterval = 1.0 / 60.0 + private let baseAnimationRate: Float = 1.0 / 2.0 + private let maxAnimationRate: Float = 1.0 / 0.7 + private let accelerationDuration: TimeInterval = 1.5 + private let fineAnimationRate: Float = 1.0 / 5.0 + + private init() { + setupEventTap() + } + + private func setupEventTap() { + let eventsToMonitor: CGEventMask = (1 << NX_SYSDEFINED) + eventTap = CGEvent.tapCreate( + tap: .cgSessionEventTap, + place: .headInsertEventTap, + options: .defaultTap, + eventsOfInterest: eventsToMonitor, + callback: eventTapCallback, + userInfo: nil + ) + + guard let eventTap = eventTap else { + return + } + let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0) + CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) + CGEvent.tapEnable(tap: eventTap, enable: true) + } + + fileprivate func handleMediaKeyEvent(_ cgEvent: CGEvent) -> Bool { + guard let nsEvent = NSEvent(cgEvent: cgEvent), + nsEvent.type == .systemDefined, + nsEvent.subtype.rawValue == 8 else { + return false + } + + let keyCode = Int32((nsEvent.data1 & 0xFFFF0000) >> 16) + let keyState = (nsEvent.data1 & 0xFF00) >> 8 + let isKeyDown = (keyState == 0x0A) + let isKeyUp = (keyState == 0x0B) + + + + switch keyCode { + case NX_KEYTYPE_PLAY: + NotificationCenter.default.post(name: .mediaKeyPlayPausePressed, object: nil) + return true + case NX_KEYTYPE_FAST: + NotificationCenter.default.post(name: .mediaKeyNextPressed, object: nil) + return true + case NX_KEYTYPE_REWIND: + NotificationCenter.default.post(name: .mediaKeyPreviousPressed, object: nil) + return true + default: + break + } + + + let action: MediaKeyAction? + switch keyCode { + case NX_KEYTYPE_SOUND_UP: action = .volumeUp + case NX_KEYTYPE_SOUND_DOWN: action = .volumeDown + case NX_KEYTYPE_BRIGHTNESS_UP: action = .brightnessUp + case NX_KEYTYPE_BRIGHTNESS_DOWN: action = .brightnessDown + case NX_KEYTYPE_MUTE: + if isKeyDown { + DispatchQueue.main.async { self.handleMute() } + } + return true + default: + return false + } + + guard let validAction = action else { return false } + + DispatchQueue.main.async { + if isKeyDown { + if self.currentAction == nil { + self.startSmoothChange(for: validAction, with: nsEvent.modifierFlags) + } + } else if isKeyUp { + if validAction == self.currentAction { + self.stopSmoothChange() + } + } + } + + return true + } + + private func handleMute() { + stopSmoothChange() + let isMuted = SystemControl.isMuted() + SystemControl.setMuted(to: !isMuted) + let currentVolume = SystemControl.getVolume() + showHUD(for: .volume(level: !isMuted ? 0.0 : (currentVolume > 0 ? currentVolume : 0.01))) + if !isMuted { NSSound(named: "Tink")?.play() } + } + + private func startSmoothChange(for action: MediaKeyAction, with modifiers: NSEvent.ModifierFlags) { + currentAction = action + isFineTuning = modifiers.contains([.shift, .option]) + keyPressStartTime = Date() + + let initialStep = isFineTuning ? (initialStepAmount / 4.0) : initialStepAmount + performChange(by: initialStep, isInitialPress: true) + + changeAnimator = Timer.scheduledTimer( + timeInterval: animationInterval, + target: self, + selector: #selector(performAnimatedStep), + userInfo: nil, + repeats: true + ) + changeAnimator?.fireDate = Date(timeIntervalSinceNow: keyRepeatDelay) + } + + private func stopSmoothChange() { + changeAnimator?.invalidate() + changeAnimator = nil + currentAction = nil + keyPressStartTime = nil + } + + @objc private func performAnimatedStep() { + guard let startTime = keyPressStartTime else { + stopSmoothChange() + return + } + + let effectiveRate: Float + if isFineTuning { + effectiveRate = fineAnimationRate + } else { + let duration = Date().timeIntervalSince(startTime) + let elapsedSinceAnimationStart = max(0, duration - keyRepeatDelay) + let progress = min(1.0, elapsedSinceAnimationStart / accelerationDuration) + let easedProgress = Float(progress * progress) + effectiveRate = baseAnimationRate + (maxAnimationRate - baseAnimationRate) * easedProgress + } + + let step = effectiveRate * Float(animationInterval) + performChange(by: step, isInitialPress: false) + } + + private func performChange(by amount: Float, isInitialPress: Bool) { + guard let action = currentAction else { return } + + switch action { + case .volumeUp: + let newVolume = min(1.0, SystemControl.getVolume() + amount) + SystemControl.setVolume(to: newVolume) + SystemControl.setMuted(to: false) + showHUD(for: .volume(level: newVolume)) + if isInitialPress { NSSound(named: "Tink")?.play() } + case .volumeDown: + let newVolume = max(0.0, SystemControl.getVolume() - amount) + SystemControl.setVolume(to: newVolume) + SystemControl.setMuted(to: false) + showHUD(for: .volume(level: newVolume)) + if isInitialPress { NSSound(named: "Tink")?.play() } + case .brightnessUp: + let newBrightness = min(1.0, SystemControl.getBrightness() + amount) + SystemControl.setBrightness(to: newBrightness) + showHUD(for: .brightness(level: newBrightness)) + case .brightnessDown: + let newBrightness = max(0.0, SystemControl.getBrightness() - amount) + SystemControl.setBrightness(to: newBrightness) + showHUD(for: .brightness(level: newBrightness)) + } + } + + private func showHUD(for hudType: HUDType) { + self.currentHUD = hudType + hudDismissalTimer?.invalidate() + hudDismissalTimer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { [weak self] _ in + self?.currentHUD = nil + } + } +} + + +struct SystemHUDView: View { + let type: HUDType + @State private var isShowing = false + + private var iconName: String { + switch type { + case .volume(let level): + if level == 0 { return "speaker.slash.fill" } + if level < 0.33 { return "speaker.wave.1.fill" } + if level < 0.66 { return "speaker.wave.2.fill" } + return "speaker.wave.3.fill" + case .brightness: return "sun.max.fill" + } + } + + private var level: Float { + switch type { + case .volume(let level): return level + case .brightness(let level): return level + } + } + + var body: some View { + HStack(spacing: 12) { + ZStack { + Circle().fill(.white.opacity(0.1)) + Image(systemName: iconName) + .font(.system(size: 18, weight: .semibold)) + .foregroundStyle(.white) + } + .frame(width: 40, height: 40) + + ModernLinearIndicator(level: CGFloat(level)) + .frame(height: 8) + } + .padding(.horizontal, 16) + .padding(.vertical, 10) + .background(.thinMaterial) + .background(.black.opacity(0.4)) + .clipShape(Capsule()) + .overlay(Capsule().strokeBorder(.white.opacity(0.2), lineWidth: 1)) + .shadow(color: .black.opacity(0.3), radius: 15, y: 5) + .padding(.top, 30) + .frame(width: 240) + .scaleEffect(isShowing ? 1 : 0.9) + .opacity(isShowing ? 1 : 0) + .onAppear { + withAnimation(.spring(response: 0.4, dampingFraction: 0.8)) { + isShowing = true + } + } + .transition(.identity) + } +} + + +struct SystemHUDSlimActivityView { + static func left(type: HUDType) -> some View { + let iconName: String = { + switch type { + case .volume(let level): + if level == 0 { return "speaker.slash.fill" } + if level < 0.33 { return "speaker.wave.1.fill" } + if level < 0.66 { return "speaker.wave.2.fill" } + return "speaker.wave.3.fill" + case .brightness: return "sun.max.fill" + } + }() + + return ZStack { + Image(systemName: iconName) + .font(.system(size: 14, weight: .semibold)) + .foregroundColor(.white) + .animation(nil, value: type) + } + .frame(width: 20, height: 20) + .animation(.default, value: type.caseIdentifier) + } + + static func right(type: HUDType) -> some View { + let level: Float = { + switch type { + case .volume(let level): return level + case .brightness(let level): return level + } + }() + + return ModernLinearIndicator(level: CGFloat(level)) + .frame(width: 100, height: 6) + .fixedSize() + } +} + + +struct ModernLinearIndicator: View { + var level: CGFloat + var body: some View { + GeometryReader { geometry in + ZStack(alignment: .leading) { + Capsule().fill(.primary.opacity(0.15)) + Capsule().fill(Color.white) + .frame(width: geometry.size.width * max(0, level)) + .animation(.linear(duration: 0.05), value: level) + } + } + } +} diff --git a/submissions/sapphire/Sapphire/Utilities/Extensions.swift b/submissions/sapphire/Sapphire/Utilities/Extensions.swift new file mode 100644 index 00000000..3440f42f --- /dev/null +++ b/submissions/sapphire/Sapphire/Utilities/Extensions.swift @@ -0,0 +1,184 @@ +// +// Extensions.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import SwiftUI +import AppKit +import Combine +import ScreenCaptureKit + + +extension Date { + func format(as format: String) -> String { + let formatter = DateFormatter() + formatter.dateFormat = format + return formatter.string(from: self) + } + func isSameDay(as otherDate: Date) -> Bool { + return Calendar.current.isDate(self, inSameDayAs: otherDate) + } + var isWeekend: Bool { + return Calendar.current.isDateInWeekend(self) + } +} + +extension Color { + func lerp(to otherColor: Color, t: CGFloat) -> Color { + let t_clamped = min(max(t, 0), 1) + let from = self.resolve(in: .init()) + let to = otherColor.resolve(in: .init()) + let r = from.red + (to.red - from.red) * Float(t_clamped) + let g = from.green + (to.green - from.green) * Float(t_clamped) + let b = from.blue + (to.blue - from.blue) * Float(t_clamped) + return Color(red: Double(r), green: Double(g), blue: Double(b)) + } +} + +extension NSImage { + func getEdgeColors() -> (left: Color, right: Color, accent: Color)? { + guard let cgImage = self.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return nil } + + let ciImage = CIImage(cgImage: cgImage) + let extent = ciImage.extent + let context = CIContext() + + func getRawAverageNSColor(from rect: CGRect) -> NSColor? { + let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: ciImage, kCIInputExtentKey: CIVector(cgRect: rect)])! + guard let outputImage = filter.outputImage else { return nil } + + var bitmap = [UInt8](repeating: 0, count: 4) + context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil) + + return NSColor(red: CGFloat(bitmap[0]) / 255.0, green: CGFloat(bitmap[1]) / 255.0, blue: CGFloat(bitmap[2]) / 255.0, alpha: 1.0) + } + + let edgeWidth = extent.width * 0.1 + let leftRect = CGRect(x: extent.origin.x, y: extent.origin.y, width: edgeWidth, height: extent.height) + let rightRect = CGRect(x: extent.maxX - edgeWidth, y: extent.origin.y, width: edgeWidth, height: extent.height) + + guard var leftNSColor = getRawAverageNSColor(from: leftRect), + var rightNSColor = getRawAverageNSColor(from: rightRect) else { + return nil + } + + if leftNSColor.isSimilar(to: rightNSColor, threshold: 0.05) { + rightNSColor = rightNSColor.madeDistinct() + } + + let accentNSColor = leftNSColor.withBrightness(increasedBy: 0.2) + + let finalLeftColor = Color(leftNSColor.saturated(by: 0.3).withMinimumBrightness(0.45)) + let finalRightColor = Color(rightNSColor.saturated(by: 0.3).withMinimumBrightness(0.45)) + let finalAccentColor = Color(accentNSColor.saturated(by: 0.3).withMinimumBrightness(0.50)) + + return (left: finalLeftColor, right: finalRightColor, accent: finalAccentColor) + } +} + +extension NSColor { + func withBrightness(increasedBy amount: CGFloat) -> NSColor { + var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 + self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) + let newBrightness = min(brightness + amount, 1.0) + return NSColor(hue: hue, saturation: saturation, brightness: newBrightness, alpha: alpha) + } + + func isSimilar(to otherColor: NSColor, threshold: CGFloat) -> Bool { + var h1: CGFloat = 0, s1: CGFloat = 0, b1: CGFloat = 0, a1: CGFloat = 0 + var h2: CGFloat = 0, s2: CGFloat = 0, b2: CGFloat = 0, a2: CGFloat = 0 + self.getHue(&h1, saturation: &s1, brightness: &b1, alpha: &a1) + otherColor.getHue(&h2, saturation: &s2, brightness: &b2, alpha: &a2) + let brightnessDiff = abs(b1 - b2) + let hueDiff = abs(h1 - h2) + return brightnessDiff < threshold && hueDiff < threshold + } + + func madeDistinct() -> NSColor { + var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 + self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) + let newBrightness = min(brightness + 0.15, 1.0) + let newSaturation = max(saturation - 0.15, 0.0) + return NSColor(hue: hue, saturation: newSaturation, brightness: newBrightness, alpha: alpha) + } + + func saturated(by percentage: CGFloat) -> NSColor { + var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 + self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) + let newSaturation = min(saturation + percentage, 1.0) + return NSColor(hue: hue, saturation: newSaturation, brightness: brightness, alpha: alpha) + } + + func withMinimumBrightness(_ minBrightness: CGFloat) -> NSColor { + var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 + self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) + if brightness < minBrightness { + return NSColor(hue: hue, saturation: saturation, brightness: minBrightness, alpha: alpha) + } + return self + } +} + + + + + + + + + +enum PickerResult { + case success(SCContentFilter) + case failure(Error?) +} + + +class ContentPickerHelper: NSObject, ObservableObject, SCContentSharingPickerObserver { + + + let pickerResultPublisher = PassthroughSubject() + + override init() { + super.init() + } + + deinit { + } + + func showPicker() { + let picker = SCContentSharingPicker.shared + picker.add(self) + picker.isActive = true + picker.present() + } + + + + + + + func contentSharingPicker(_ picker: SCContentSharingPicker, didUpdateWith filter: SCContentFilter, for stream: SCStream?) { + SCContentSharingPicker.shared.remove(self) + DispatchQueue.main.async { + self.pickerResultPublisher.send(.success(filter)) + } + } + + + func contentSharingPicker(_ picker: SCContentSharingPicker, didCancelFor stream: SCStream?) { + SCContentSharingPicker.shared.remove(self) + DispatchQueue.main.async { + self.pickerResultPublisher.send(.failure(nil)) + } + } + + + func contentSharingPickerStartDidFailWithError(_ error: Error) { + SCContentSharingPicker.shared.remove(self) + DispatchQueue.main.async { + self.pickerResultPublisher.send(.failure(error)) + } + } +} diff --git a/submissions/sapphire/Sapphire/Utilities/Helpers.swift b/submissions/sapphire/Sapphire/Utilities/Helpers.swift new file mode 100644 index 00000000..2ccdb249 --- /dev/null +++ b/submissions/sapphire/Sapphire/Utilities/Helpers.swift @@ -0,0 +1,99 @@ +// +// Helpers.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import Foundation +import SwiftUI +import AppKit + + +public class Debouncer { + private let delay: TimeInterval + private var workItem: DispatchWorkItem? + private let queue: DispatchQueue + + public init(delay: TimeInterval, queue: DispatchQueue = .main) { + self.delay = delay + self.queue = queue + } + + + public func debounce(action: @escaping (() -> Void)) { + workItem?.cancel() + let newWorkItem = DispatchWorkItem(block: action) + workItem = newWorkItem + queue.asyncAfter(deadline: .now() + delay, execute: newWorkItem) + } + + + public func cancel() { + workItem?.cancel() + } +} + + +struct SizeLoggingViewModifier: ViewModifier { + let label: String + func body(content: Content) -> some View { + content + .background( + GeometryReader { geometry in + Color.clear + .onAppear { + } + .onChange(of: geometry.size) { newSize in + } + } + ) + } +} + + +struct HapticManager { + static func perform(_ pattern: NSHapticFeedbackManager.FeedbackPattern) { + NSHapticFeedbackManager.defaultPerformer.perform(pattern, performanceTime: .now) + } +} + +struct BlurButtonStyle: ButtonStyle { + func makeBody(configuration: Configuration) -> some View { + configuration.label + .blur(radius: configuration.isPressed ? 4 : 0) + .scaleEffect(configuration.isPressed ? 0.9 : 1.0) + .opacity(configuration.isPressed ? 0.8 : 1.0) + .animation(.spring(response: 0.35, dampingFraction: 0.5), value: configuration.isPressed) + } +} + +struct InteractiveProgressBar: View { + @Binding var value: Double + var gradient: Gradient + var onSeek: (Double) -> Void + @State private var isDragging = false + @State private var dragValue: Double = 0.0 + + var body: some View { + GeometryReader { geometry in + ZStack(alignment: .leading) { + Rectangle().fill(Color.secondary.opacity(0.3)).frame(height: 10) + Rectangle().fill(LinearGradient(gradient: gradient, startPoint: .leading, endPoint: .trailing)).frame(width: geometry.size.width * CGFloat(isDragging ? dragValue : value), height: 10) + } + .clipShape(Capsule()) + .position(x: geometry.size.width / 2, y: geometry.size.height / 2) + .contentShape(Rectangle()) + .gesture(DragGesture(minimumDistance: 0).onChanged { gestureValue in + if !isDragging { isDragging = true; dragValue = value } + let newProgress = min(max(0, gestureValue.location.x / geometry.size.width), 1) + self.dragValue = newProgress + }.onEnded { gestureValue in + let finalProgress = min(max(0, gestureValue.location.x / geometry.size.width), 1) + onSeek(finalProgress) + isDragging = false + }) + .animation(isDragging ? .none : .linear(duration: 0.5), value: value) + } + } +} diff --git a/submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift b/submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift new file mode 100644 index 00000000..8ca6fb44 --- /dev/null +++ b/submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift @@ -0,0 +1,17 @@ +// +// DynamicNotchTests.swift +// DynamicNotchTests +// +// Created by Shariq Charolia on 2025-05-07. +// + +//import Testing +//@testable import Sapphire +// +//struct DynamicNotchTests { +// +// @Test func example() async throws { +// // Write your test here and use APIs like `#expect(...)` to check expected conditions. +// } +// +//} diff --git a/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift b/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift new file mode 100644 index 00000000..d2ba60f2 --- /dev/null +++ b/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift @@ -0,0 +1,41 @@ +// +// DynamicNotchUITests.swift +// DynamicNotchUITests +// +// Created by Shariq Charolia on 2025-05-07. +// + +import XCTest + +final class DynamicNotchUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + @MainActor + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + @MainActor + func testLaunchPerformance() throws { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } +} diff --git a/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift b/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift new file mode 100644 index 00000000..721f0454 --- /dev/null +++ b/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift @@ -0,0 +1,33 @@ +// +// DynamicNotchUITestsLaunchTests.swift +// DynamicNotchUITests +// +// Created by Shariq Charolia on 2025-05-07. +// + +import XCTest + +final class DynamicNotchUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + @MainActor + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist b/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist new file mode 100644 index 00000000..8ffa2b0b --- /dev/null +++ b/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist @@ -0,0 +1,40 @@ + + + + + BuildMachineOSBuild + 25A5306g + CFBundleDevelopmentRegion + en + CFBundleIdentifier + swift-protobuf.SwiftProtobuf.resources + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + SwiftProtobuf_SwiftProtobuf + CFBundlePackageType + BNDL + CFBundleSupportedPlatforms + + MacOSX + + DTCompiler + com.apple.compilers.llvm.clang.1_0 + DTPlatformBuild + 24F74 + DTPlatformName + macosx + DTPlatformVersion + 15.5 + DTSDKBuild + 24F74 + DTSDKName + macosx15.5 + DTXcode + 1640 + DTXcodeBuild + 16F6 + LSMinimumSystemVersion + 10.13 + + diff --git a/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy b/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 00000000..e5407507 --- /dev/null +++ b/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,14 @@ + + + + + NSPrivacyTracking + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTrackingDomains + + + diff --git a/submissions/sapphire/Util/Data+Extensions.swift b/submissions/sapphire/Util/Data+Extensions.swift new file mode 100644 index 00000000..efa8472a --- /dev/null +++ b/submissions/sapphire/Util/Data+Extensions.swift @@ -0,0 +1,47 @@ +// +// Data+URLSafeBase64.swift +// NearDrop +// +// Created by Grishka on 08.04.2023. +// + +import Foundation +import CoreFoundation + +extension Data{ + func urlSafeBase64EncodedString() -> String { + return String(base64EncodedString().replacingOccurrences(of: "=", with: "").map { + if $0=="/"{ + return "_" + } else if $0=="+" { + return "-" + } else { + return $0 + } + }) + } + + static func randomData(length: Int) -> Data{ + var data=Data(count: length) + data.withUnsafeMutableBytes { + guard 0 == SecRandomCopyBytes(kSecRandomDefault, length, $0.baseAddress!) else { fatalError() } + } + return data + } + + static func dataFromUrlSafeBase64(_ str:String)->Data?{ + var regularB64=String(str.map{ + if $0=="_"{ + return "/" + }else if $0=="-"{ + return "+" + }else{ + return $0 + } + }) + while (regularB64.count%4) != 0{ + regularB64=regularB64+"=" + } + return Data(base64Encoded: regularB64, options: .ignoreUnknownCharacters) + } +} From 77429cd0ae81c9e3546b39d6c6500df1f7996f8c Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 14:45:32 -0400 Subject: [PATCH 03/16] Add files via upload --- .../Services/System/AudioDeviceManager.swift | 124 ++++++++++ .../Services/System/BatteryMonitor.swift | 71 ++++++ .../Services/System/DesktopManager.swift | 38 +++ .../Services/System/FocusModeManager.swift | 81 +++++++ .../Services/Weather/WeatherService.swift | 174 +++++++++++++ .../Services/Weather/WeatherViewModel.swift | 102 ++++++++ .../Widgets/Calendar/CalendarWidgetView.swift | 170 +++++++++++++ .../Calendar/ScrollOffsetPreferenceKey.swift | 23 ++ .../Widgets/MusicPlayer/LyricsView.swift | 126 ++++++++++ .../Widgets/MusicPlayer/MusicPlayerView.swift | 157 ++++++++++++ .../Widgets/MusicPlayer/MusicWidgetView.swift | 150 ++++++++++++ .../MusicPlayer/Spotify/DevicesView.swift | 127 ++++++++++ .../MusicPlayer/Spotify/LoginPromptView.swift | 34 +++ .../MusicPlayer/Spotify/PlaylistView.swift | 112 +++++++++ .../Spotify/QueueAndPlaylistsView.swift | 218 +++++++++++++++++ .../Spotify/SpotifyPlaybackManager.swift | 72 ++++++ .../NearbyShare/NearDropProgressView.swift | 229 ++++++++++++++++++ .../Sapphire/Widgets/NotchWidgetView.swift | 106 ++++++++ .../Widgets/Weather/WeatherDetailView.swift | 134 ++++++++++ .../Widgets/Weather/WeatherIconMapper.swift | 100 ++++++++ .../Widgets/Weather/WeatherWidgetView.swift | 97 ++++++++ 21 files changed, 2445 insertions(+) create mode 100644 submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/DesktopManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift create mode 100644 submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift create mode 100644 submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift create mode 100644 submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift diff --git a/submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift b/submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift new file mode 100644 index 00000000..20a8fd60 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift @@ -0,0 +1,124 @@ +// +// AudioDeviceManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-08. +// + +import Foundation +import Combine +import AudioToolbox + + +struct AudioSwitchEvent: Hashable { + enum Direction: Hashable { + case switchedToMac + case switchedAwayFromMac + } + + let id = UUID() + let deviceName: String + let direction: Direction +} + + +class AudioDeviceManager: ObservableObject { + @Published var lastSwitchEvent: AudioSwitchEvent? + + private var previousDeviceName: String? + + init() { + + DispatchQueue.main.async { + self.setupAudioListener() + + self.previousDeviceName = self.getCurrentDeviceName() + } + } + + private func setupAudioListener() { + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioHardwarePropertyDefaultOutputDevice, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMain + ) + + + let propertyListener: AudioObjectPropertyListenerBlock = { [weak self] _, _ in + DispatchQueue.main.async { + self?.handleDeviceChange() + } + } + + let status = AudioObjectAddPropertyListenerBlock( + AudioObjectID(kAudioObjectSystemObject), + &propertyAddress, + nil, + propertyListener + ) + + if status != noErr { + } + } + + private func handleDeviceChange() { + let newDeviceName = getCurrentDeviceName() + + + guard newDeviceName != previousDeviceName else { return } + + + let didSwitchAway = isAutoSwitchDevice(name: previousDeviceName) && !isAutoSwitchDevice(name: newDeviceName) + let didSwitchTo = !isAutoSwitchDevice(name: previousDeviceName) && isAutoSwitchDevice(name: newDeviceName) + + if didSwitchAway, let name = previousDeviceName { + lastSwitchEvent = AudioSwitchEvent(deviceName: name, direction: .switchedAwayFromMac) + } else if didSwitchTo, let name = newDeviceName { + lastSwitchEvent = AudioSwitchEvent(deviceName: name, direction: .switchedToMac) + } + + + self.previousDeviceName = newDeviceName + } + + + + + private func isAutoSwitchDevice(name: String?) -> Bool { + guard let lowercasedName = name?.lowercased() else { return false } + let keywords = ["airpods", "beats", "powerbeats"] + return keywords.contains { lowercasedName.contains($0) } + } + + private func getCurrentDeviceName() -> String? { + var deviceID: AudioDeviceID = kAudioObjectUnknown + var propertySize = UInt32(MemoryLayout.size) + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioHardwarePropertyDefaultOutputDevice, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMain + ) + + guard AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &propertyAddress, 0, nil, &propertySize, &deviceID) == noErr else { + return nil + } + + return getDeviceName(for: deviceID) + } + + private func getDeviceName(for deviceID: AudioDeviceID) -> String? { + var name: CFString = "" as CFString + var propertySize = UInt32(MemoryLayout.size) + var propertyAddress = AudioObjectPropertyAddress( + mSelector: kAudioDevicePropertyDeviceNameCFString, + mScope: kAudioObjectPropertyScopeGlobal, + mElement: kAudioObjectPropertyElementMain + ) + + guard AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &name) == noErr else { + return nil + } + + return name as String + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift b/submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift new file mode 100644 index 00000000..fe5f0379 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift @@ -0,0 +1,71 @@ +// +// BatteryMonitor.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-03. +// + +import Foundation +import IOKit.ps + +class BatteryMonitor: ObservableObject { + @Published var currentState: BatteryState? + + private var runLoopSource: CFRunLoopSource? + + init() { + setupBatteryChangeNotification() + updateBatteryState() + } + + deinit { + if let source = runLoopSource { + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, .defaultMode) + } + } + + private func setupBatteryChangeNotification() { + let callback: IOPowerSourceCallbackType = { _ in + DispatchQueue.main.async { + BatteryMonitor.shared?.updateBatteryState() + } + } + + let context = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) + + if let source = IOPSNotificationCreateRunLoopSource(callback, context)?.takeRetainedValue() { + runLoopSource = source + CFRunLoopAddSource(CFRunLoopGetCurrent(), source, .defaultMode) + } else { + } + + BatteryMonitor.shared = self + } + + private static var shared: BatteryMonitor? + + private func updateBatteryState() { + guard let snapshot = IOPSCopyPowerSourcesInfo()?.takeRetainedValue(), + let sources = IOPSCopyPowerSourcesList(snapshot)?.takeRetainedValue() as? [CFTypeRef], + let powerSource = sources.first, + let info = IOPSGetPowerSourceDescription(snapshot, powerSource)?.takeUnretainedValue() as? [String: AnyObject] else { + return + } + + let level = info[kIOPSCurrentCapacityKey] as? Int ?? -1 + let isCharging = info[kIOPSIsChargingKey] as? Bool ?? false + let sourceState = info[kIOPSPowerSourceStateKey] as? String ?? "" + + + let newState = BatteryState( + level: level, + isCharging: isCharging, + isPluggedIn: sourceState == kIOPSACPowerValue + ) + + + if newState != currentState { + currentState = newState + } + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/DesktopManager.swift b/submissions/sapphire/Sapphire/Services/System/DesktopManager.swift new file mode 100644 index 00000000..30d1d75b --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/DesktopManager.swift @@ -0,0 +1,38 @@ +// +// DesktopManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import AppKit +import Combine + +class DesktopManager: ObservableObject { + + @Published private(set) var currentDesktopNumber: Int? + + init() { + + self.currentDesktopNumber = CGSHelper.getActiveDesktopNumber() + + + NSWorkspace.shared.notificationCenter.addObserver( + self, + selector: #selector(activeSpaceDidChange), + name: NSWorkspace.activeSpaceDidChangeNotification, + object: nil + ) + } + + @objc private func activeSpaceDidChange() { + DispatchQueue.main.async { + + self.currentDesktopNumber = CGSHelper.getActiveDesktopNumber() + } + } + + deinit { + NSWorkspace.shared.notificationCenter.removeObserver(self) + } +} diff --git a/submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift b/submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift new file mode 100644 index 00000000..1735d1b2 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift @@ -0,0 +1,81 @@ +// +// FocusModeManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import Foundation +import Combine +import Intents + + + +class FocusModeManager: ObservableObject { + + + @Published private(set) var currentFocusMode: FocusModeInfo? + + private var timer: Timer? + + init() { + + + INFocusStatusCenter.default.requestAuthorization { status in + + guard status == .authorized else { + return + } + + + DispatchQueue.main.async { + self.timer = Timer.scheduledTimer(withTimeInterval: 100, repeats: true) { [weak self] _ in + self?.checkFocusState() + } + + self.checkFocusState() + } + } + } + + + private func checkFocusState() { + + let isFocused = INFocusStatusCenter.default.focusStatus.isFocused + + + + let newMode: FocusModeInfo? = (isFocused == true) ? getActiveFocusDetails() : nil + + + if self.currentFocusMode != newMode { + DispatchQueue.main.async { + self.currentFocusMode = newMode + if let mode = newMode { + } else { + } + } + } + } + + + + private func getActiveFocusDetails() -> FocusModeInfo? { + let dndServiceDefaults = UserDefaults(suiteName: "com.apple.do-not-disturb-service") + + guard let preferences = dndServiceDefaults?.persistentDomain(forName: "com.apple.do-not-disturb-service"), + let assertionDetails = preferences["assertionDetails"] as? [[String: Any]], + let activeModeDict = assertionDetails.first, + let name = activeModeDict["name"] as? String, + let identifier = activeModeDict["identifier"] as? String else { + + return FocusModeInfo(name: "Do Not Disturb", identifier: "moon.fill") + } + + return FocusModeInfo(name: name, identifier: identifier) + } + + deinit { + timer?.invalidate() + } +} diff --git a/submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift b/submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift new file mode 100644 index 00000000..b24ce631 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift @@ -0,0 +1,174 @@ +// +// WeatherService.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import Foundation +import CoreLocation +import SwiftUI + +class WeatherService: NSObject, CLLocationManagerDelegate { + private let locationManager = CLLocationManager() + private var completionHandler: ((Result) -> Void)? + + private let weatherAPIKey = "e45ff1b7c7bda231216c7ab7c33509b8" + + private static let apiDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" + formatter.locale = Locale(identifier: "en_US_POSIX") + return formatter + }() + + private static let displayTimeFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.timeStyle = .short + return formatter + }() + + private static let hourlyTimeFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateFormat = "ha" + return formatter + }() + + override init() { + super.init() + locationManager.delegate = self + locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers + } + + public func fetchWeather(completion: @escaping (Result) -> Void) { + self.completionHandler = completion + + if !CLLocationManager.locationServicesEnabled() { + let error = NSError(domain: "WeatherService", code: 3, userInfo: [NSLocalizedDescriptionKey: "Location services are disabled system-wide."]) + completionHandler?(.failure(error)) + return + } + + switch locationManager.authorizationStatus { + case .authorized, .authorizedAlways: + locationManager.requestLocation() + case .denied, .restricted: + let error = NSError(domain: "WeatherService", code: 2, userInfo: [NSLocalizedDescriptionKey: "Location access was denied. Please enable it in System Settings."]) + completionHandler?(.failure(error)) + case .notDetermined: + locationManager.requestLocation() + @unknown default: + let error = NSError(domain: "WeatherService", code: 99, userInfo: [NSLocalizedDescriptionKey: "Unknown location authorization status."]) + completionHandler?(.failure(error)) + } + } + + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + guard let location = locations.last else { return } + locationManager.stopUpdatingLocation() + fetchAPIs(for: location) + } + + func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { + completionHandler?(.failure(error)) + } + + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { + fetchWeather(completion: self.completionHandler ?? { _ in }) + } + + private func fetchAPIs(for location: CLLocation) { + let lat = location.coordinate.latitude + let lon = location.coordinate.longitude + let urlString = "https://api.weather.com/v1/geocode/\(lat)/\(lon)/aggregate.json?apiKey=\(weatherAPIKey)&products=conditionsshort,fcstdaily10short,fcsthourly24short,nowlinks" + + guard let url = URL(string: urlString) else { + let error = NSError(domain: "WeatherService", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) + completionHandler?(.failure(error)) + return + } + + Task { + do { + let placemarks = try await CLGeocoder().reverseGeocodeLocation(location) + let locationName = placemarks.first?.locality ?? placemarks.first?.name ?? "Unknown Location" + + let (data, _) = try await URLSession.shared.data(from: url) + + let decoder = JSONDecoder() + let apiResponse = try decoder.decode(WeatherApiResponse.self, from: data) + + let processedData = self.process(response: apiResponse, locationName: locationName) + self.completionHandler?(.success(processedData)) + + } catch { + self.completionHandler?(.failure(error)) + } + } + } + + private func process(response: WeatherApiResponse, locationName: String) -> ProcessedWeatherData { + let observation = response.conditionsshort?.observation + let todayForecast = response.fcstdaily10short?.forecasts?.first + + let uiDailyForecasts: [DailyForecastUIData] = response.fcstdaily10short?.forecasts?.prefix(7).compactMap { forecast in + guard let dow = forecast.dow, + let maxTemp = forecast.imperial?.max_temp, let minTemp = forecast.imperial?.min_temp, + let maxTempMetric = forecast.metric?.max_temp, let minTempMetric = forecast.metric?.min_temp else { + return nil + } + return DailyForecastUIData( + dayOfWeek: String(dow.prefix(3)).uppercased(), + iconName: WeatherIconMapper.map(from: forecast.day?.icon_cd ?? 44), + highTemp: maxTemp, + lowTemp: minTemp, + highTempMetric: maxTempMetric, + lowTempMetric: minTempMetric + ) + } ?? [] + + let uiHourlyForecasts: [HourlyForecastUIData] = response.fcsthourly24short?.forecasts?.prefix(8).compactMap { forecast in + guard let gmt = forecast.fcst_valid, let icon = forecast.icon_cd, + let tempImperial = forecast.imperial?.temp, + let tempMetric = forecast.metric?.temp else { + return nil + } + let date = Date(timeIntervalSince1970: TimeInterval(gmt)) + return HourlyForecastUIData( + time: Self.hourlyTimeFormatter.string(from: date).uppercased(), + iconName: WeatherIconMapper.map(from: icon), + temperature: "\(tempImperial)°", + temperatureMetric: "\(tempMetric)°" + ) + } ?? [] + + return ProcessedWeatherData( + locationName: locationName, + temperature: observation?.imperial?.temp ?? 0, + temperatureMetric: observation?.metric?.temp ?? 0, + highTemp: todayForecast?.imperial?.max_temp ?? 0, + highTempMetric: todayForecast?.metric?.max_temp ?? 0, + lowTemp: todayForecast?.imperial?.min_temp ?? 0, + lowTempMetric: todayForecast?.metric?.min_temp ?? 0, + conditionDescription: observation?.wx_phrase ?? "Unavailable", + iconCode: observation?.wx_icon ?? 44, + feelsLike: observation?.imperial?.feels_like ?? 0, + feelsLikeMetric: observation?.metric?.feels_like ?? 0, + windInfo: "\(observation?.imperial?.wspd ?? 0) mph", + humidity: "\(observation?.rh ?? 0)%", + precipChance: todayForecast?.day?.pop ?? 0, + uvIndex: "\(observation?.uv_index ?? 0) (\(observation?.uv_desc ?? "N/A"))", + sunriseTime: formatTime(from: todayForecast?.sunrise), + sunsetTime: formatTime(from: todayForecast?.sunset), + visibility: observation?.vis != nil ? "\(Int(observation!.vis!)) mi" : "-- mi", + pressure: observation?.pressure != nil ? "\(String(format: "%.2f", observation!.pressure! * 0.02953)) in" : "-- in", + dailyForecasts: uiDailyForecasts, + hourlyForecasts: uiHourlyForecasts + ) + } + + private func formatTime(from dateString: String?) -> String { + guard let dateString = dateString, let date = Self.apiDateFormatter.date(from: dateString) else { return "--:--" } + return Self.displayTimeFormatter.string(from: date) + } +} diff --git a/submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift b/submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift new file mode 100644 index 00000000..b30c5e36 --- /dev/null +++ b/submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift @@ -0,0 +1,102 @@ +// +// WeatherViewModel.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI +import CoreLocation + +class WeatherViewModel: ObservableObject { + private let weatherService = WeatherService() + private let settingsModel = SettingsModel() + + + @Published var locationName: String = "Loading..." + @Published var temperature: String = "—°" + @Published var conditionDescription: String = "Fetching..." + @Published var highLowTemp: String = "H: —° L: —°" + @Published var feelsLike: String = "—°" + @Published var windInfo: String = "— mph" + @Published var humidity: String = "—%" + @Published var uvIndex: String = "—" + @Published var visibility: String = "—" + @Published var pressure: String = "—" + @Published var precipChance: String = "—%" + @Published var iconName: String = "icloud" + @Published var gradientColors: [Color] = [.blue.opacity(0.8), .purple.opacity(0.8)] + @Published var hourlyForecasts: [HourlyForecastUIData] = [] + + init() { + fetch() + Timer.scheduledTimer(withTimeInterval: 60 * 15, repeats: true) { [weak self] _ in + self?.fetch() + } + } + + + func fetch() { + weatherService.fetchWeather { [weak self] result in + DispatchQueue.main.async { + switch result { + case .success(let data): + self?.updateUI(with: data) + case .failure(let error): + self?.handleError(error) + } + } + } + } + + + private func updateUI(with data: ProcessedWeatherData) { + let useCelsius = settingsModel.settings.weatherUseCelsius + + self.locationName = data.locationName + self.temperature = useCelsius ? "\(data.temperatureMetric)°" : "\(data.temperature)°" + self.conditionDescription = data.conditionDescription + self.highLowTemp = useCelsius ? "H: \(data.highTempMetric)° L: \(data.lowTempMetric)°" : "H: \(data.highTemp)° L: \(data.lowTemp)°" + self.feelsLike = useCelsius ? "\(data.feelsLikeMetric)°" : "\(data.feelsLike)°" + self.windInfo = data.windInfo + self.humidity = data.humidity + self.uvIndex = data.uvIndex + self.visibility = data.visibility + self.pressure = data.pressure + self.precipChance = "\(data.precipChance)%" + self.iconName = WeatherIconMapper.map(from: data.iconCode) + self.hourlyForecasts = data.hourlyForecasts + self.gradientColors = gradientColors(for: data.iconCode) + } + + private func handleError(_ error: Error) { + self.locationName = "Error" + self.temperature = "—°" + self.conditionDescription = "Failed to load" + self.highLowTemp = "H: —° L: —°" + self.feelsLike = "—°" + self.windInfo = "— mph" + self.humidity = "—%" + self.uvIndex = "—" + self.visibility = "—" + self.pressure = "—" + self.precipChance = "—%" + self.iconName = "exclamationmark.triangle.fill" + self.gradientColors = [.gray, .black.opacity(0.8)] + self.hourlyForecasts = [] + } + + + private func gradientColors(for iconCode: Int) -> [Color] { + switch iconCode { + case 31, 32, 33, 34, 36: return [Color("#4A90E2"), Color("#81C7F4")] + case 27, 28, 29, 30: return [Color("#5D7A98"), Color("#8E9EAE")] + case 26: return [Color("#8E9EAE"), Color("#B4C1CC")] + case 3, 4, 37, 38, 47: return [Color("#2c3e50"), Color("#465868")] + case 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 35, 39, 40, 45: return [Color("#5A7D9A"), Color("#829AB1")] + case 13, 14, 15, 16, 41, 42, 43, 46: return [Color("#B4C1CC"), Color("#E0E6EB")] + case 19, 20, 21, 22: return [Color("#95A5A6"), Color("#BDC3C7")] + default: return [Color("#4A90E2"), Color("#81C7F4")] + } + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift new file mode 100644 index 00000000..7dcd10c8 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift @@ -0,0 +1,170 @@ +// +// CalendarWidgetView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import SwiftUI + + +struct CenterDateInfo: Equatable { + let date: Date + let distance: CGFloat +} +struct CenterDatePreferenceKey: PreferenceKey { + typealias Value = CenterDateInfo? + static var defaultValue: Value = nil + static func reduce(value: inout Value, nextValue: () -> Value) { + guard let next = nextValue() else { return } + if value == nil || next.distance < value!.distance { + value = next + } + } +} + + +@available(macOS 14.0, *) +struct CalendarWidgetView: View { + @StateObject private var viewModel = InteractiveCalendarViewModel() + + var body: some View { + HStack(alignment: .top, spacing: 10) { + Text(viewModel.selectedMonthAbbreviated) + .font(.system(size: 28, weight: .bold, design: .rounded)) + .lineLimit(1) + .minimumScaleFactor(0.6) + .frame(width: 55, alignment: .leading) + .padding(.top, 4) + .id("Month-\(viewModel.selectedMonthAbbreviated)") + .transition(.asymmetric( + insertion: .opacity.combined(with: .offset(y: -10)), + removal: .opacity.combined(with: .offset(y: 10)) + )) + + VStack(alignment: .leading, spacing: 8) { + interactiveCalendar() + eventsView + } + } + .padding(.horizontal, 12) + .padding(.vertical, 10) + .frame(width: 240, height: 100) + .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) + .foregroundColor(.white) + .environmentObject(viewModel) + } + + private func interactiveCalendar() -> some View { + ScrollViewReader { proxy in + GeometryReader { containerProxy in + let itemWidth: CGFloat = 28 + let itemSpacing: CGFloat = 10 + let horizontalPadding = (containerProxy.size.width / 2) - (itemWidth / 2) + + ScrollView(.horizontal, showsIndicators: false) { + LazyHStack(spacing: itemSpacing) { + ForEach(viewModel.dates, id: \.self) { date in + DynamicDayView( + date: date, + containerMidX: containerProxy.frame(in: .global).midX + ) + .id(date) + .onTapGesture { + + HapticManager.perform(.generic) + + withAnimation(.spring(response: 0.3, dampingFraction: 0.75)) { + viewModel.selectDate(date) + proxy.scrollTo(date, anchor: .center) + } + } + } + } + .padding(.horizontal, horizontalPadding) + } + .onPreferenceChange(CenterDatePreferenceKey.self) { centerInfo in + if let newDate = centerInfo?.date, !newDate.isSameDay(as: viewModel.selectedDate) { + + HapticManager.perform(.alignment) + + withAnimation(.easeInOut(duration: 0.1)) { + viewModel.selectDate(newDate) + } + } + } + .onAppear { + proxy.scrollTo(viewModel.today, anchor: .center) + } + } + .frame(height: 38) + } + } + + private var eventsView: some View { + HStack(spacing: 6) { + Image(systemName: "calendar.badge.checkmark") + .font(.system(size: 12)) + .foregroundColor(.gray) + Text("Nothing for today") + .font(.system(size: 13, weight: .medium)) + .foregroundColor(.gray) + } + .frame(maxWidth: .infinity) + } +} + + + +struct DynamicDayView: View { + let date: Date + let containerMidX: CGFloat + + @EnvironmentObject private var viewModel: InteractiveCalendarViewModel + + var body: some View { + let isSelected = date.isSameDay(as: viewModel.selectedDate) + let dayName = date.format(as: isSelected ? "EEE" : "EEEEE").uppercased() + + GeometryReader { itemProxy in + let itemMidX = itemProxy.frame(in: .global).midX + let distance = itemMidX - containerMidX + + let absDistance = abs(distance) + let focusFactor = max(0, 1 - (absDistance / 80)) + + let scale = 0.7 + (focusFactor * 0.7) + let opacity = 0.5 + (focusFactor * 0.5) + let blur = (1 - focusFactor) * 1.5 + let rotationAngle = Angle.degrees(Double(distance / 10)) + + let baseColor = date.isWeekend ? Color.red.opacity(0.8) : Color.white.opacity(0.8) + let finalColor = baseColor.lerp(to: .blue, t: focusFactor) + let dayLetterColor = Color.gray.lerp(to: .blue, t: focusFactor) + + VStack(spacing: 3) { + Text(dayName) + .font(.system(size: 10, weight: .semibold, design: .rounded)) + .foregroundColor(dayLetterColor) + .id(dayName) + .transition( + .asymmetric( + insertion: .offset(y: 10).combined(with: .opacity), + removal: .offset(y: -10).combined(with: .opacity) + ) + ) + + Text(date.format(as: "d")) + .font(.system(size: 13, weight: .bold, design: .rounded)) + .foregroundColor(finalColor) + } + .scaleEffect(scale) + .blur(radius: blur) + .opacity(opacity) + .rotation3DEffect(rotationAngle, axis: (x: 0, y: 1, z: 0), perspective: 0.5) + .frame(width: itemProxy.size.width, height: itemProxy.size.height) + .preference(key: CenterDatePreferenceKey.self, value: CenterDateInfo(date: date, distance: absDistance)) + } + .frame(width: 28) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift b/submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift new file mode 100644 index 00000000..51d079df --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift @@ -0,0 +1,23 @@ +// +// ScrollOffsetPreferenceKey.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import SwiftUI + + +struct DayFrame: Equatable { + let id: Date + let frame: CGRect +} + + +struct DayFramesPreferenceKey: PreferenceKey { + static var defaultValue: [DayFrame] = [] + + static func reduce(value: inout [DayFrame], nextValue: () -> [DayFrame]) { + value.append(contentsOf: nextValue()) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift new file mode 100644 index 00000000..351ce439 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift @@ -0,0 +1,126 @@ +// +// LyricsView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import SwiftUI + + +struct LyricLineView: View { + let lyric: LyricLine + let isCurrent: Bool + let accentColor: Color + + var body: some View { + VStack(alignment: .center, spacing: 6) { + Text(lyric.text) + .font(.system(size: 26, weight: .bold)) + .multilineTextAlignment(.center) + .foregroundColor(isCurrent ? accentColor : .primary) + .shadow(radius: 5) + + if let translated = lyric.translatedText, !translated.isEmpty { + Text(translated) + .font(.system(size: 18, weight: .medium)) + .multilineTextAlignment(.center) + .foregroundColor(isCurrent ? accentColor : .secondary) + .opacity(isCurrent ? 0.8 : 0.6) + } + } + .scaleEffect(isCurrent ? 1.0 : 0.90) + .opacity(isCurrent ? 1.0 : 0.5) + .animation(.spring(response: 0.6, dampingFraction: 0.7), value: isCurrent) + } +} + + +struct LyricsView: View { + + var lyrics: [LyricLine] + var currentLyricID: UUID? + var accentColor: Color + var onDismiss: () -> Void + + + private let lineSpacing: CGFloat = 70.0 + + + var body: some View { + GeometryReader { geometry in + let computedOffset = calculateScrollOffset(fullViewHeight: geometry.size.height) + + ZStack(alignment: .top) { + if lyrics.isEmpty { + emptyLyricsView + .frame(maxWidth: .infinity, maxHeight: .infinity) + } else { + VStack(spacing: 0) { + ForEach(lyrics) { lyric in + LyricLineView( + lyric: lyric, + isCurrent: lyric.id == currentLyricID, + accentColor: accentColor + ) + .frame(height: lineSpacing) + } + } + .frame(width: geometry.size.width) + .offset(y: computedOffset) + .animation(.spring(response: 0.8, dampingFraction: 0.8), value: computedOffset) + } + } + .mask { + + let viewHeight = geometry.size.height + + if viewHeight > 0 { + let fadeLength: CGFloat = 5 + let fadePercentage = fadeLength / viewHeight + + let solidStartLocation = min(fadePercentage, 0.5) + let solidEndLocation = max(1.0 - fadePercentage, 0.5) + + LinearGradient( + gradient: Gradient(stops: [ + + .init(color: .clear, location: 0.0), + + .init(color: .black, location: solidStartLocation), + + .init(color: .black, location: solidEndLocation), + + .init(color: .clear, location: 1.0) + ]), + startPoint: .top, + endPoint: .bottom + ) + } else { + Color.black + } + } + } + .frame(width: 400) + .onTapGesture(perform: onDismiss) + } + + + + private func calculateScrollOffset(fullViewHeight: CGFloat) -> CGFloat { + guard let currentIndex = lyrics.firstIndex(where: { $0.id == currentLyricID }) else { + let totalContentHeight = CGFloat(lyrics.count) * lineSpacing + return (fullViewHeight - totalContentHeight) / 2 + } + + let targetOffset = (fullViewHeight / 2) - (lineSpacing / 2) - (CGFloat(currentIndex) * lineSpacing) + return targetOffset + } + + + private var emptyLyricsView: some View { + Text("No lyrics available.") + .font(.headline) + .foregroundColor(.secondary) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift new file mode 100644 index 00000000..a9d41e55 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift @@ -0,0 +1,157 @@ +// +// MusicPlayerView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import SwiftUI +import AppKit + +struct MusicPlayerView: View { + @Binding var mode: NotchWidgetMode + @EnvironmentObject var musicWidget: MusicWidget + @EnvironmentObject var spotifyManager: SpotifyAPIManager + + @EnvironmentObject var liveActivityManager: LiveActivityManager + + private enum ActiveView { + case player, loginPrompt, queueAndPlaylists, devices, lyrics + } + @State private var activeView: ActiveView = .player + + + @State private var showLyrics: Bool = false + + + var body: some View { + ZStack(alignment: .topLeading) { + + ZStack { + switch activeView { + case .player: + playerView + .transition(.asymmetric( + insertion: .move(edge: .leading).combined(with: .opacity), + removal: .move(edge: .trailing).combined(with: .opacity)) + ) + case .loginPrompt: + LoginPromptView(onDismiss: { dismissSubView() }) + .transition(.asymmetric( + insertion: .scale(scale: 0.9).combined(with: .opacity), + removal: .scale(scale: 0.9).combined(with: .opacity)) + ) + case .queueAndPlaylists: + QueueAndPlaylistsView(onDismiss: { dismissSubView() }) + .transition(.asymmetric( + insertion: .move(edge: .trailing).combined(with: .opacity), + removal: .move(edge: .leading).combined(with: .opacity)) + ) + case .devices: + DevicesView(onDismiss: { dismissSubView() }) + .transition(.asymmetric( + insertion: .move(edge: .trailing).combined(with: .opacity), + removal: .move(edge: .leading).combined(with: .opacity)) + ) + + case .lyrics: + LyricsView( + lyrics: musicWidget.lyrics, + currentLyricID: musicWidget.currentLyric?.id, + accentColor: musicWidget.accentColor, + onDismiss: { dismissSubView() } + ) + .transition(.asymmetric( + insertion: .scale(scale: 1.05).combined(with: .opacity), + removal: .scale(scale: 0.9).combined(with: .opacity)) + ) + } + } + .id(activeView) + .animation(.spring(response: 0.4, dampingFraction: 0.8), value: activeView) + } + + .onAppear { + liveActivityManager.showLyricsBinding = $showLyrics + } + .onChange(of: showLyrics) { shouldShow in + if shouldShow { + activeView = .lyrics + + showLyrics = false + } + } + } + + + private var playerView: some View { + VStack(spacing: 3) { + HStack(spacing: 12) { + Image(nsImage: musicWidget.artwork ?? NSImage(systemSymbolName: "waveform", accessibilityDescription: "Album art")!) + .resizable().aspectRatio(contentMode: .fit).frame(width: 60, height: 60) + .cornerRadius(8).shadow(color: musicWidget.accentColor.opacity(0.7), radius: 5) + VStack(alignment: .leading, spacing: 3) { + Text(musicWidget.title ?? "Title").font(.system(size: 16, weight: .semibold)).lineLimit(1) + Text(musicWidget.artist ?? "Artist").font(.system(size: 13)).foregroundColor(.secondary).lineLimit(1) + } + Spacer() + WaveformView().environmentObject(musicWidget).scaleEffect(1.3) + } + + HStack(alignment: .center, spacing: 8) { + Text(formatTime(musicWidget.currentElapsedTime)) + InteractiveProgressBar( + value: $musicWidget.playbackProgress, + gradient: Gradient(colors: [musicWidget.leftGradientColor, musicWidget.rightGradientColor]), + onSeek: { [musicWidget] newProgress in + let seekTime = newProgress * musicWidget.totalDuration + if seekTime.isFinite && musicWidget.totalDuration > 0 { musicWidget.seek(to: seekTime) } + } + ).frame(height: 30).shadow(color: musicWidget.accentColor.opacity(0.5), radius: 8, y: 3) + Text("-\(formatTime(musicWidget.totalDuration - musicWidget.currentElapsedTime))") + }.font(.system(size: 10, weight: .medium, design: .monospaced)).foregroundColor(.secondary) + + + if let lyricText = (musicWidget.currentLyric?.translatedText ?? musicWidget.currentLyric?.text), + !lyricText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + Text(lyricText).font(.system(size: 12, weight: .medium)).foregroundColor(musicWidget.accentColor) + .multilineTextAlignment(.center).lineLimit(2).frame(minHeight: 35, alignment: .center) + .transition(.opacity.animation(.easeInOut(duration: 0.3))).id(musicWidget.currentLyric?.id) + .contentShape(Rectangle()) + .onTapGesture { + + activeView = .lyrics + } + } + + HStack { + Button(action: { handleButtonTap(for: .queueAndPlaylists) }) { Image(systemName: "list.bullet").font(.system(size: 20)) }.foregroundColor(.secondary).frame(width: 40, height: 40).contentShape(Rectangle()) + Spacer() + Button(action: { musicWidget.previousTrack() }) { Image(systemName: "backward.fill") }.frame(width: 44, height: 44).contentShape(Rectangle()) + Spacer() + Button(action: { musicWidget.isPlaying ? musicWidget.pause() : musicWidget.play() }) { Image(systemName: musicWidget.isPlaying ? "pause.fill" : "play.fill").font(.system(size: 28)) }.frame(width: 44, height: 44).contentShape(Rectangle()) + Spacer() + Button(action: { musicWidget.nextTrack() }) { Image(systemName: "forward.fill") }.frame(width: 44, height: 44).contentShape(Rectangle()) + Spacer() + Button(action: { handleButtonTap(for: .devices) }) { Image(systemName: "hifispeaker").font(.system(size: 18)) }.foregroundColor(.secondary).frame(width: 40, height: 40).contentShape(Rectangle()) + }.buttonStyle(BlurButtonStyle()).font(.system(size: 22)).foregroundColor(.primary) + .padding(.top, musicWidget.currentLyric == nil ? 10 : 0) + .padding(.bottom, musicWidget.currentLyric == nil ? 5 : 0) + } + .frame(width: 400).padding(10) + .animation(.easeInOut(duration: 0.3), value: musicWidget.currentLyric) + } + + + private func handleButtonTap(for view: ActiveView) { + if spotifyManager.isAuthenticated { activeView = view } + else { activeView = .loginPrompt } + } + + private func dismissSubView() { activeView = .player } + private func formatTime(_ seconds: Double) -> String { + let cleanSeconds = seconds.isNaN || seconds.isInfinite ? 0 : seconds + let (minutes, seconds) = (Int(cleanSeconds) / 60, Int(cleanSeconds) % 60) + return String(format: "%d:%02d", minutes, seconds) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift new file mode 100644 index 00000000..864c6eda --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift @@ -0,0 +1,150 @@ +// +// MusicWidgetView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import SwiftUI +import AppKit + +struct MusicWidgetView: View { + @EnvironmentObject var musicWidget: MusicWidget + @EnvironmentObject var settings: SettingsModel + @Binding var mode: NotchWidgetMode + @State private var isHoveringArtwork = false + + var body: some View { + + if let title = musicWidget.title, !title.isEmpty { + + HStack(alignment: .center, spacing: 16) { + albumArtWithOverlay + + VStack(alignment: .leading, spacing: 8) { + MusicInfoView( + title: musicWidget.title, + album: musicWidget.album, + artist: musicWidget.artist + ) + + MusicControlsView( + isPlaying: musicWidget.isPlaying, + onPrevious: musicWidget.previousTrack, + onPlayPause: { musicWidget.isPlaying ? musicWidget.pause() : musicWidget.play() }, + onNext: musicWidget.nextTrack + ) + } + .frame(maxWidth: .infinity, alignment: .leading) + } + .frame(height: 100) + .frame(maxWidth: 300) + .fixedSize() + } else { + + OpenPlayerView( + player: settings.settings.defaultMusicPlayer, + action: openDefaultPlayer + ) + } + } + + private var albumArtWithOverlay: some View { + Image(nsImage: musicWidget.artwork ?? NSImage(systemSymbolName: "waveform", accessibilityDescription: "Album art")!) + .resizable().aspectRatio(contentMode: .fill) + .frame(width: 100, height: 100).cornerRadius(30) + .shadow(color: musicWidget.accentColor.opacity(0.7), radius: 8, y: 5) + .overlay(alignment: .bottomLeading) { + if let icon = musicWidget.appIcon { + Image(nsImage: icon).resizable().aspectRatio(contentMode: .fit) + .frame(width: 22, height: 22).clipShape(Circle()).padding(6) + } + } + .onHover { hovering in + self.isHoveringArtwork = hovering + if hovering { HapticManager.perform(.alignment) } + } + .onTapGesture { mode = .musicPlayer } + } + + + private func openDefaultPlayer() { + let player = settings.settings.defaultMusicPlayer + let bundleId = player == .appleMusic ? "com.apple.Music" : "com.spotify.client" + NSWorkspace.shared.launchApplication(bundleId) + } +} + + +private struct OpenPlayerView: View { + let player: DefaultMusicPlayer + let action: () -> Void + + var body: some View { + VStack(spacing: 12) { + Image(systemName: "music.note") + .font(.system(size: 40, weight: .light)) + .foregroundColor(.white.opacity(0.8)) + + Button(action: action) { + Text("Open \(player.displayName)") + .font(.system(size: 14, weight: .medium)) + .foregroundColor(.white) + .padding(.horizontal, 16) + .padding(.vertical, 8) + .background(Color.white.opacity(0.15)) + .clipShape(Capsule()) + } + .buttonStyle(.plain) + } + .frame(width: 300, height: 100) + } +} + + +private struct MusicInfoView: View { + let title: String? + let album: String? + let artist: String? + + var body: some View { + VStack(alignment: .leading, spacing: 4) { + if let title = title, !title.isEmpty { + Text(title) + .font(.system(size: 17, weight: .semibold)) + } + + if let album = album, !album.isEmpty, album != title { + Text(album) + .font(.system(size: 14, weight: .medium)) + } + if let artist = artist, !artist.isEmpty { + Text(artist) + .font(.system(size: 13, weight: .regular)) + .foregroundColor(.white.opacity(0.7)) + } + } + .foregroundStyle(.white) + .lineLimit(1) + .minimumScaleFactor(0.8) + } +} + + +private struct MusicControlsView: View { + let isPlaying: Bool + let onPrevious: () -> Void + let onPlayPause: () -> Void + let onNext: () -> Void + + var body: some View { + HStack(spacing: 18) { + Button(action: onPrevious) { Image(systemName: "backward.end.fill") } + Button(action: onPlayPause) { Image(systemName: isPlaying ? "pause.fill" : "play.fill").font(.system(size: 20, weight: .semibold)) } + Button(action: onNext) { Image(systemName: "forward.end.fill") } + } + .buttonStyle(BlurButtonStyle()) + .font(.system(size: 16)) + .foregroundColor(.white) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift new file mode 100644 index 00000000..b1d65e14 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift @@ -0,0 +1,127 @@ +// +// DevicesView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import SwiftUI + +struct DevicesView: View { + var onDismiss: () -> Void + @EnvironmentObject var spotifyManager: SpotifyAPIManager + + @State private var devices: [SpotifyDevice] = [] + @State private var isLoading = true + @State private var volume: Double = 75 + @State private var debouncer = Debouncer(delay: 0.2) + + var body: some View { + VStack(spacing: 15) { + + + if isLoading { + ProgressView().frame(maxHeight: .infinity) + } else if spotifyManager.isPremiumUser { + premiumUserView + } else { + freeUserView + } + } + .padding(20).onAppear { Task { await fetchInitialData() } } + } + + private var premiumUserView: some View { + VStack { + if devices.contains(where: { $0.isActive }) { + VolumeControl(volume: $volume) + .onChange(of: volume) { newValue in + debouncer.debounce { Task { _ = await spotifyManager.setVolume(percent: Int(newValue)) } } + } + } + ScrollView { + VStack(spacing: 8) { + ForEach(devices) { device in + DeviceRow(device: device, isActive: device.isActive) + .onTapGesture { + guard !device.isActive, let deviceId = device.id else { return } + Task { _ = await spotifyManager.transferPlayback(to: deviceId); await fetchInitialData() } + } + } + } + } + } + } + + private var freeUserView: some View { + VStack(spacing: 20) { + Text("Local Volume Control").font(.headline) + VolumeControl(volume: $volume) + .onChange(of: volume) { newValue in + debouncer.debounce { Task { _ = await spotifyManager.setVolume(percent: Int(newValue)) } } + } + VStack(spacing: 8) { + Image(systemName: "exclamationmark.lock.fill").font(.largeTitle).foregroundColor(.yellow) + Text("Device Switching Requires Premium").font(.headline) + Text("You can control the volume of your local Spotify app. To switch playback to other devices, a Premium account is required.").font(.subheadline).foregroundColor(.secondary).multilineTextAlignment(.center) + }.padding().background(.thinMaterial).cornerRadius(16) + Spacer() + } + } + + private func fetchInitialData() async { + if spotifyManager.isPremiumUser { + let allDevices = await spotifyManager.fetchDevices() + let playbackState = await spotifyManager.fetchPlaybackState() + await MainActor.run { + self.devices = allDevices + if let currentVolume = playbackState?.device.volumePercent { self.volume = Double(currentVolume) } + self.isLoading = false + } + } else { + if let localVolume = spotifyManager.getLocalVolume() { await MainActor.run { self.volume = Double(localVolume) } } + await MainActor.run { self.isLoading = false } + } + } +} + + + +struct VolumeControl: View { + @Binding var volume: Double + var body: some View { + HStack(spacing: 10) { + Image(systemName: volume < 1 ? "speaker.slash.fill" : "speaker.wave.1.fill") + Slider(value: $volume, in: 0...100) + Image(systemName: volume > 66 ? "speaker.wave.3.fill" : "speaker.wave.2.fill") + } + .foregroundColor(.secondary).padding().background(.ultraThinMaterial).cornerRadius(16) + } +} + +struct DeviceRow: View { + let device: SpotifyDevice + let isActive: Bool + + var body: some View { + HStack { + Image(systemName: iconName(for: device.type)).font(.title2).frame(width: 30).foregroundColor(isActive ? .green : .primary) + Text(device.name).fontWeight(isActive ? .semibold : .regular) + Spacer() + if isActive { Image(systemName: "speaker.wave.2.fill").foregroundColor(.green) } + } + .padding().background(.thinMaterial).cornerRadius(12) + .overlay(RoundedRectangle(cornerRadius: 12).stroke(isActive ? Color.green.opacity(0.7) : Color.secondary.opacity(0.2), lineWidth: 1.5)) + .scaleEffect(isActive ? 1.0 : 0.98).animation(.spring(response: 0.4, dampingFraction: 0.6), value: isActive) + } + + private func iconName(for type: String) -> String { + switch type.lowercased() { + case "computer": return "desktopcomputer" + case "speaker": return "hifispeaker.2.fill" + case "smartphone": return "iphone" + case "avr", "stb": return "tv.inset.filled" + default: return "questionmark.circle" + } + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift new file mode 100644 index 00000000..6f5663bd --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift @@ -0,0 +1,34 @@ +// +// LoginPromptView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import SwiftUI + +struct LoginPromptView: View { + var onDismiss: () -> Void + + var body: some View { + VStack(spacing: 20) { + Image("spotify-logo") + .resizable().aspectRatio(contentMode: .fit).frame(width: 80) + + Text("Connect to Spotify") + .font(.title2).bold() + + Text("Log in to control playback, see your queue, and manage devices.") + .font(.subheadline).foregroundColor(.secondary).multilineTextAlignment(.center) + + Button("Log in with Spotify") { + SpotifyAPIManager.shared.login() + } + .buttonStyle(.borderedProminent).tint(.green) + + Button("Not Now", action: onDismiss) + .buttonStyle(.plain).foregroundColor(.secondary) + } + .padding(30) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift new file mode 100644 index 00000000..14a06f3b --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift @@ -0,0 +1,112 @@ +// +// PlaylistView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import SwiftUI + +struct PlaylistView: View { + + var onDismiss: () -> Void + var onSelectPlaylist: (SpotifyPlaylist) -> Void + + + @State private var playlists: [SpotifyPlaylist] = [] + @State private var isLoading = true + + var body: some View { + VStack(spacing: 0) { + + HStack { + Text("Your Playlists") + .font(.system(size: 18, weight: .bold)) + Spacer() + Button(action: onDismiss) { + Image(systemName: "xmark.circle.fill") + .font(.title2) + .foregroundStyle(.secondary, .tertiary) + } + .buttonStyle(PlainButtonStyle()) + } + .padding([.top, .horizontal], 20) + .padding(.bottom, 15) + + + ZStack { + if isLoading { + ProgressView() + .progressViewStyle(CircularProgressViewStyle()) + .scaleEffect(1.5) + .frame(maxHeight: .infinity) + } else if playlists.isEmpty { + Text("No playlists found.") + .foregroundColor(.secondary) + .frame(maxHeight: .infinity) + } else { + + ScrollView { + LazyVStack(spacing: 12) { + ForEach(playlists) { playlist in + PlaylistRow(playlist: playlist) + .onTapGesture { + onSelectPlaylist(playlist) + } + } + } + .padding(.horizontal, 20) + .padding(.bottom, 20) + } + } + } + } + .onAppear(perform: fetchPlaylists) + } + + private func fetchPlaylists() { + Task { + + let fetchedPlaylists = await SpotifyAPIManager.shared.fetchPlaylists() + + + await MainActor.run { + self.playlists = fetchedPlaylists + self.isLoading = false + } + } + } +} + + +struct PlaylistRow: View { + let playlist: SpotifyPlaylist + + var body: some View { + HStack(spacing: 12) { + + + ZStack { + Color.secondary.opacity(0.3) + Image(systemName: "music.note.list") + .font(.title2) + .foregroundColor(.white.opacity(0.8)) + } + .frame(width: 50, height: 50) + .cornerRadius(6) + + VStack(alignment: .leading, spacing: 3) { + Text(playlist.name) + .font(.system(size: 15, weight: .semibold)) + .lineLimit(1) + Text("By \(playlist.owner.displayName)") + .font(.system(size: 12)) + .foregroundColor(.secondary) + .lineLimit(1) + } + } + .padding(8) + .background(Color.white.opacity(0.05)) + .cornerRadius(10) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift new file mode 100644 index 00000000..fa489ad8 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift @@ -0,0 +1,218 @@ +// +// QueueAndPlaylistsView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import SwiftUI + + +struct CustomUnavailableView: View { + let title: String + let systemImage: String + var description: String? = nil + + var body: some View { + VStack(spacing: 12) { + Image(systemName: systemImage).font(.largeTitle).foregroundColor(.secondary.opacity(0.7)) + Text(title).font(.headline).foregroundColor(.primary) + if let description = description { + Text(description).font(.subheadline).foregroundColor(.secondary).multilineTextAlignment(.center).padding(.horizontal) + } + }.frame(maxHeight: .infinity) + } +} + + +struct QueueAndPlaylistsView: View { + var onDismiss: () -> Void + @State private var selection: Int = 0 + @State private var queue: SpotifyQueue? + @State private var playlists: [SpotifyPlaylist] = [] + @State private var isLoading = true + @State private var showSpotifyNotOpenAlert = false + + var body: some View { + VStack(spacing: 15) { + + HStack { + Button(action: onDismiss) { Image(systemName: "chevron.left"); Text("Back") } + .buttonStyle(.plain).foregroundColor(.secondary) + Spacer() + }.font(.system(size: 18)) + + + HStack(spacing: 10) { + TabButton(title: "Queue", systemImage: "list.bullet.rectangle", isSelected: selection == 0) { selection = 0 } + TabButton(title: "Playlists", systemImage: "music.note.list", isSelected: selection == 1) { selection = 1 } + } + + + if isLoading { + ProgressView().frame(maxHeight: .infinity) + } else { + if selection == 0 { queueView } + else { playlistsView } + } + + + } + .padding(20) + .onAppear(perform: fetchData) + .alert("Spotify App Is Not Open", isPresented: $showSpotifyNotOpenAlert) { + Button("OK", role: .cancel) { } + } message: { + Text("To control playback with a free account, please open the Spotify desktop app first.") + } + } + + private func fetchData() { + Task { + async let queueData = SpotifyAPIManager.shared.fetchQueue() + async let playlistsData = SpotifyAPIManager.shared.fetchPlaylists() + self.queue = await queueData + self.playlists = await playlistsData + self.isLoading = false + } + } + + + + private var queueView: some View { + ScrollView { + if let queue = queue, let nowPlaying = queue.currentlyPlaying { + VStack(alignment: .leading, spacing: 18) { + SectionHeader(title: "Now Playing") + QueueTrackRow(track: nowPlaying, onPlay: handlePlaybackResult) + + if !queue.queue.isEmpty { + SectionHeader(title: "Next Up") + ForEach(queue.queue) { track in + QueueTrackRow(track: track, onPlay: handlePlaybackResult) + } + } else { + CustomUnavailableView(title: "No Songs Up Next", systemImage: "music.note.list", description: "Add songs to your queue in the Spotify app to see them here.").padding(.top, 20) + } + } + } else { + CustomUnavailableView(title: "Queue Unavailable", systemImage: "speaker.slash.fill", description: "Start playing music in Spotify and ensure you have a Premium account to view your queue.") + } + } + } + + private var playlistsView: some View { + ScrollView { + if !playlists.isEmpty { + VStack(spacing: 10) { + ForEach(playlists) { playlist in + FullPlaylistRow(playlist: playlist, onPlay: handlePlaybackResult) + } + } + } else { + CustomUnavailableView(title: "No Playlists Found", systemImage: "music.mic") + } + } + } + + private func handlePlaybackResult(_ result: PlaybackResult) { + switch result { + case .requiresSpotifyAppOpen: + showSpotifyNotOpenAlert = true + default: + break + } + } +} + +struct TabButton: View { + let title: String + let systemImage: String + let isSelected: Bool + let action: () -> Void + + var body: some View { + Button(action: action) { + HStack { + Image(systemName: systemImage) + Text(title) + } + .font(.system(size: 14, weight: .semibold)) + .padding(.horizontal, 16) + .padding(.vertical, 8) + + .contentShape(Capsule()) + } + .buttonStyle(.plain) + .background(isSelected ? Color.accentColor : .clear) + .foregroundColor(isSelected ? .white : .primary) + .clipShape(Capsule()) + .animation(.spring(response: 0.3, dampingFraction: 0.7), value: isSelected) + } +} + +struct SectionHeader: View { + let title: String + var body: some View { Text(title).font(.headline).foregroundColor(.secondary).padding(.leading, 5) } +} + +struct QueueTrackRow: View { + let track: SpotifyTrack + var onPlay: (PlaybackResult) -> Void + @State private var isHovered = false + + var body: some View { + HStack(spacing: 12) { + AsyncImage(url: track.imageURL) { $0.resizable() } placeholder: { ZStack { Color.secondary.opacity(0.3); Image(systemName: "music.note") } } + .frame(width: 45, height: 45).cornerRadius(6) + .overlay( + ZStack { + if isHovered { + Color.black.opacity(0.5) + Image(systemName: "play.fill").font(.title3).foregroundColor(.white) + } + }.cornerRadius(6) + ) + VStack(alignment: .leading) { Text(track.name).fontWeight(.medium).lineLimit(1); Text(track.artists.map(\.name).joined(separator: ", ")).font(.subheadline).foregroundColor(.secondary).lineLimit(1) } + Spacer() + } + .padding(8).background(.thinMaterial).cornerRadius(10) + + .onHover { hovering in + self.isHovered = hovering + } + .onTapGesture { performPlayback() } + + .animation(.easeInOut(duration: 0.15), value: isHovered) + } + + private func performPlayback() { + Task { + let result = await SpotifyAPIManager.shared.playTrack(uri: track.uri) + onPlay(result) + } + } +} + +struct FullPlaylistRow: View { + let playlist: SpotifyPlaylist + var onPlay: (PlaybackResult) -> Void + var body: some View { + HStack(spacing: 12) { + AsyncImage(url: playlist.imageURL) { $0.resizable() } placeholder: { ZStack { Color.secondary.opacity(0.3); Image(systemName: "music.note.list") } } + .frame(width: 45, height: 45).cornerRadius(6) + VStack(alignment: .leading) { Text(playlist.name).fontWeight(.medium).lineLimit(1); Text("By \(playlist.owner.displayName)").font(.subheadline).foregroundColor(.secondary).lineLimit(1) } + Spacer() + Image(systemName: "chevron.right").foregroundColor(.secondary) + } + .padding(8).background(.thinMaterial).cornerRadius(10) + .onTapGesture { performPlayback() } + } + + private func performPlayback() { + Task { + let result = await SpotifyAPIManager.shared.playPlaylist(contextUri: playlist.uri) + onPlay(result) + } + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift new file mode 100644 index 00000000..ca607fb0 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift @@ -0,0 +1,72 @@ +// +// SpotifyPlaybackManager.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import Foundation + + +class SpotifyPlaybackManager { + static let shared = SpotifyPlaybackManager() + + + + private var localPlayer: LibrespotSession? + + init() { + + + self.localPlayer = LibrespotSession() + } + + + func play(trackUri: String) { + let spotifyManager = SpotifyAPIManager.shared + + + if spotifyManager.isPremiumUser { + + + Task { + await spotifyManager.playTrack(uri: trackUri) + } + } else { + + + + + localPlayer?.play(uri: trackUri) + } + } + + + func play(contextUri: String) { + let spotifyManager = SpotifyAPIManager.shared + + if spotifyManager.isPremiumUser { + Task { + await spotifyManager.playPlaylist(contextUri: contextUri) + } + } else { + localPlayer?.play(contextUri: contextUri) + } + } +} + + + +struct LibrespotSession { + func play(uri: String) { + + + + + + + } + + func play(contextUri: String) { + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift b/submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift new file mode 100644 index 00000000..89b80ee6 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift @@ -0,0 +1,229 @@ +// +// NearDropProgressView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-05. +// + +import SwiftUI +import NearbyShare + + + +struct NearDropProgressView: View { + @StateObject private var nearbyManager = NearbyConnectionManager.shared + @EnvironmentObject var liveActivityManager: LiveActivityManager + + + @State private var isShowing = false + + private var allDisplayableTransfers: [TransferProgressInfo] { + let pending = nearbyManager.pendingTransfers.values.sorted { $0.id > $1.id } + let active = nearbyManager.transfers + return pending + active + } + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + HeaderView() + + + + Group { + if allDisplayableTransfers.isEmpty { + EmptyStateView() + .transition(.opacity.combined(with: .scale(scale: 0.95))) + } else { + ScrollView { + + LazyVStack(spacing: 8) { + ForEach(allDisplayableTransfers) { transfer in + ModernTransferRowView(transfer: transfer) + .transition(.opacity) + } + } + .padding(8) + } + .transition(.opacity) + } + } + + .animation(.spring(response: 0.3, dampingFraction: 0.8), value: allDisplayableTransfers.isEmpty) + } + .frame(width: 400) + .frame(maxHeight: 500) + .fixedSize(horizontal: false, vertical: true) + + .background(Color(red: 0.1, green: 0.1, blue: 0.21), in: RoundedRectangle(cornerRadius: 28, style: .continuous)) + .environmentObject(liveActivityManager) + + .scaleEffect(isShowing ? 1 : 0.98) + .opacity(isShowing ? 1 : 0) + .padding(.top, 1) + .onAppear { + withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) { + isShowing = true + } + } + } +} + + + + +private struct HeaderView: View { + var body: some View { + HStack { + Image(privateName: "shareplay") + .font(.system(size: 20, weight: .semibold)) + .foregroundColor(.primary) + + Text("AirDrops") + .font(.headline) + .fontWeight(.bold) + + Spacer() + } + .padding(16) + .background(.black.opacity(0.3)) + + + } +} + +private struct EmptyStateView: View { + var body: some View { + VStack(spacing: 12) { + Image(systemName: "tray") + .font(.system(size: 40, weight: .light)) + .foregroundColor(.secondary) + Text("No Active Transfers") + .font(.headline) + .foregroundColor(.secondary) + } + .frame(maxWidth: .infinity, minHeight: 150) + .padding() + } +} + + + + +private struct ModernTransferRowView: View { + let transfer: TransferProgressInfo + @EnvironmentObject var liveActivityManager: LiveActivityManager + + var body: some View { + HStack(spacing: 12) { + ZStack { + Circle().fill(Color.accentColor.opacity(0.15)) + Image(systemName: transfer.iconName).font(.title3).foregroundColor(.accentColor) + }.frame(width: 44, height: 44) + + VStack(alignment: .leading, spacing: 2) { + Text(transfer.deviceName).font(.callout).fontWeight(.semibold).lineLimit(1) + Text(transfer.fileDescription).font(.caption).foregroundColor(.secondary).lineLimit(1) + } + Spacer(minLength: 8) + + + trailingItem + .animation(.spring(response: 0.3, dampingFraction: 0.8), value: transfer.state) + } + .padding(10) + .background(Color.black.opacity(0.1)) + .clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous)) + } + + @ViewBuilder + private var trailingItem: some View { + + switch transfer.state { + case .waiting: + IntegratedActionIconButtonsView(transfer: transfer) + .environmentObject(liveActivityManager) + .transition(.opacity.combined(with: .scale(scale: 0.9))) + case .inProgress: + CircularProgressIndicator(progress: transfer.progress) + .transition(.opacity.combined(with: .scale(scale: 0.9))) + case .finished: + Image(systemName: "checkmark.circle.fill").font(.title2).foregroundStyle(.green) + .transition(.opacity.combined(with: .scale(scale: 0.9))) + case .failed: + Image(systemName: "xmark.circle.fill").font(.title2).foregroundStyle(.red) + .transition(.opacity.combined(with: .scale(scale: 0.9))) + case .canceled: + Image(systemName: "xmark.circle.fill").font(.title2).foregroundStyle(.secondary) + .transition(.opacity.combined(with: .scale(scale: 0.9))) + } + } +} + + + +private struct IntegratedActionIconButtonsView: View { + let transfer: TransferProgressInfo + @EnvironmentObject var liveActivityManager: LiveActivityManager + + private func submitConsent(accept: Bool, action: NearDropUserAction = .save) { + liveActivityManager.clearNearDropActivity(id: transfer.id) + NearbyConnectionManager.shared.submitUserConsent(transferID: transfer.id, accept: accept, action: action) + } + + var body: some View { + HStack(spacing: 8) { + if transfer.iconName == "link" { + Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) + Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) + Button { submitConsent(accept: true, action: .open) } label: { Image(systemName: "arrow.up.right.square") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: true)) + } else if transfer.iconName == "text.quote" { + Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) + Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) + Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "square.and.arrow.down") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: true)) + } else { + Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) + Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "checkmark") } + .buttonStyle(ModernIconActionButtonStyle(isProminent: true)) + } + } + } +} + +private struct CircularProgressIndicator: View { + let progress: Double + var body: some View { + ZStack { + Circle().stroke(lineWidth: 4.0).opacity(0.2).foregroundColor(.secondary) + Circle().trim(from: 0.0, to: CGFloat(min(self.progress, 1.0))) + .stroke(style: StrokeStyle(lineWidth: 4.0, lineCap: .round, lineJoin: .round)) + .foregroundColor(.accentColor) + .rotationEffect(Angle(degrees: 270.0)) + Text("\(Int(progress * 100))%").font(.caption2).fontWeight(.bold).foregroundColor(.secondary) + } + .frame(width: 36, height: 36) + } +} + + + +private struct ModernIconActionButtonStyle: ButtonStyle { + var isProminent: Bool + + func makeBody(configuration: Configuration) -> some View { + configuration.label + .font(.system(size: 14, weight: .semibold)) + .foregroundColor(isProminent ? .white : .primary) + .frame(width: 32, height: 32) + .background(isProminent ? Color.accentColor : Color.secondary.opacity(0.25)) + .clipShape(Circle()) + .scaleEffect(configuration.isPressed ? 0.9 : 1.0) + .animation(.spring(response: 0.3, dampingFraction: 0.7), value: configuration.isPressed) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift new file mode 100644 index 00000000..e72f1366 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift @@ -0,0 +1,106 @@ +// +// NotchWidgetView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-26. +// + +import SwiftUI + +enum NotchWidgetMode { + case defaultWidgets + case musicPlayer + case nearDrop + case weatherPlayer +} + +struct NotchWidgetView: View { + @Binding var mode: NotchWidgetMode + + @StateObject private var settings = SettingsModel() + + @State private var showContent = false + + private var enabledAndOrderedWidgets: [WidgetType] { + let orderedTypes = settings.settings.widgetOrder + + return orderedTypes.filter { widgetType in + switch widgetType { + case .music: + return settings.settings.musicWidgetEnabled + case .weather: + return settings.settings.weatherWidgetEnabled + case .calendar: + return settings.settings.calendarWidgetEnabled + case .shortcuts: + return settings.settings.shortcutsWidgetEnabled + } + } + } + + var body: some View { + Group { + switch mode { + case .defaultWidgets: + AnyView( + HStack(spacing: 0) { + ForEach(enabledAndOrderedWidgets) { widgetType in + widgetView(for: widgetType) + } + } + ) + .blur(radius: showContent ? 0 : 8) + .opacity(showContent ? 1 : 0) + .scaleEffect(showContent ? 1 : 0.98) + + case .musicPlayer: + AnyView( + + MusicPlayerView(mode: $mode) + .environmentObject(settings) + ) + .blur(radius: showContent ? 0 : 8) + .opacity(showContent ? 1 : 0) + + case .nearDrop: + AnyView(NearDropProgressView()) + .blur(radius: showContent ? 0 : 8) + .opacity(showContent ? 1 : 0) + + case .weatherPlayer: + AnyView( + + WeatherPlayerView(mode: $mode) + .environmentObject(settings) + ) + .blur(radius: showContent ? 0 : 8) + .opacity(showContent ? 1 : 0) + } + } + .padding(.top, NotchConfiguration.universalHeight - 10) + .padding(.horizontal, 10) + .onAppear { + withAnimation(.spring(response: 1.0, dampingFraction: 0.8)) { + showContent = true + } + } + .onDisappear { + showContent = false + } + } + + @ViewBuilder + private func widgetView(for widgetType: WidgetType) -> some View { + switch widgetType { + case .music: + MusicWidgetView(mode: $mode) + case .weather: + WeatherWidgetView(mode: $mode) + case .calendar: + CalendarWidgetView() + case .shortcuts: + + EmptyView() + } + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift new file mode 100644 index 00000000..ec0e9498 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift @@ -0,0 +1,134 @@ +// +// WeatherDetailView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI + + + +struct WeatherPlayerView: View { + @StateObject private var viewModel = WeatherViewModel() + @Binding var mode: NotchWidgetMode + + var body: some View { + ZStack(alignment: .topLeading) { + ZStack { + VStack(spacing: 0) { + + currentWeatherAndDetailsSection + .padding(.horizontal, 24) + .padding(.top, 20) + .padding(.bottom, 10) + + + hourlyForecastSection + .padding(.horizontal, 24) + .padding(.bottom, 30) + } + } + .frame(width: 560, height: 240) + .onAppear { + viewModel.fetch() + } + .animation(.spring(response: 0.6, dampingFraction: 1, blendDuration: 0.2), value: viewModel.temperature) + .animation(.easeInOut(duration: 0.8), value: viewModel.gradientColors.first) + + } + } + + private var currentWeatherAndDetailsSection: some View { + HStack(alignment: .top, spacing: 20) { + + Image(systemName: viewModel.iconName) + .font(.system(size: 88, weight: .thin)) + .symbolRenderingMode(.multicolor) + .shadow(color: .black.opacity(0.2), radius: 8, y: 4) + .frame(width: 100, height: 100) + .padding(10) + + + VStack(alignment: .leading, spacing: 4) { + Text(viewModel.locationName) + .font(.title2.weight(.semibold)) + .lineLimit(1) + + Text(viewModel.temperature) + .font(.system(size: 72, weight: .heavy, design: .rounded)) + .lineLimit(1) + .minimumScaleFactor(0.6) + + Text(viewModel.conditionDescription.capitalized) + .font(.title3).fontWeight(.medium) + .lineLimit(1) + + + VStack(alignment: .leading, spacing: 2) { + HStack(spacing: 8) { + Text(viewModel.highLowTemp) + } + .font(.callout).fontWeight(.medium) + .opacity(0.8) + + HStack(spacing: 12) { + HStack(spacing: 4) { + Image(systemName: "thermometer.medium") + .font(.caption) + Text("Feels: \(viewModel.feelsLike)") + } + HStack(spacing: 4) { + Image(systemName: "wind") + .font(.caption) + Text("Wind: \(viewModel.windInfo)") + } + } + .font(.subheadline).fontWeight(.regular) + .opacity(0.7) + } + .padding(.top, 8) + } + Spacer() + } + .frame(maxHeight: .infinity, alignment: .topLeading) + } + + private var hourlyForecastSection: some View { + VStack(alignment: .leading, spacing: 8) { + Text("HOURLY FORECAST") + .font(.caption2.weight(.bold)) + .opacity(0.6) + .kerning(0.5) + .padding(.horizontal, 12) + + HStack(spacing: 18) { + ForEach(viewModel.hourlyForecasts) { forecast in + HourlyForecastCell(forecast: forecast) + } + } + } + .frame(height: 80) + } +} + + + +private struct HourlyForecastCell: View { + let forecast: HourlyForecastUIData + @EnvironmentObject private var settings: SettingsModel + + var body: some View { + VStack(spacing: 4) { + Text(forecast.time) + .font(.caption2).fontWeight(.medium) + .opacity(0.8) + Image(systemName: forecast.iconName) + .font(.title2).symbolRenderingMode(.multicolor) + .frame(height: 28) + Text(settings.settings.weatherUseCelsius ? forecast.temperatureMetric : forecast.temperature) + .font(.subheadline).fontWeight(.semibold) + } + .frame(width: 50) + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift new file mode 100644 index 00000000..ba6f2c70 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift @@ -0,0 +1,100 @@ +// +// WeatherIconMapper.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-30. +// + +import Foundation + + +struct WeatherIconMapper { + + + + + static func map(from code: Int) -> String { + switch code { + + case 0: return "tornado" + case 1: return "tropicalstorm" + case 2: return "hurricane" + case 3: return "cloud.bolt.rain.fill" + case 4: return "cloud.bolt.rain.fill" + + + case 5: return "cloud.sleet.fill" + case 6: return "cloud.sleet.fill" + case 7: return "cloud.sleet.fill" + case 8: return "cloud.hail.fill" + case 10: return "thermometer.snowflake" + + + case 9: return "cloud.drizzle.fill" + case 11: return "cloud.rain.fill" + case 12: return "cloud.heavyrain.fill" + case 40: return "cloud.heavyrain.fill" + case 35: return "cloud.hail.fill" + + + case 13: return "cloud.snow.fill" + case 14: return "cloud.snow.fill" + case 15: return "wind.snow" + case 16: return "snowflake" + case 42: return "cloud.snow.fill" + case 43: return "snowflake" + + + case 17: return "cloud.hail.fill" + case 18: return "cloud.sleet.fill" + + + case 19: return "wind" + case 20: return "cloud.fog.fill" + case 21: return "sun.haze.fill" + case 22: return "smoke.fill" + + + case 23: return "wind" + case 24: return "wind" + + + case 25: return "thermometer.snowflake" + + + case 26: return "cloud.fill" + + + case 27: return "cloud.moon.fill" + case 29: return "cloud.moon.fill" + case 31: return "moon.stars.fill" + case 33: return "moon.fill" + + + case 28: return "cloud.sun.fill" + case 30: return "cloud.sun.fill" + case 32: return "sun.max.fill" + case 34: return "sun.min.fill" + + + case 37: return "cloud.sun.bolt.fill" + case 38: return "cloud.sun.rain.fill" + case 39: return "cloud.sun.rain.fill" + case 41: return "cloud.sun.rain.fill" + + + case 45: return "cloud.moon.rain.fill" + case 46: return "cloud.moon.rain.fill" + case 47: return "cloud.moon.bolt.fill" + + + case 36: return "sun.max.trianglebadge.exclamationmark" + + + case 44: return "questionmark.circle" + + default: + return "questionmark.circle" + } + } +} diff --git a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift new file mode 100644 index 00000000..7aed0c88 --- /dev/null +++ b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift @@ -0,0 +1,97 @@ +// +// WeatherWidgetView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-06-27. +// + +import SwiftUI + +struct WeatherWidgetView: View { + @StateObject private var viewModel = WeatherViewModel() + @Binding var mode: NotchWidgetMode + + var body: some View { + Button(action: { + withAnimation(.spring(response: 0.4, dampingFraction: 0.8)) { + mode = .weatherPlayer + } + }) { + HStack(alignment: .center, spacing: 0) { + primaryInfo.layoutPriority(1) + secondaryInfo + } + .frame(width: 250, height: 100) + } + .buttonStyle(.plain) + .onAppear { + viewModel.fetch() + } + } + + private var primaryInfo: some View { + HStack(spacing: 8) { + Image(systemName: viewModel.iconName) + .font(.system(size: 44)) + .symbolRenderingMode(.multicolor) + .shadow(radius: 2) + .minimumScaleFactor(0.8) + .id(viewModel.iconName) + .transition(.opacity) + + VStack(alignment: .leading, spacing: 2) { + Text(viewModel.temperature) + .font(.system(size: 42, weight: .bold, design: .rounded)) + .minimumScaleFactor(0.5) + .id(viewModel.temperature) + .transition(.opacity) + + Text(viewModel.locationName) + .font(.headline).fontWeight(.medium).lineLimit(1).minimumScaleFactor(0.7) + .id(viewModel.locationName) + .transition(.opacity) + + Text(viewModel.conditionDescription) + .font(.subheadline).opacity(0.8).lineLimit(1).minimumScaleFactor(0.7) + .id(viewModel.conditionDescription) + .transition(.opacity) + } + + .animation(.easeInOut(duration: 0.4), value: viewModel.locationName) + } + } + + private var secondaryInfo: some View { + VStack(alignment: .trailing, spacing: 4) { + CompactInfoRow(iconName: "wind", value: viewModel.windInfo) + CompactInfoRow(iconName: "drop.fill", value: viewModel.precipChance) + CompactInfoRow(iconName: "humidity.fill", value: viewModel.humidity) + } + + .animation(.easeInOut(duration: 0.4), value: viewModel.windInfo) + } +} + + +struct CompactInfoRow: View { + let iconName: String + let value: String + + var body: some View { + HStack(spacing: 5) { + Image(systemName: iconName) + .font(.callout) + .frame(width: 20) + .symbolRenderingMode(.hierarchical) + .opacity(0.8) + + Text(value) + .font(.system(.subheadline, design: .rounded)) + .fontWeight(.semibold) + .lineLimit(1) + .minimumScaleFactor(0.7) + } + .id(value) + .transition(.opacity) + } +} From cbaef8760576869d3a87f7b3039f1bc42b978081 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 15:34:12 -0400 Subject: [PATCH 04/16] Update README.md --- submissions/sapphire/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/submissions/sapphire/README.md b/submissions/sapphire/README.md index 8b137891..cefb8a17 100644 --- a/submissions/sapphire/README.md +++ b/submissions/sapphire/README.md @@ -1 +1,15 @@ +**Name**: Sapphire +**Description**: This app is focused on providing power tools for mac. It can show multiple live activities such as music, weather, eye break reminders and more. + +**GitHub URL**: [Sapphire Github](https://github.com/cshariq/Sapphire) + +**How did you build this**: I used Swift UI to build the app, in Xcode. Nearby Share functionailty has been cloned from [NearDrop Github](https://github.com/grishka/NearDrop), I did add some functionality though. + +**How many hours did you spend on this**: 168 hours + +**Did you use #arcade to log your progress?**: No + +**Testflight link**: Unsigned Release can be downloaded from the github. [Download beta](https://github.com/cshariq/Sapphire/releases/tag/Pre-Release) + +**Video Demo URL**: [Youtube](https://youtu.be/5Uk3lqt-vDc) From 4df271b696436700d3d5549be619defbb2190176 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:43:19 -0400 Subject: [PATCH 05/16] Delete submissions/sapphire/Protobuf-Inputs.xcfilelist --- submissions/sapphire/Protobuf-Inputs.xcfilelist | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 submissions/sapphire/Protobuf-Inputs.xcfilelist diff --git a/submissions/sapphire/Protobuf-Inputs.xcfilelist b/submissions/sapphire/Protobuf-Inputs.xcfilelist deleted file mode 100644 index f75fe5a8..00000000 --- a/submissions/sapphire/Protobuf-Inputs.xcfilelist +++ /dev/null @@ -1,6 +0,0 @@ -${SRCROOT}/Packages/NearbyShare/ProtobufSource/device_to_device_messages.proto -${SRCROOT}/Packages/NearbyShare/ProtobufSource/offline_wire_formats.proto -${SRCROOT}/Packages/NearbyShare/ProtobufSource/securegcm.proto -${SRCROOT}/Packages/NearbyShare/ProtobufSource/securemessage.proto -${SRCROOT}/Packages/NearbyShare/ProtobufSource/ukey.proto -${SRCROOT}/Packages/NearbyShare/ProtobufSource/wire_format.proto From 1155c93b98ec9c5e2a0c74c4e84a45739aea86e2 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:43:29 -0400 Subject: [PATCH 06/16] Delete submissions/sapphire/Protobuf-Outputs.xcfilelist --- submissions/sapphire/Protobuf-Outputs.xcfilelist | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 submissions/sapphire/Protobuf-Outputs.xcfilelist diff --git a/submissions/sapphire/Protobuf-Outputs.xcfilelist b/submissions/sapphire/Protobuf-Outputs.xcfilelist deleted file mode 100644 index 28fd0d5f..00000000 --- a/submissions/sapphire/Protobuf-Outputs.xcfilelist +++ /dev/null @@ -1,6 +0,0 @@ -${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/device_to_device_messages.pb.swift -${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/offline_wire_formats.pb.swift -${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/securegcm.pb.swift -${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/securemessage.pb.swift -${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/ukey.pb.swift -${SRCROOT}/Packages/NearbyShare/Sources/NearbyShare/ProtobufGenerated/wire_format.pb.swift From c370f02f79b542b79df1d7ecdcfed0b731dedcbd Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:43:57 -0400 Subject: [PATCH 07/16] Delete submissions/sapphire/Nearby directory --- .../sapphire/Nearby/DeviceListCell.swift | 26 - .../Nearby/InboundNearbyConnection.swift | 291 ---------- .../Nearby/NWConnectionProtocol.swift | 38 -- .../Nearby/NearDropDisplayState.swift | 26 - .../sapphire/Nearby/NearbyConnection.swift | 468 --------------- .../Nearby/NearbyConnectionManager.swift | 536 ------------------ .../Nearby/OutboundNearbyConnection.swift | 449 --------------- .../sapphire/Nearby/ShareViewController.swift | 262 --------- .../sapphire/Nearby/TransferDirection.swift | 26 - 9 files changed, 2122 deletions(-) delete mode 100644 submissions/sapphire/Nearby/DeviceListCell.swift delete mode 100644 submissions/sapphire/Nearby/InboundNearbyConnection.swift delete mode 100644 submissions/sapphire/Nearby/NWConnectionProtocol.swift delete mode 100644 submissions/sapphire/Nearby/NearDropDisplayState.swift delete mode 100644 submissions/sapphire/Nearby/NearbyConnection.swift delete mode 100644 submissions/sapphire/Nearby/NearbyConnectionManager.swift delete mode 100644 submissions/sapphire/Nearby/OutboundNearbyConnection.swift delete mode 100644 submissions/sapphire/Nearby/ShareViewController.swift delete mode 100644 submissions/sapphire/Nearby/TransferDirection.swift diff --git a/submissions/sapphire/Nearby/DeviceListCell.swift b/submissions/sapphire/Nearby/DeviceListCell.swift deleted file mode 100644 index 2393dc43..00000000 --- a/submissions/sapphire/Nearby/DeviceListCell.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// DeviceListCell.swift -// ShareExtension -// -// Created by Grishka on 20.09.2023. -// - -import Cocoa - -class DeviceListCell: NSCollectionViewItem { - public var clickHandler: (() -> Void)? - - override func viewDidLoad() { - super.viewDidLoad() - if let btn = view as? NSButton { - btn.isEnabled = true - btn.setButtonType(.momentaryPushIn) - btn.action = #selector(onClick) - btn.target = self - } - } - - @IBAction func onClick(_ sender: Any?) { - clickHandler?() - } -} diff --git a/submissions/sapphire/Nearby/InboundNearbyConnection.swift b/submissions/sapphire/Nearby/InboundNearbyConnection.swift deleted file mode 100644 index 92232c06..00000000 --- a/submissions/sapphire/Nearby/InboundNearbyConnection.swift +++ /dev/null @@ -1,291 +0,0 @@ -// -// InboundNearbyConnection.swift -// NearDrop -// -// Created by Grishka on 08.04.2023. -// - -import Foundation -import Network -import CryptoKit -import CommonCrypto -import System -import AppKit -import SwiftECC -import BigInt - -protocol InboundNearbyConnectionDelegate { - func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, fileURLs: [URL]) - func connection(_ connection: InboundNearbyConnection, didUpdateProgress progress: Double) - func connectionWasTerminated(connection: InboundNearbyConnection, error: Error?) -} - -class InboundNearbyConnection: NearbyConnection { - private var currentState: State = .initial - public var delegate: InboundNearbyConnectionDelegate? - private var cipherCommitment: Data? - private var textPayloadID: Int64 = 0 - private var userAction: NearDropUserAction = .save - - enum State { - case initial, receivedConnectionRequest, sentUkeyServerInit, receivedUkeyClientFinish, sentConnectionResponse, sentPairedKeyResult, receivedPairedKeyResult, waitingForUserConsent, receivingFiles, disconnecting, disconnected - } - - override init(connection: NWConnection, id: String) { - super.init(connection: connection, id: id) - } - - override func handleConnectionClosure() { - // If the connection is closed by the peer before the transfer is finished, - // and we don't have a specific error, treat it as a cancellation. - // This handles cases where the sender cancels the transfer from their device or it times out. - if (currentState == .waitingForUserConsent || currentState == .receivingFiles) && lastError == nil { - lastError = NearbyError.canceled(reason: .userCanceled) - } - - super.handleConnectionClosure() - currentState = .disconnected - do { try deletePartiallyReceivedFiles() } catch { print("Error deleting partially received files: \(error)") } - DispatchQueue.main.async { self.delegate?.connectionWasTerminated(connection: self, error: self.lastError) } - } - - override internal func processReceivedFrame(frameData: Data) { - do { - switch currentState { - case .initial: try processConnectionRequestFrame(try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)) - case .receivedConnectionRequest: let msg = try Securegcm_Ukey2Message(serializedData: frameData); ukeyClientInitMsgData = frameData; try processUkey2ClientInit(msg) - case .sentUkeyServerInit: try processUkey2ClientFinish(try Securegcm_Ukey2Message(serializedData: frameData), raw: frameData) - case .receivedUkeyClientFinish: try processConnectionResponseFrame(try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)) - default: try decryptAndProcessReceivedSecureMessage(try Securemessage_SecureMessage(serializedData: frameData)) - } - } catch { lastError = error; print("Deserialization error: \(error) in state \(currentState)"); protocolError() } - } - - override internal func processTransferSetupFrame(_ frame: Sharing_Nearby_Frame) throws { - if frame.hasV1, frame.v1.hasType, case .cancel = frame.v1.type { print("Transfer canceled"); try sendDisconnectionAndDisconnect(); return } - switch currentState { - case .sentConnectionResponse: try processPairedKeyEncryptionFrame(frame) - case .sentPairedKeyResult: try processPairedKeyResultFrame(frame) - case .receivedPairedKeyResult: try processIntroductionFrame(frame) - case .receivingFiles: break // This is expected after accepting - default: print("Unexpected connection state in processTransferSetupFrame: \(currentState)\n\(frame)") - } - } - - override func isServer() -> Bool { return true } - - override func processFileChunk(frame: Location_Nearby_Connections_PayloadTransferFrame) throws { - let id = frame.payloadHeader.id - guard let fileInfo = transferredFiles[id] else { throw NearbyError.protocolError("File payload ID \(id) is not known") } - let currentOffset = fileInfo.bytesTransferred - guard frame.payloadChunk.offset == currentOffset else { throw NearbyError.protocolError("Invalid offset") } - guard currentOffset + Int64(frame.payloadChunk.body.count) <= fileInfo.meta.size else { throw NearbyError.protocolError("File size mismatch") } - - if !frame.payloadChunk.body.isEmpty { - fileInfo.fileHandle?.write(frame.payloadChunk.body) - transferredFiles[id]!.bytesTransferred += Int64(frame.payloadChunk.body.count) - fileInfo.progress?.completedUnitCount = transferredFiles[id]!.bytesTransferred - let progress = Double(transferredFiles[id]!.bytesTransferred) / Double(fileInfo.meta.size) - DispatchQueue.main.async { - self.delegate?.connection(self, didUpdateProgress: progress) - } - } - - if (frame.payloadChunk.flags & 1) == 1 { - try fileInfo.fileHandle?.close(); transferredFiles[id]!.fileHandle = nil; fileInfo.progress?.unpublish() - - if userAction == .copy { - if let fileContents = try? String(contentsOf: fileInfo.destinationURL, encoding: .utf8) { - NSPasteboard.general.clearContents() - NSPasteboard.general.setString(fileContents, forType: .string) - } - try? FileManager.default.removeItem(at: fileInfo.destinationURL) - } - - transferredFiles.removeValue(forKey: id) - if transferredFiles.isEmpty { - currentState = .disconnecting - try sendDisconnectionAndDisconnect() - } - } - } - - override func processBytesPayload(payload: Data, id: Int64) throws -> Bool { - if id == textPayloadID { - guard let textContent = String(data: payload, encoding: .utf8) else { - if userAction != .save { print("Received non-UTF8 payload for an action other than save. Saving as binary.") } - try saveBinaryPayload(payload) - return true - } - - switch self.userAction { - case .save: - try saveTextPayload(textContent) - case .open: - if let url = extractURL(from: textContent) { NSWorkspace.shared.open(url) } - else { print("Could not extract URL to open, saving as text instead."); try saveTextPayload(textContent) } - case .copy: - let textToCopy = extractURL(from: textContent)?.absoluteString ?? textContent - NSPasteboard.general.clearContents() - NSPasteboard.general.setString(textToCopy, forType: .string) - } - - currentState = .disconnecting - try sendDisconnectionAndDisconnect() - return true - } - return false - } - - private func processConnectionRequestFrame(_ frame: Location_Nearby_Connections_OfflineFrame) throws { - guard frame.hasV1, frame.v1.hasConnectionRequest, frame.v1.connectionRequest.hasEndpointInfo, case .connectionRequest = frame.v1.type else { throw NearbyError.protocolError("Invalid connection request frame") } - let endpointInfo = frame.v1.connectionRequest.endpointInfo - guard endpointInfo.count > 17 else { throw NearbyError.protocolError("Endpoint info too short") } - let deviceNameLength = Int(endpointInfo[17]); guard endpointInfo.count >= deviceNameLength + 18 else { throw NearbyError.protocolError("Endpoint info too short for name") } - guard let deviceName = String(data: endpointInfo[18..<(18 + deviceNameLength)], encoding: .utf8) else { throw NearbyError.protocolError("Device name is not valid UTF-8") } - let rawDeviceType = Int(endpointInfo[0] & 7) >> 1 - remoteDeviceInfo = RemoteDeviceInfo(name: deviceName, type: .fromRawValue(value: rawDeviceType)) - currentState = .receivedConnectionRequest - } - - private func processUkey2ClientInit(_ msg: Securegcm_Ukey2Message) throws { - guard msg.hasMessageType, msg.hasMessageData, case .clientInit = msg.messageType else { sendUkey2Alert(type: .badMessageType); throw NearbyError.ukey2 } - let clientInit = try Securegcm_Ukey2ClientInit(serializedData: msg.messageData) - guard clientInit.version == 1 else { sendUkey2Alert(type: .badVersion); throw NearbyError.ukey2 } - guard clientInit.random.count == 32 else { sendUkey2Alert(type: .badRandom); throw NearbyError.ukey2 } - guard let commitment = clientInit.cipherCommitments.first(where: { $0.handshakeCipher == .p256Sha512 }) else { sendUkey2Alert(type: .badHandshakeCipher); throw NearbyError.ukey2 } - cipherCommitment = commitment.commitment - guard clientInit.nextProtocol == "AES_256_CBC-HMAC_SHA256" else { sendUkey2Alert(type: .badNextProtocol); throw NearbyError.ukey2 } - - let domain = Domain.instance(curve: .EC256r1); let (pubKey, privKey) = domain.makeKeyPair(); publicKey = pubKey; privateKey = privKey - var serverInit = Securegcm_Ukey2ServerInit(); serverInit.version = 1; serverInit.random = Data.randomData(length: 32); serverInit.handshakeCipher = .p256Sha512 - var pkey = Securemessage_GenericPublicKey(); pkey.type = .ecP256; pkey.ecP256PublicKey.x = Data(pubKey.w.x.asSignedBytes()); pkey.ecP256PublicKey.y = Data(pubKey.w.y.asSignedBytes()); serverInit.publicKey = try pkey.serializedData() - var serverInitMsg = Securegcm_Ukey2Message(); serverInitMsg.messageType = .serverInit; serverInitMsg.messageData = try serverInit.serializedData() - let serverInitData = try serverInitMsg.serializedData(); ukeyServerInitMsgData = serverInitData; sendFrameAsync(serverInitData); currentState = .sentUkeyServerInit - } - - private func processUkey2ClientFinish(_ msg: Securegcm_Ukey2Message, raw: Data) throws { - guard msg.hasMessageType, msg.hasMessageData, case .clientFinish = msg.messageType else { throw NearbyError.ukey2 } - var sha = SHA512(); sha.update(data: raw); guard cipherCommitment == Data(sha.finalize()) else { throw NearbyError.ukey2 } - let clientFinish = try Securegcm_Ukey2ClientFinished(serializedData: msg.messageData) - try finalizeKeyExchange(peerKey: try Securemessage_GenericPublicKey(serializedData: clientFinish.publicKey)); currentState = .receivedUkeyClientFinish - } - - private func processConnectionResponseFrame(_ frame: Location_Nearby_Connections_OfflineFrame) throws { - guard frame.hasV1, frame.v1.hasType, case .connectionResponse = frame.v1.type else { return } - var resp = Location_Nearby_Connections_OfflineFrame(); resp.version = .v1; resp.v1.type = .connectionResponse; resp.v1.connectionResponse.response = .accept; resp.v1.connectionResponse.osInfo.type = .apple; sendFrameAsync(try resp.serializedData()) - encryptionDone = true; var pairedEncryption = Sharing_Nearby_Frame(); pairedEncryption.version = .v1; pairedEncryption.v1.type = .pairedKeyEncryption - pairedEncryption.v1.pairedKeyEncryption.secretIDHash = Data.randomData(length: 6); pairedEncryption.v1.pairedKeyEncryption.signedData = Data.randomData(length: 72); try sendTransferSetupFrame(pairedEncryption); currentState = .sentConnectionResponse - } - - private func processPairedKeyEncryptionFrame(_ frame: Sharing_Nearby_Frame) throws { - guard frame.hasV1, frame.v1.hasPairedKeyEncryption else { throw NearbyError.requiredFieldMissing("shareNearbyFrame.v1.pairedKeyEncryption") } - var pairedResult = Sharing_Nearby_Frame(); pairedResult.version = .v1; pairedResult.v1.type = .pairedKeyResult; pairedResult.v1.pairedKeyResult.status = .unable; try sendTransferSetupFrame(pairedResult); currentState = .sentPairedKeyResult - } - - private func processPairedKeyResultFrame(_ frame: Sharing_Nearby_Frame) throws { - guard frame.hasV1, frame.v1.hasPairedKeyResult else { throw NearbyError.requiredFieldMissing("shareNearbyFrame.v1.pairedKeyResult") } - currentState = .receivedPairedKeyResult - } - - private func processIntroductionFrame(_ frame: Sharing_Nearby_Frame) throws { - guard frame.hasV1, frame.v1.hasIntroduction else { throw NearbyError.requiredFieldMissing("shareNearbyFrame.v1.introduction") } - currentState = .waitingForUserConsent; - var destinationURLs: [URL] = [] - let downloadsDirectory = (try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: true)).resolvingSymlinksInPath() - var textDescription: String? - - if !frame.v1.introduction.fileMetadata.isEmpty { - let files = frame.v1.introduction.fileMetadata - for file in files { - let dest = makeFileDestinationURL(downloadsDirectory.appendingPathComponent(file.name)); destinationURLs.append(dest) - let info = InternalFileInfo(meta: .init(name: file.name, size: file.size, mimeType: file.mimeType), payloadID: file.payloadID, destinationURL: dest) - transferredFiles[file.payloadID] = info - } - if files.count == 1, let firstFile = files.first, (firstFile.mimeType == "text/plain" || firstFile.name.lowercased().hasSuffix(".txt")) { - textDescription = firstFile.name - } - let metadata = TransferMetadata(files: transferredFiles.values.map { $0.meta }, id: id, pinCode: pinCode, textDescription: textDescription) - DispatchQueue.main.async { self.delegate?.obtainUserConsent(for: metadata, from: self.remoteDeviceInfo!, fileURLs: destinationURLs) } - } else if let meta = frame.v1.introduction.textMetadata.first { - textPayloadID = meta.payloadID - let metadata = TransferMetadata(files: [], id: id, pinCode: pinCode, textDescription: meta.textTitle) - DispatchQueue.main.async { self.delegate?.obtainUserConsent(for: metadata, from: self.remoteDeviceInfo!, fileURLs: []) } - } else { - rejectTransfer(with: .unsupportedAttachmentType) - } - } - - private func makeFileDestinationURL(_ initialDest: URL) -> URL { - var dest = initialDest; var counter = 1 - if FileManager.default.fileExists(atPath: dest.path) { - let ext = dest.pathExtension; let baseUrl = dest.deletingPathExtension() - repeat { dest = URL(fileURLWithPath: "\(baseUrl.path) (\(counter))\(ext.isEmpty ? "" : ".\(ext)")"); counter += 1 } while FileManager.default.fileExists(atPath: dest.path) - } - return dest - } - - func submitUserConsent(accepted: Bool, action: NearDropUserAction) { - DispatchQueue.global(qos: .utility).async { - if accepted { self.userAction = action; self.acceptTransfer() } - else { self.rejectTransfer() } - } - } - - private func acceptTransfer() { - do { - if !transferredFiles.isEmpty { - for (id, file) in transferredFiles { - FileManager.default.createFile(atPath: file.destinationURL.path, contents: nil) - let handle = try FileHandle(forWritingTo: file.destinationURL); transferredFiles[id]!.fileHandle = handle - let progress = Progress(); progress.fileURL = file.destinationURL; progress.totalUnitCount = file.meta.size; progress.kind = .file; progress.isPausable = false; progress.publish(); transferredFiles[id]!.progress = progress - } - } - var frame = Sharing_Nearby_Frame(); frame.version = .v1; frame.v1.type = .response; frame.v1.connectionResponse.status = .accept; currentState = .receivingFiles; try sendTransferSetupFrame(frame) - } catch { lastError = error; protocolError() } - } - - private func rejectTransfer(with reason: Sharing_Nearby_ConnectionResponseFrame.Status = .reject) { - var frame = Sharing_Nearby_Frame(); frame.version = .v1; frame.v1.type = .response; frame.v1.connectionResponse.status = reason - do { - try sendTransferSetupFrame(frame) - if reason == .reject { - self.lastError = NearbyError.canceled(reason: .userRejected) - } - try sendDisconnectionAndDisconnect() - } catch { - print("Error \(error)") - protocolError() - } - } - - private func extractURL(from string: String) -> URL? { - do { - let detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) - if let match = detector.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) { - return match.url - } - } catch { - print("Error creating data detector: \(error.localizedDescription)") - } - return nil - } - - private func saveTextPayload(_ text: String) throws { - let downloadsDirectory = try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: true) - let dateFormatter = DateFormatter(); dateFormatter.dateFormat = "yyyy-MM-dd HH.mm.ss" - let dest = makeFileDestinationURL(downloadsDirectory.appendingPathComponent("Nearby Text \(dateFormatter.string(from: Date())).txt")) - try text.data(using: .utf8)?.write(to: dest) - } - - private func saveBinaryPayload(_ data: Data) throws { - let downloadsDirectory = try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: true) - let dateFormatter = DateFormatter(); dateFormatter.dateFormat = "yyyy-MM-dd HH.mm.ss" - let dest = makeFileDestinationURL(downloadsDirectory.appendingPathComponent("Nearby Data \(dateFormatter.string(from: Date())).bin")) - try data.write(to: dest) - } - - private func deletePartiallyReceivedFiles() throws { - for (_, file) in transferredFiles where file.created { try FileManager.default.removeItem(at: file.destinationURL) } - } -} diff --git a/submissions/sapphire/Nearby/NWConnectionProtocol.swift b/submissions/sapphire/Nearby/NWConnectionProtocol.swift deleted file mode 100644 index d1f6b765..00000000 --- a/submissions/sapphire/Nearby/NWConnectionProtocol.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// NWConnectionProtocol.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-02. -// - - -import Foundation -import Network // This is the ONLY file that will contain this import. - -// Create protocols that mirror the NWConnection and NWListener APIs -// This decouples our code from the Network framework itself. - -protocol NWConnectionProtocol { - init(to: NWEndpoint, using: NWParameters) - var stateUpdateHandler: ((NWConnection.State) -> Void)? { get set } - func start(queue: DispatchQueue) - func send(content: Data?, completion: NWConnection.SendCompletion) - func receive(minimumIncompleteLength: Int, maximumLength: Int, completion: @escaping (Data?, NWConnection.ContentContext?, Bool, NWError?) -> Void) - func cancel() -} - -protocol NWListenerProtocol { - init(using: NWParameters) throws - var stateUpdateHandler: ((NWListener.State) -> Void)? { get set } - var newConnectionHandler: ((NWConnection) -> Void)? { get set } - var port: NWEndpoint.Port? { get } - func start(queue: DispatchQueue) - func cancel() -} - -// Make the real classes conform to our protocols -extension NWConnection: NWConnectionProtocol {} -extension NWListener: NWListenerProtocol {} - -// We will now use `NWConnectionProtocol` and `NWListenerProtocol` -// throughout the NearbyShare code instead of the concrete types. \ No newline at end of file diff --git a/submissions/sapphire/Nearby/NearDropDisplayState.swift b/submissions/sapphire/Nearby/NearDropDisplayState.swift deleted file mode 100644 index 181bc3c3..00000000 --- a/submissions/sapphire/Nearby/NearDropDisplayState.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// NearDropDisplayState.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-02. -// - -import Foundation - -/// The different states a NearDrop transfer can be in for the UI. -enum NearDropDisplayState: Equatable { - case waitingForConsent - case inProgress - case finished - case failed(String) -} - -/// A clean, decoupled data structure for displaying the NearDrop live activity. -/// It has no dependency on the NearbyShare module. -struct NearDropDisplayPayload: Identifiable, Equatable { - let id: String // The unique transfer ID - let deviceName: String - let fileInfo: String - let pinCode: String? - var state: NearDropDisplayState = .waitingForConsent -} diff --git a/submissions/sapphire/Nearby/NearbyConnection.swift b/submissions/sapphire/Nearby/NearbyConnection.swift deleted file mode 100644 index da229ac3..00000000 --- a/submissions/sapphire/Nearby/NearbyConnection.swift +++ /dev/null @@ -1,468 +0,0 @@ -// -// NearbyConnection.swift -// NearDrop -// -// Created by Grishka on 09.04.2023. -// - -import Foundation -import Network -import CommonCrypto -import CryptoKit -import System - -import SwiftECC -import BigInt - -class NearbyConnection{ - internal static let SANE_FRAME_LENGTH=5*1024*1024 - private static let dispatchQueue=DispatchQueue(label: "me.grishka.NearDrop.queue", qos: .utility) // FIFO (non-concurrent) queue to avoid those exciting concurrency bugs - - internal let connection:NWConnection - internal var remoteDeviceInfo:RemoteDeviceInfo? - private var payloadBuffers:[Int64:NSMutableData]=[:] - internal var encryptionDone:Bool=false - internal var transferredFiles:[Int64:InternalFileInfo]=[:] - public let id:String - internal var lastError:Error? - private var connectionClosed:Bool=false - - // UKEY2-related state - internal var publicKey:ECPublicKey? - internal var privateKey:ECPrivateKey? - internal var ukeyClientInitMsgData:Data? - internal var ukeyServerInitMsgData:Data? - - // SecureMessage encryption keys - internal var decryptKey:[UInt8]? - internal var encryptKey:[UInt8]? - internal var recvHmacKey:SymmetricKey? - internal var sendHmacKey:SymmetricKey? - - // SecureMessage sequence numbers - private var serverSeq:Int32=0 - private var clientSeq:Int32=0 - - private(set) var pinCode:String? - - init(connection:NWConnection, id:String) { - self.connection=connection - self.id=id - } - - func start(){ - connection.stateUpdateHandler={state in - if case .ready = state { - self.connectionReady() - self.receiveFrameAsync() - } else if case .failed(let err) = state { - self.lastError=err - print("Error opening socket: \(err)") - self.handleConnectionClosure() - } - } - //connection.start(queue: .global(qos: .utility)) - connection.start(queue: NearbyConnection.dispatchQueue) - } - - func connectionReady(){} - - internal func handleConnectionClosure(){ - print("Connection closed") - } - - internal func protocolError(){ - disconnect() - } - - internal func processReceivedFrame(frameData:Data){ - fatalError() - } - - internal func processTransferSetupFrame(_ frame:Sharing_Nearby_Frame) throws{ - fatalError() - } - - internal func isServer() -> Bool{ - fatalError() - } - - internal func processFileChunk(frame:Location_Nearby_Connections_PayloadTransferFrame) throws{ - protocolError() - } - - internal func processBytesPayload(payload:Data, id:Int64)throws ->Bool{ - return false - } - - private func receiveFrameAsync(){ - connection.receive(minimumIncompleteLength: 4, maximumLength: 4) { content, contentContext, isComplete, error in - if self.connectionClosed{ - return - } - if isComplete{ - self.handleConnectionClosure() - return - } - if !(error==nil){ - self.lastError=error - self.protocolError() - return - } - guard let content=content else { - assertionFailure() - return - } - let frameLength:UInt32=UInt32(content[0]) << 24 | UInt32(content[1]) << 16 | UInt32(content[2]) << 8 | UInt32(content[3]) - guard frameLengthVoid)?=nil){ - if connectionClosed{ - return - } - var lengthPrefixedData=Data(capacity: frame.count+4) - let length:Int=frame.count - lengthPrefixedData.append(contentsOf: [ - UInt8(truncatingIfNeeded: length >> 24), - UInt8(truncatingIfNeeded: length >> 16), - UInt8(truncatingIfNeeded: length >> 8), - UInt8(truncatingIfNeeded: length) - ]) - lengthPrefixedData.append(frame) - connection.send(content: lengthPrefixedData, completion: .contentProcessed({ error in - if let completion=completion{ - completion() - } - })) - } - - internal func encryptAndSendOfflineFrame(_ frame:Location_Nearby_Connections_OfflineFrame, completion:(()->Void)?=nil) throws{ - var d2dMsg=Securegcm_DeviceToDeviceMessage() - serverSeq+=1 - d2dMsg.sequenceNumber=serverSeq - d2dMsg.message=try frame.serializedData() - - let serializedMsg=[UInt8](try d2dMsg.serializedData()) - let iv=Data.randomData(length: 16) - var encryptedData=Data(count: serializedMsg.count+16) - var encryptedLength:size_t=0 - encryptedData.withUnsafeMutableBytes({ - let status=CCCrypt( - CCOperation(kCCEncrypt), - CCAlgorithm(kCCAlgorithmAES128), - CCOptions(kCCOptionPKCS7Padding), - encryptKey, kCCKeySizeAES256, - [UInt8](iv), - serializedMsg, serializedMsg.count, - $0.baseAddress, $0.count, - &encryptedLength - ) - guard status==kCCSuccess else { fatalError("CCCrypt error: \(status)") } - }) - - var hb=Securemessage_HeaderAndBody() - hb.body=encryptedData.prefix(encryptedLength) - hb.header=Securemessage_Header() - hb.header.encryptionScheme = .aes256Cbc - hb.header.signatureScheme = .hmacSha256 - hb.header.iv=iv - var md=Securegcm_GcmMetadata() - md.type = .deviceToDeviceMessage - md.version=1 - hb.header.publicMetadata=try md.serializedData() - - var smsg=Securemessage_SecureMessage() - smsg.headerAndBody=try hb.serializedData() - smsg.signature=Data(HMAC.authenticationCode(for: smsg.headerAndBody, using: sendHmacKey!)) - sendFrameAsync(try smsg.serializedData(), completion: completion) - } - - internal func sendTransferSetupFrame(_ frame:Sharing_Nearby_Frame) throws{ - try sendBytesPayload(data: try frame.serializedData(), id: Int64.random(in: Int64.min...Int64.max)) - } - - internal func sendBytesPayload(data:Data, id:Int64) throws{ - var transfer=Location_Nearby_Connections_PayloadTransferFrame() - transfer.packetType = .data - transfer.payloadChunk.offset=0 - transfer.payloadChunk.flags=0 - transfer.payloadChunk.body=data - transfer.payloadHeader.id=id - transfer.payloadHeader.type = .bytes - transfer.payloadHeader.totalSize=Int64(transfer.payloadChunk.body.count) - transfer.payloadHeader.isSensitive=false - - var wrapper=Location_Nearby_Connections_OfflineFrame() - wrapper.version = .v1 - wrapper.v1=Location_Nearby_Connections_V1Frame() - wrapper.v1.type = .payloadTransfer - wrapper.v1.payloadTransfer=transfer - try encryptAndSendOfflineFrame(wrapper) - - transfer.payloadChunk.flags=1 // .lastChunk - transfer.payloadChunk.offset=Int64(transfer.payloadChunk.body.count) - transfer.payloadChunk.clearBody() - wrapper.v1.payloadTransfer=transfer - try encryptAndSendOfflineFrame(wrapper) - } - - internal func decryptAndProcessReceivedSecureMessage(_ smsg:Securemessage_SecureMessage) throws{ - guard smsg.hasSignature, smsg.hasHeaderAndBody else { throw NearbyError.requiredFieldMissing("secureMessage.signature|headerAndBody") } - let hmac=Data(HMAC.authenticationCode(for: smsg.headerAndBody, using: recvHmacKey!)) - guard hmac==smsg.signature else { throw NearbyError.protocolError("hmac!=signature") } - let headerAndBody=try Securemessage_HeaderAndBody(serializedData: smsg.headerAndBody) - var decryptedData=Data(count: headerAndBody.body.count) - - var decryptedLength:Int=0 - decryptedData.withUnsafeMutableBytes({ - let status=CCCrypt( - CCOperation(kCCDecrypt), - CCAlgorithm(kCCAlgorithmAES128), - CCOptions(kCCOptionPKCS7Padding), - decryptKey, kCCKeySizeAES256, - [UInt8](headerAndBody.header.iv), - [UInt8](headerAndBody.body), headerAndBody.body.count, - $0.baseAddress, $0.count, - &decryptedLength - ) - guard status==kCCSuccess else { fatalError("CCCrypt error: \(status)") } - }) - decryptedData=decryptedData.prefix(decryptedLength) - let d2dMsg=try Securegcm_DeviceToDeviceMessage(serializedData: decryptedData) - guard d2dMsg.hasMessage, d2dMsg.hasSequenceNumber else { throw NearbyError.requiredFieldMissing("d2dMessage.message|sequenceNumber") } - clientSeq+=1 - guard d2dMsg.sequenceNumber==clientSeq else { throw NearbyError.protocolError("Wrong sequence number. Expected \(clientSeq), got \(d2dMsg.sequenceNumber)") } - let offlineFrame=try Location_Nearby_Connections_OfflineFrame(serializedData: d2dMsg.message) - - if offlineFrame.hasV1 && offlineFrame.v1.hasType, case .payloadTransfer = offlineFrame.v1.type { - guard offlineFrame.v1.hasPayloadTransfer else { throw NearbyError.requiredFieldMissing("offlineFrame.v1.payloadTransfer") } - let payloadTransfer=offlineFrame.v1.payloadTransfer - let header=payloadTransfer.payloadHeader; - let chunk=payloadTransfer.payloadChunk; - guard header.hasType, header.hasID else { throw NearbyError.requiredFieldMissing("payloadHeader.type|id") } - guard payloadTransfer.hasPayloadChunk, chunk.hasOffset, chunk.hasFlags else { throw NearbyError.requiredFieldMissing("payloadTransfer.payloadChunk|offset|flags") } - if case .bytes = header.type{ - let payloadID=header.id - if header.totalSize > InboundNearbyConnection.SANE_FRAME_LENGTH { - payloadBuffers.removeValue(forKey: payloadID) - throw NearbyError.protocolError("Payload too large (\(header.totalSize) bytes)") - } - if payloadBuffers[payloadID]==nil { - payloadBuffers[payloadID]=NSMutableData(capacity: Int(header.totalSize)) - } - let buffer=payloadBuffers[payloadID]! - guard chunk.offset==buffer.count else { - payloadBuffers.removeValue(forKey: payloadID) - throw NearbyError.protocolError("Unexpected chunk offset \(chunk.offset), expected \(buffer.count)") - } - if chunk.hasBody { - buffer.append(chunk.body) - } - - if let inbound = self as? InboundNearbyConnection, header.totalSize > 0 { - let progress = Double(buffer.count) / Double(header.totalSize) - DispatchQueue.main.async { - inbound.delegate?.connection(inbound, didUpdateProgress: progress) - } - } - - if (chunk.flags & 1)==1 { - payloadBuffers.removeValue(forKey: payloadID) - if !(try processBytesPayload(payload: Data(buffer), id: payloadID)){ - let innerFrame=try Sharing_Nearby_Frame(serializedData: buffer as Data) - try processTransferSetupFrame(innerFrame) - } - } - }else if case .file = header.type{ - try processFileChunk(frame: payloadTransfer) - } - }else if offlineFrame.hasV1 && offlineFrame.v1.hasType, case .keepAlive = offlineFrame.v1.type{ - #if DEBUG - print("Sent keep-alive") - #endif - sendKeepAlive(ack: true) - }else{ - print("Unhandled offline frame encrypted: \(offlineFrame)") - } - } - - internal static func pinCodeFromAuthKey(_ key:SymmetricKey) -> String{ - var hash:Int=0 - var multiplier:Int=1 - let keyBytes:[UInt8]=key.withUnsafeBytes({ - return [UInt8]($0) - }) - - for _byte in keyBytes { - let byte=Int(Int8(bitPattern: _byte)) - hash=(hash+byte*multiplier)%9973 - multiplier=(multiplier*31)%9973 - } - - return String(format: "%04d", abs(hash)) - } - - internal static func hkdfExtract(salt:Data, ikm:Data) -> Data{ - return HMAC.authenticationCode(for: ikm, using: SymmetricKey(data: salt)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)}) - } - - internal static func hkdfExpand(prk:Data, info:Data, length:Int) -> Data{ - var okm=Data() - var t=Data() - var i=0 - while okm.count.authenticationCode(for: toDigest, using: SymmetricKey(data: prk)).withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)}) - okm=okm+t - } - return okm.subdata(in: 0.. SymmetricKey{ - if #available(macOS 11.0, *){ - return HKDF.deriveKey(inputKeyMaterial: inputKeyMaterial, salt: salt, info: info, outputByteCount: outputByteCount) - }else{ - return SymmetricKey(data: hkdfExpand(prk: hkdfExtract(salt: salt, ikm: inputKeyMaterial.withUnsafeBytes({return Data(bytes: $0.baseAddress!, count: $0.count)})), info: info, length: outputByteCount)) - } - } - - internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{ - guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing("peerKey.ecP256PublicKey") } - - let domain=Domain.instance(curve: .EC256r1) - var clientX=peerKey.ecP256PublicKey.x - var clientY=peerKey.ecP256PublicKey.y - if clientX.count>32{ - clientX=clientX.suffix(32) - } - if clientY.count>32{ - clientY=clientY.suffix(32) - } - let key=try ECPublicKey(domain: domain, w: Point(BInt(magnitude: [UInt8](clientX)), BInt(magnitude: [UInt8](clientY)))) - - let dhs=(try privateKey?.domain.multiplyPoint(key.w, privateKey!.s).x.asMagnitudeBytes())! - var sha=SHA256() - sha.update(data: dhs) - let derivedSecretKey=Data(sha.finalize()) - - var ukeyInfo=Data() - ukeyInfo.append(ukeyClientInitMsgData!) - ukeyInfo.append(ukeyServerInitMsgData!) - let authString=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32) - let nextSecret=NearbyConnection.hkdf(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32) - - pinCode=NearbyConnection.pinCodeFromAuthKey(authString) - - let salt:Data=Data([0x82, 0xAA, 0x55, 0xA0, 0xD3, 0x97, 0xF8, 0x83, 0x46, 0xCA, 0x1C, - 0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D, - 0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10]) - - let d2dClientKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32) - let d2dServerKey=NearbyConnection.hkdf(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32) - - sha=SHA256() - sha.update(data: "SecureMessage".data(using: .utf8)!) - let smsgSalt=Data(sha.finalize()) - - let clientKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)}) - let clientHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32) - let serverKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)}) - let serverHmacKey=NearbyConnection.hkdf(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32) - - if isServer(){ - decryptKey=clientKey - recvHmacKey=clientHmacKey - encryptKey=serverKey - sendHmacKey=serverHmacKey - }else{ - decryptKey=serverKey - recvHmacKey=serverHmacKey - encryptKey=clientKey - sendHmacKey=clientHmacKey - } - } - - internal func disconnect(){ - connection.send(content: nil, isComplete: true, completion: .contentProcessed({ error in - self.handleConnectionClosure() - })) - connectionClosed=true - } - - internal func sendDisconnectionAndDisconnect() throws{ - var offlineFrame=Location_Nearby_Connections_OfflineFrame() - offlineFrame.version = .v1 - offlineFrame.v1.type = .disconnection - offlineFrame.v1.disconnection=Location_Nearby_Connections_DisconnectionFrame() - - if encryptionDone{ - try encryptAndSendOfflineFrame(offlineFrame) - }else{ - sendFrameAsync(try offlineFrame.serializedData()) - } - disconnect() - } - - internal func sendUkey2Alert(type:Securegcm_Ukey2Alert.AlertType){ - var alert=Securegcm_Ukey2Alert() - alert.type=type - var msg=Securegcm_Ukey2Message() - msg.messageType = .alert - msg.messageData = try! alert.serializedData() - sendFrameAsync(try! msg.serializedData()) - disconnect() - } - - internal func sendKeepAlive(ack:Bool){ - var offlineFrame=Location_Nearby_Connections_OfflineFrame() - offlineFrame.version = .v1 - offlineFrame.v1.type = .keepAlive - offlineFrame.v1.keepAlive.ack=ack - - do{ - if encryptionDone{ - try encryptAndSendOfflineFrame(offlineFrame) - }else{ - sendFrameAsync(try offlineFrame.serializedData()) - } - }catch{ - print("Error sending KEEP_ALIVE: \(error)") - } - } -} - -struct InternalFileInfo{ - let meta:FileMetadata - let payloadID:Int64 - let destinationURL:URL - var bytesTransferred:Int64=0 - var fileHandle:FileHandle? - var progress:Progress? - var created:Bool=false -} diff --git a/submissions/sapphire/Nearby/NearbyConnectionManager.swift b/submissions/sapphire/Nearby/NearbyConnectionManager.swift deleted file mode 100644 index 84e503e1..00000000 --- a/submissions/sapphire/Nearby/NearbyConnectionManager.swift +++ /dev/null @@ -1,536 +0,0 @@ -// -// NearbyConnectionManager.swift -// NearDrop -// -// Created by Grishka on 08.04.2023. -// - -import Foundation -import Network -import System -import Combine - -public enum NearDropUserAction { - case save - case open - case copy -} - -public struct RemoteDeviceInfo{ - public let name:String - public let type:DeviceType - public var id:String? - - init(name: String, type: DeviceType, id: String? = nil) { - self.name = name - self.type = type - self.id = id - } - - init(info:EndpointInfo){ - self.name=info.name - self.type=info.deviceType - } - - public enum DeviceType:Int32{ - case unknown=0 - case phone - case tablet - case computer - - public static func fromRawValue(value:Int) -> DeviceType{ - switch value { - case 0: - return .unknown - case 1: - return .phone - case 2: - return .tablet - case 3: - return .computer - default: - return .unknown - } - } - } -} - - -public enum NearbyError:Error{ - case protocolError(_ message:String) - case requiredFieldMissing(_ message:String) - case ukey2 - case inputOutput - case canceled(reason:CancellationReason) - - public enum CancellationReason{ - case userRejected, userCanceled, notEnoughSpace, unsupportedType, timedOut - } -} - -public struct TransferMetadata{ - public let files:[FileMetadata] - public let id:String - public let pinCode:String? - public let textDescription:String? - - init(files: [FileMetadata], id: String, pinCode: String?, textDescription: String?=nil){ - self.files = files - self.id = id - self.pinCode = pinCode - self.textDescription = textDescription - } -} - -public struct FileMetadata{ - public let name:String - public let size:Int64 - public let mimeType:String -} - -struct FoundServiceInfo{ - let service:NWBrowser.Result - var device:RemoteDeviceInfo? -} - -struct OutgoingTransferInfo{ - let service:NWBrowser.Result - let device:RemoteDeviceInfo - let connection:OutboundNearbyConnection - let delegate:ShareExtensionDelegate -} - -struct EndpointInfo{ - let name:String - let deviceType:RemoteDeviceInfo.DeviceType - - init(name: String, deviceType: RemoteDeviceInfo.DeviceType){ - self.name = name - self.deviceType = deviceType - } - - init?(data:Data){ - guard data.count>17 else {return nil} - let deviceNameLength=Int(data[17]) - guard data.count>=deviceNameLength+18 else {return nil} - guard let deviceName=String(data: data[18..<(18+deviceNameLength)], encoding: .utf8) else {return nil} - let rawDeviceType:Int=Int(data[0] & 7) >> 1 - self.name=deviceName - self.deviceType=RemoteDeviceInfo.DeviceType.fromRawValue(value: rawDeviceType) - } - - func serialize()->Data{ - var endpointInfo:[UInt8]=[UInt8(deviceType.rawValue << 1)] - for _ in 0...15{ - endpointInfo.append(UInt8.random(in: 0...255)) - } - var nameChars=[UInt8](name.utf8) - if nameChars.count>255{ - nameChars=[UInt8](nameChars[0..<255]) - } - endpointInfo.append(UInt8(nameChars.count)) - for ch in nameChars{ - endpointInfo.append(UInt8(ch)) - } - return Data(endpointInfo) - } -} - -public protocol ShareExtensionDelegate:AnyObject{ - func addDevice(device:RemoteDeviceInfo) - func removeDevice(id:String) - func connectionWasEstablished(pinCode:String) - func connectionFailed(with error:Error) - func transferAccepted() - func transferProgress(progress:Double) - func transferFinished() -} - -public protocol MainAppDelegate { - func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, fileURLs: [URL]) - func incomingTransfer(id: String, didUpdateProgress progress: Double) - func incomingTransfer(id: String, didFinishWith error: Error?) -} - -// A lightweight struct to decode only the settings we need. -fileprivate struct NeardropFrameworkSettings: Decodable { - let neardropEnabled: Bool - let neardropDeviceDisplayName: String -} - -public class NearbyConnectionManager: NSObject, ObservableObject, NetServiceDelegate, InboundNearbyConnectionDelegate, OutboundNearbyConnectionDelegate { - - private var tcpListener: NWListener; - public let endpointID: [UInt8] = generateEndpointID() - private var mdnsService: NetService? - private var activeConnections: [String: InboundNearbyConnection] = [:] - private var foundServices: [String: FoundServiceInfo] = [:] - private var shareExtensionDelegates: [ShareExtensionDelegate] = [] - private var outgoingTransfers: [String: OutgoingTransferInfo] = [:] - public var mainAppDelegate: (any MainAppDelegate)? - private var discoveryRefCount = 0 - private var browser: NWBrowser? - - @Published public var transfers: [TransferProgressInfo] = [] - @Published public var pendingTransfers: [String: TransferProgressInfo] = [:] - private var cleanupTimers: [String: Timer] = [:] - - private let sharedDefaults: UserDefaults - - public static let shared = NearbyConnectionManager() - - override init() { - let appGroupID = "group.com.shariq.sapphire.shared" - self.sharedDefaults = UserDefaults(suiteName: appGroupID) ?? .standard - tcpListener = try! NWListener(using: NWParameters(tls: .none)) - super.init() - NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange), name: UserDefaults.didChangeNotification, object: sharedDefaults) - } - - @objc private func userDefaultsDidChange() { - DispatchQueue.main.async { - self.updateServiceFromSettings() - } - } - - private func loadSettings() -> NeardropFrameworkSettings { - if let data = sharedDefaults.data(forKey: "appSettings"), - let settings = try? JSONDecoder().decode(NeardropFrameworkSettings.self, from: data) { - return settings - } - return NeardropFrameworkSettings(neardropEnabled: true, neardropDeviceDisplayName: Host.current().localizedName ?? "My Mac") - } - - public func becomeVisible() { - print("[NCM] Attempting to become visible...") - updateServiceFromSettings() - } - - private func updateServiceFromSettings() { - let settings = loadSettings() - print("[NCM] Updating service based on settings. Neardrop Enabled: \(settings.neardropEnabled)") - - if settings.neardropEnabled { - if tcpListener.port == nil { - print("[NCM] TCP Listener not running. Starting now.") - startTCPListener() - } - } else { - if mdnsService != nil { - print("[NCM] Neardrop is disabled. Stopping MDNS service.") - mdnsService?.stop() - mdnsService = nil - } - } - } - - private func startTCPListener() { - tcpListener.stateUpdateHandler = { [weak self] state in - guard let self = self else { return } - - switch state { - case .ready: - if let port = self.tcpListener.port, port.rawValue > 0 { - print("[NCM] TCP Listener is ready on port \(port.rawValue). Initializing MDNS.") - self.initMDNS(on: port) - } else { - print("❌ [NCM] TCP Listener is ready, but the port is invalid (0 or nil). Cannot start MDNS broadcast.") - } - case .failed(let error): - print("❌ [NCM] TCP Listener failed to start: \(error.localizedDescription)") - self.mdnsService?.stop() - self.mdnsService = nil - default: - break - } - } - - tcpListener.newConnectionHandler = { [weak self] connection in - let id = UUID().uuidString - let conn = InboundNearbyConnection(connection: connection, id: id) - self?.activeConnections[id] = conn - conn.delegate = self - conn.start() - } - - tcpListener.start(queue: .global(qos: .utility)) - } - - private static func generateEndpointID() -> [UInt8] { - var id: [UInt8] = []; let alphabet = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".compactMap { UInt8($0.asciiValue!) } - for _ in 0...3 { id.append(alphabet[Int.random(in: 0..= 0) - if discoveryRefCount == 0 { browser?.cancel(); browser = nil } - } - - public func addShareExtensionDelegate(_ delegate: ShareExtensionDelegate) { - shareExtensionDelegates.append(delegate) - for service in foundServices.values { if let device = service.device { delegate.addDevice(device: device) } } - } - - public func removeShareExtensionDelegate(_ delegate: ShareExtensionDelegate) { shareExtensionDelegates.removeAll { $0 === delegate } } - public func cancelOutgoingTransfer(id: String) { - outgoingTransfers[id]?.connection.cancel() - } - - private func endpointID(for service: NWBrowser.Result) -> String? { - guard case let .service(name: serviceName, _, _, _) = service.endpoint, let nameData = Data.dataFromUrlSafeBase64(serviceName), nameData.count >= 10, - nameData[0] == 0x23, nameData.subdata(in: 5..<8) == Data([0xFC, 0x9F, 0x5E]) else { return nil } - return String(data: nameData.subdata(in: 1..<5), encoding: .ascii) - } - - private func maybeAddFoundDevice(service: NWBrowser.Result) { - if service.interfaces.contains(where: { $0.type == .loopback }) { return } - guard let endpointID = endpointID(for: service) else { return } - var foundService = FoundServiceInfo(service: service) - guard case let .bonjour(txtRecord) = service.metadata, let infoEncoded = txtRecord.dictionary["n"], let infoData = Data.dataFromUrlSafeBase64(infoEncoded), infoData.count >= 19 else { return } - let nameLength = Int(infoData[17]); guard infoData.count >= nameLength + 18, let name = String(data: infoData.subdata(in: 18..<(18 + nameLength)), encoding: .utf8) else { return } - let type = RemoteDeviceInfo.DeviceType.fromRawValue(value: (Int(infoData[0]) >> 1) & 7) - let deviceInfo = RemoteDeviceInfo(name: name, type: type, id: endpointID) - foundService.device = deviceInfo; foundServices[endpointID] = foundService - for delegate in shareExtensionDelegates { delegate.addDevice(device: deviceInfo) } - } - - private func maybeRemoveFoundDevice(service: NWBrowser.Result) { - guard let endpointID = endpointID(for: service), foundServices.removeValue(forKey: endpointID) != nil else { return } - for delegate in shareExtensionDelegates { delegate.removeDevice(id: endpointID) } - } - - public func startOutgoingTransfer(deviceID: String, delegate: ShareExtensionDelegate, urls: [URL]) { - guard let info = foundServices[deviceID] else { return } - let tcp = NWProtocolTCP.Options(); tcp.noDelay = true - let nwconn = NWConnection(to: info.service.endpoint, using: NWParameters(tls: .none, tcp: tcp)) - let conn = OutboundNearbyConnection(connection: nwconn, id: deviceID, urlsToSend: urls) - conn.delegate = self - outgoingTransfers[deviceID] = OutgoingTransferInfo(service: info.service, device: info.device!, connection: conn, delegate: delegate) - - let transferInfo = TransferProgressInfo( - id: deviceID, - deviceName: info.device!.name, - fileDescription: urls.count == 1 ? urls[0].lastPathComponent : "\(urls.count) files", - direction: .outgoing, - iconName: "arrow.up.doc" - ) - DispatchQueue.main.async { - self.transfers.insert(transferInfo, at: 0) - } - - conn.start() - } - - func outboundConnectionWasEstablished(connection: OutboundNearbyConnection) { - if let transfer = outgoingTransfers[connection.id] { - DispatchQueue.main.async { transfer.delegate.connectionWasEstablished(pinCode: connection.pinCode!) } - } - } - - func outboundConnectionTransferAccepted(connection: OutboundNearbyConnection) { - if let transfer = outgoingTransfers[connection.id] { - DispatchQueue.main.async { - transfer.delegate.transferAccepted() - if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { - self.transfers[index].state = .inProgress - } - } - } - } - - func outboundConnection(connection: OutboundNearbyConnection, transferProgress: Double) { - if let transfer = outgoingTransfers[connection.id] { - DispatchQueue.main.async { - transfer.delegate.transferProgress(progress: transferProgress) - if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { - self.transfers[index].progress = transferProgress - } - } - } - } - - func outboundConnection(connection: OutboundNearbyConnection, failedWithError: Error) { - if let transfer = outgoingTransfers.removeValue(forKey: connection.id) { - DispatchQueue.main.async { - transfer.delegate.connectionFailed(with: failedWithError) - if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { - self.transfers[index].state = .failed - self.scheduleCleanup(for: connection.id) - } - } - } - } - - func outboundConnectionTransferFinished(connection: OutboundNearbyConnection) { - if let transfer = outgoingTransfers.removeValue(forKey: connection.id) { - DispatchQueue.main.async { - transfer.delegate.transferFinished() - if let index = self.transfers.firstIndex(where: { $0.id == connection.id }) { - self.transfers[index].state = .finished - self.scheduleCleanup(for: connection.id) - } - } - } - } - - // MARK: - Helpers & Delegate Methods - - public func netServiceDidPublish(_ sender: NetService) { - print("✅ [NCM - NetService] Successfully published service: \(sender.name) on port \(sender.port)") - } - - public func netService(_ sender: NetService, didNotPublish errorDict: [String : NSNumber]) { - print("❌ [NCM - NetService] FAILED to publish service: \(sender.name). Error: \(errorDict)") - } - - private func scheduleCleanup(for transferID: String) { - cleanupTimers[transferID]?.invalidate() - let timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: false) { [weak self] _ in - DispatchQueue.main.async { - guard let self = self else { return } - self.transfers.removeAll { $0.id == transferID } - self.cleanupTimers.removeValue(forKey: transferID) - } - } - cleanupTimers[transferID] = timer - } - - private func fileDescription(for transfer: TransferMetadata) -> String { - if let text = transfer.textDescription { return text } - if transfer.files.count == 1 { return transfer.files[0].name } - return "\(transfer.files.count) files" - } - - private func iconName(for transfer: TransferMetadata) -> String { - if let desc = transfer.textDescription { - if let _ = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue).firstMatch(in: desc, options: [], range: NSRange(location: 0, length: desc.utf16.count)) { - return "link" - } - return "text.quote" - } - guard let firstFile = transfer.files.first else { return "questionmark" } - if transfer.files.count > 1 { return "doc.on.doc.fill" } - - let mimeType = firstFile.mimeType.lowercased() - if mimeType.starts(with: "image/") { return "photo" } - if mimeType.starts(with: "video/") { return "video.fill" } - if mimeType.starts(with: "audio/") { return "music.note" } - if mimeType.contains("pdf") { return "doc.richtext.fill" } - if mimeType.contains("zip") || mimeType.contains("archive") { return "archivebox.fill" } - - return "doc.fill" - } -} diff --git a/submissions/sapphire/Nearby/OutboundNearbyConnection.swift b/submissions/sapphire/Nearby/OutboundNearbyConnection.swift deleted file mode 100644 index 8000a201..00000000 --- a/submissions/sapphire/Nearby/OutboundNearbyConnection.swift +++ /dev/null @@ -1,449 +0,0 @@ -// -// OutboundNearbyConnection.swift -// NearbyShare -// -// Created by Grishka on 23.09.2023. -// - -import Foundation -import Network -import CryptoKit -import CommonCrypto -import System -import UniformTypeIdentifiers - -import SwiftECC -import BigInt - -class OutboundNearbyConnection:NearbyConnection{ - private var currentState:State = .initial - private let urlsToSend:[URL] - private var ukeyClientFinishMsgData:Data? - private var queue:[OutgoingFileTransfer]=[] - private var currentTransfer:OutgoingFileTransfer? - public var delegate:OutboundNearbyConnectionDelegate? - private var totalBytesToSend:Int64=0 - private var totalBytesSent:Int64=0 - private var cancelled:Bool=false - private var textPayloadID:Int64=0 - - enum State{ - case initial, sentUkeyClientInit, sentUkeyClientFinish, sentPairedKeyEncryption, sentPairedKeyResult, sentIntroduction, sendingFiles - } - - init(connection: NWConnection, id: String, urlsToSend:[URL]){ - self.urlsToSend=urlsToSend - super.init(connection: connection, id: id) - if urlsToSend.count==1 && !urlsToSend[0].isFileURL{ - textPayloadID=Int64.random(in: Int64.min...Int64.max) - } - } - - deinit { - if let transfer=currentTransfer, let handle=transfer.handle{ - try? handle.close() - } - for transfer in queue{ - if let handle=transfer.handle{ - try? handle.close() - } - } - } - - public func cancel(){ - cancelled=true - if encryptionDone{ - var cancel=Sharing_Nearby_Frame() - cancel.version = .v1 - cancel.v1=Sharing_Nearby_V1Frame() - cancel.v1.type = .cancel - try? sendTransferSetupFrame(cancel) - } - try? sendDisconnectionAndDisconnect() - } - - override func connectionReady() { - super.connectionReady() - do{ - try sendConnectionRequest() - try sendUkey2ClientInit() - }catch{ - lastError=error - protocolError() - } - } - - override func isServer() -> Bool { - return false - } - - override func processReceivedFrame(frameData: Data) { - do{ - #if DEBUG - print("received \(frameData), state is \(currentState)") - #endif - switch currentState { - case .initial: - protocolError() - case .sentUkeyClientInit: - try processUkey2ServerInit(frame: try Securegcm_Ukey2Message(serializedData: frameData), raw: frameData) - case .sentUkeyClientFinish: - try processConnectionResponse(frame: try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)) - default: - let smsg=try Securemessage_SecureMessage(serializedData: frameData) - try decryptAndProcessReceivedSecureMessage(smsg) - } - }catch{ - if case NearbyError.ukey2=error{ - }else if currentState == .sentUkeyClientInit{ - sendUkey2Alert(type: .badMessage) - } - lastError=error - protocolError() - } - } - - override func processTransferSetupFrame(_ frame: Sharing_Nearby_Frame) throws { - if frame.hasV1 && frame.v1.hasType, case .cancel = frame.v1.type { - print("Transfer canceled") - try sendDisconnectionAndDisconnect() - delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .userCanceled)) - return - } - print(frame) - switch currentState{ - case .sentPairedKeyEncryption: - try processPairedKeyEncryption(frame: frame) - case .sentPairedKeyResult: - try processPairedKeyResult(frame: frame) - case .sentIntroduction: - try processConsent(frame: frame) - case .sendingFiles: - break - default: - assertionFailure("Unexpected state \(currentState)") - } - } - - override func protocolError() { - super.protocolError() - delegate?.outboundConnection(connection: self, failedWithError: lastError!) - } - - private func sendConnectionRequest() throws { - var frame=Location_Nearby_Connections_OfflineFrame() - frame.version = .v1 - frame.v1=Location_Nearby_Connections_V1Frame() - frame.v1.type = .connectionRequest - frame.v1.connectionRequest=Location_Nearby_Connections_ConnectionRequestFrame() - frame.v1.connectionRequest.endpointID=String(bytes: NearbyConnectionManager.shared.endpointID, encoding: .ascii)! - frame.v1.connectionRequest.endpointName=Host.current().localizedName! - let endpointInfo=EndpointInfo(name: Host.current().localizedName!, deviceType: .computer) - frame.v1.connectionRequest.endpointInfo=endpointInfo.serialize() - frame.v1.connectionRequest.mediums=[.wifiLan] - sendFrameAsync(try frame.serializedData()) - } - - private func sendUkey2ClientInit() throws { - let domain=Domain.instance(curve: .EC256r1) - let (pubKey, privKey)=domain.makeKeyPair() - publicKey=pubKey - privateKey=privKey - - var finishFrame=Securegcm_Ukey2Message() - finishFrame.messageType = .clientFinish - var finish=Securegcm_Ukey2ClientFinished() - var pkey=Securemessage_GenericPublicKey() - pkey.type = .ecP256 - pkey.ecP256PublicKey=Securemessage_EcP256PublicKey() - pkey.ecP256PublicKey.x=Data(pubKey.w.x.asSignedBytes()) - pkey.ecP256PublicKey.y=Data(pubKey.w.y.asSignedBytes()) - finish.publicKey=try pkey.serializedData() - finishFrame.messageData=try finish.serializedData() - ukeyClientFinishMsgData=try finishFrame.serializedData() - - var frame=Securegcm_Ukey2Message() - frame.messageType = .clientInit - - var clientInit=Securegcm_Ukey2ClientInit() - clientInit.version=1 - clientInit.random=Data.randomData(length: 32) - clientInit.nextProtocol="AES_256_CBC-HMAC_SHA256" - var sha=SHA512() - sha.update(data: ukeyClientFinishMsgData!) - var commitment=Securegcm_Ukey2ClientInit.CipherCommitment() - commitment.commitment=Data(sha.finalize()) - commitment.handshakeCipher = .p256Sha512 - clientInit.cipherCommitments.append(commitment) - frame.messageData=try clientInit.serializedData() - - ukeyClientInitMsgData=try frame.serializedData() - sendFrameAsync(ukeyClientInitMsgData!) - currentState = .sentUkeyClientInit - } - - private func processUkey2ServerInit(frame:Securegcm_Ukey2Message, raw:Data) throws{ - ukeyServerInitMsgData=raw - guard frame.messageType == .serverInit else{ - sendUkey2Alert(type: .badMessageType) - throw NearbyError.ukey2 - } - let serverInit=try Securegcm_Ukey2ServerInit(serializedData: frame.messageData) - guard serverInit.version==1 else{ - sendUkey2Alert(type: .badVersion) - throw NearbyError.ukey2 - } - guard serverInit.random.count==32 else{ - sendUkey2Alert(type: .badRandom) - throw NearbyError.ukey2 - } - guard serverInit.handshakeCipher == .p256Sha512 else{ - sendUkey2Alert(type: .badHandshakeCipher) - throw NearbyError.ukey2 - } - - let serverKey=try Securemessage_GenericPublicKey(serializedData: serverInit.publicKey) - try finalizeKeyExchange(peerKey: serverKey) - sendFrameAsync(ukeyClientFinishMsgData!) - currentState = .sentUkeyClientFinish - - var resp=Location_Nearby_Connections_OfflineFrame() - resp.version = .v1 - resp.v1=Location_Nearby_Connections_V1Frame() - resp.v1.type = .connectionResponse - resp.v1.connectionResponse=Location_Nearby_Connections_ConnectionResponseFrame() - resp.v1.connectionResponse.response = .accept - resp.v1.connectionResponse.status=0 - resp.v1.connectionResponse.osInfo=Location_Nearby_Connections_OsInfo() - resp.v1.connectionResponse.osInfo.type = .apple - sendFrameAsync(try resp.serializedData()) - - encryptionDone=true - delegate?.outboundConnectionWasEstablished(connection: self) - } - - private func processConnectionResponse(frame:Location_Nearby_Connections_OfflineFrame) throws{ - #if DEBUG - print("connection response: \(frame)") - #endif - guard frame.version == .v1 else {throw NearbyError.protocolError("Unexpected offline frame version \(frame.version)")} - guard frame.v1.type == .connectionResponse else {throw NearbyError.protocolError("Unexpected frame type \(frame.v1.type)")} - guard frame.v1.connectionResponse.response == .accept else {throw NearbyError.protocolError("Connection was rejected by recipient")} - - var pairedEncryption=Sharing_Nearby_Frame() - pairedEncryption.version = .v1 - pairedEncryption.v1=Sharing_Nearby_V1Frame() - pairedEncryption.v1.type = .pairedKeyEncryption - pairedEncryption.v1.pairedKeyEncryption=Sharing_Nearby_PairedKeyEncryptionFrame() - pairedEncryption.v1.pairedKeyEncryption.secretIDHash=Data.randomData(length: 6) - pairedEncryption.v1.pairedKeyEncryption.signedData=Data.randomData(length: 72) - try sendTransferSetupFrame(pairedEncryption) - - currentState = .sentPairedKeyEncryption - } - - private func processPairedKeyEncryption(frame:Sharing_Nearby_Frame) throws{ - guard frame.hasV1, frame.v1.hasPairedKeyEncryption else { throw NearbyError.requiredFieldMissing("sharingNearbyFrame.v1.pairedKeyEncryption") } - var pairedResult=Sharing_Nearby_Frame() - pairedResult.version = .v1 - pairedResult.v1=Sharing_Nearby_V1Frame() - pairedResult.v1.type = .pairedKeyResult - pairedResult.v1.pairedKeyResult=Sharing_Nearby_PairedKeyResultFrame() - pairedResult.v1.pairedKeyResult.status = .unable - try sendTransferSetupFrame(pairedResult) - currentState = .sentPairedKeyResult - } - - private func processPairedKeyResult(frame:Sharing_Nearby_Frame) throws{ - guard frame.hasV1, frame.v1.hasPairedKeyResult else { throw NearbyError.requiredFieldMissing("sharingNearbyFrame.v1.pairedKeyResult") } - - var introduction=Sharing_Nearby_Frame() - introduction.version = .v1 - introduction.v1.type = .introduction - if urlsToSend.count==1 && !urlsToSend[0].isFileURL{ - var meta=Sharing_Nearby_TextMetadata() - meta.type = .url - meta.textTitle=urlsToSend[0].host ?? "URL" - meta.size=Int64(urlsToSend[0].absoluteString.utf8.count) - meta.payloadID=textPayloadID - introduction.v1.introduction.textMetadata.append(meta) - }else{ - for url in urlsToSend{ - guard url.isFileURL else {continue} - var meta=Sharing_Nearby_FileMetadata() - meta.name=OutboundNearbyConnection.sanitizeFileName(name: url.lastPathComponent) - let attrs=try FileManager.default.attributesOfItem(atPath: url.path) - meta.size=(attrs[FileAttributeKey.size] as! NSNumber).int64Value - let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier - meta.mimeType="application/octet-stream" - if let typeID=typeID{ - if #available(macOS 11.0, *){ - let type=UTType(typeID) - if let type=type, let mimeType=type.preferredMIMEType{ - meta.mimeType=mimeType - } - }else{ - if let mimeType=UTTypeCopyPreferredTagWithClass(typeID as CFString, kUTTagClassMIMEType){ - meta.mimeType=(mimeType.takeRetainedValue() as NSString) as String - } - } - } - if meta.mimeType.starts(with: "image/"){ - meta.type = .image - }else if meta.mimeType.starts(with: "video/"){ - meta.type = .video - }else if(meta.mimeType.starts(with: "audio/")){ - meta.type = .audio - }else if(url.pathExtension.lowercased()=="apk"){ - meta.type = .app - }else{ - meta.type = .unknown - } - meta.payloadID=Int64.random(in: Int64.min...Int64.max) - queue.append(OutgoingFileTransfer(url: url, payloadID: meta.payloadID, handle: try FileHandle(forReadingFrom: url), totalBytes: meta.size, currentOffset: 0)) - introduction.v1.introduction.fileMetadata.append(meta) - totalBytesToSend+=meta.size - } - } - #if DEBUG - print("sent introduction: \(introduction)") - #endif - try sendTransferSetupFrame(introduction) - - currentState = .sentIntroduction - } - - private func processConsent(frame:Sharing_Nearby_Frame) throws{ - guard frame.version == .v1, frame.v1.type == .response else {throw NearbyError.requiredFieldMissing("sharingNearbyFrame.v1.type==response")} - switch frame.v1.connectionResponse.status{ - case .accept: - currentState = .sendingFiles - delegate?.outboundConnectionTransferAccepted(connection: self) - if urlsToSend.count==1 && !urlsToSend[0].isFileURL{ - try sendURL() - }else{ - try sendNextFileChunk() - } - case .reject, .unknown: - delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .userRejected)) - try sendDisconnectionAndDisconnect() - case .notEnoughSpace: - delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .notEnoughSpace)) - try sendDisconnectionAndDisconnect() - case .timedOut: - delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .timedOut)) - try sendDisconnectionAndDisconnect() - case .unsupportedAttachmentType: - delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .unsupportedType)) - try sendDisconnectionAndDisconnect() - } - } - - private func sendURL() throws{ - try sendBytesPayload(data: Data(urlsToSend[0].absoluteString.utf8), id: textPayloadID) - delegate?.outboundConnectionTransferFinished(connection: self) - try sendDisconnectionAndDisconnect() - } - - private func sendNextFileChunk() throws{ - if cancelled{ - return - } - if currentTransfer==nil || currentTransfer?.currentOffset==currentTransfer?.totalBytes{ - if currentTransfer != nil && currentTransfer?.handle != nil{ - try currentTransfer?.handle?.close() - } - if queue.isEmpty{ - #if DEBUG - print("Disconnecting because all files have been transferred") - #endif - try sendDisconnectionAndDisconnect() - delegate?.outboundConnectionTransferFinished(connection: self) - return - } - currentTransfer=queue.removeFirst() - } - - let fileBuffer:Data - if #available(macOS 10.15.4, *) { - guard let _fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{ - throw NearbyError.inputOutput - } - fileBuffer=_fileBuffer - } else { - fileBuffer=currentTransfer!.handle!.readData(ofLength: 512*1024) - } - - var transfer=Location_Nearby_Connections_PayloadTransferFrame() - transfer.packetType = .data - transfer.payloadChunk.offset=currentTransfer!.currentOffset - transfer.payloadChunk.flags=0 - transfer.payloadChunk.body=fileBuffer - transfer.payloadHeader.id=currentTransfer!.payloadID - transfer.payloadHeader.type = .file - transfer.payloadHeader.totalSize=Int64(currentTransfer!.totalBytes) - transfer.payloadHeader.isSensitive=false - currentTransfer!.currentOffset+=Int64(fileBuffer.count) - - var wrapper=Location_Nearby_Connections_OfflineFrame() - wrapper.version = .v1 - wrapper.v1=Location_Nearby_Connections_V1Frame() - wrapper.v1.type = .payloadTransfer - wrapper.v1.payloadTransfer=transfer - try encryptAndSendOfflineFrame(wrapper, completion: { - do{ - try self.sendNextFileChunk() - }catch{ - self.lastError=error - self.protocolError() - } - }) - #if DEBUG - print("sent file chunk, current transfer: \(String(describing: currentTransfer))") - #endif - totalBytesSent+=Int64(fileBuffer.count) - delegate?.outboundConnection(connection: self, transferProgress: Double(totalBytesSent)/Double(totalBytesToSend)) - - if currentTransfer!.currentOffset==currentTransfer!.totalBytes{ - // Signal end of file (yes, all this for one bit) - var transfer=Location_Nearby_Connections_PayloadTransferFrame() - transfer.packetType = .data - transfer.payloadChunk.offset=currentTransfer!.currentOffset - transfer.payloadChunk.flags=1 // <- this one here - transfer.payloadHeader.id=currentTransfer!.payloadID - transfer.payloadHeader.type = .file - transfer.payloadHeader.totalSize=Int64(currentTransfer!.totalBytes) - transfer.payloadHeader.isSensitive=false - - var wrapper=Location_Nearby_Connections_OfflineFrame() - wrapper.version = .v1 - wrapper.v1=Location_Nearby_Connections_V1Frame() - wrapper.v1.type = .payloadTransfer - wrapper.v1.payloadTransfer=transfer - try encryptAndSendOfflineFrame(wrapper) - #if DEBUG - print("sent EOF, current transfer: \(String(describing: currentTransfer))") - #endif - } - } - - private static func sanitizeFileName(name:String)->String{ - return name.replacingOccurrences(of: "[\\/\\\\?%\\*:\\|\"<>=]", with: "_", options: .regularExpression) - } -} - -fileprivate struct OutgoingFileTransfer{ - let url:URL - let payloadID:Int64 - let handle:FileHandle? - let totalBytes:Int64 - var currentOffset:Int64 -} - -protocol OutboundNearbyConnectionDelegate{ - func outboundConnectionWasEstablished(connection:OutboundNearbyConnection) - func outboundConnection(connection:OutboundNearbyConnection, transferProgress:Double) - func outboundConnectionTransferAccepted(connection:OutboundNearbyConnection) - func outboundConnection(connection:OutboundNearbyConnection, failedWithError:Error) - func outboundConnectionTransferFinished(connection:OutboundNearbyConnection) -} diff --git a/submissions/sapphire/Nearby/ShareViewController.swift b/submissions/sapphire/Nearby/ShareViewController.swift deleted file mode 100644 index ff3682d1..00000000 --- a/submissions/sapphire/Nearby/ShareViewController.swift +++ /dev/null @@ -1,262 +0,0 @@ -// -// ShareViewController.swift -// ShareExtension -// -// Created by Grishka on 12.09.2023. -// - -import Foundation -import Cocoa -import NearbyShare -import QuickLookThumbnailing // <-- IMPORT ADDED - -class ShareViewController: NSViewController, ShareExtensionDelegate { - - private var urls: [URL] = [] - private var foundDevices: [RemoteDeviceInfo] = [] - private var chosenDevice: RemoteDeviceInfo? - private var lastError: Error? - - @IBOutlet var filesIcon: NSImageView? - @IBOutlet var filesLabel: NSTextField? - @IBOutlet var loadingOverlay: NSStackView? - @IBOutlet var largeProgress: NSProgressIndicator? - @IBOutlet var listView: NSCollectionView? - @IBOutlet var listViewWrapper: NSView? - @IBOutlet var contentWrap: NSView? - @IBOutlet var progressView: NSView? - @IBOutlet var progressDeviceIcon: NSImageView? - @IBOutlet var progressDeviceName: NSTextField? - @IBOutlet var progressProgressBar: NSProgressIndicator? - @IBOutlet var progressState: NSTextField? - @IBOutlet var progressDeviceIconWrap: NSView? - @IBOutlet var progressDeviceSecondaryIcon: NSImageView? - - override var nibName: NSNib.Name? { - return NSNib.Name("ShareViewController") - } - - override func loadView() { - super.loadView() - - let item = self.extensionContext!.inputItems[0] as! NSExtensionItem - if let attachments = item.attachments { - for attachment in attachments as NSArray { - let provider = attachment as! NSItemProvider - // Use public.url and public.file-url for broader compatibility - let typeURL = "public.url" - let typeFileURL = "public.file-url" - - provider.loadItem(forTypeIdentifier: typeURL, options: nil) { data, err in - self.handleAttachment(data: data, error: err, total: attachments.count) - } - provider.loadItem(forTypeIdentifier: typeFileURL, options: nil) { data, err in - self.handleAttachment(data: data, error: err, total: attachments.count) - } - } - } else { - cancelRequest() - return - } - - contentWrap!.addSubview(listViewWrapper!) - contentWrap!.addSubview(loadingOverlay!) - contentWrap!.addSubview(progressView!) - progressView!.isHidden = true - - listViewWrapper!.translatesAutoresizingMaskIntoConstraints = false - loadingOverlay!.translatesAutoresizingMaskIntoConstraints = false - progressView!.translatesAutoresizingMaskIntoConstraints = false - NSLayoutConstraint.activate([ - listViewWrapper!.widthAnchor.constraint(equalTo: contentWrap!.widthAnchor), - listViewWrapper!.heightAnchor.constraint(equalTo: contentWrap!.heightAnchor), - loadingOverlay!.widthAnchor.constraint(equalTo: contentWrap!.widthAnchor), - loadingOverlay!.centerYAnchor.constraint(equalTo: contentWrap!.centerYAnchor), - progressView!.widthAnchor.constraint(equalTo: contentWrap!.widthAnchor), - progressView!.centerYAnchor.constraint(equalTo: contentWrap!.centerYAnchor) - ]) - - largeProgress!.startAnimation(nil) - let flowLayout = NSCollectionViewFlowLayout() - flowLayout.itemSize = NSSize(width: 75, height: 90) - flowLayout.sectionInset = NSEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) - flowLayout.minimumInteritemSpacing = 10 - flowLayout.minimumLineSpacing = 10 - listView!.collectionViewLayout = flowLayout - listView!.dataSource = self - - progressDeviceIconWrap!.wantsLayer = true - progressDeviceIconWrap!.layer!.masksToBounds = false - } - - private func handleAttachment(data: NSSecureCoding?, error: Error?, total: Int) { - if let url = data as? URL { - DispatchQueue.main.async { - if !self.urls.contains(url) { - self.urls.append(url) - if self.urls.count == total { - self.urlsReady() - } - } - } - } - } - - override func viewDidLoad() { - super.viewDidLoad() - NearbyConnectionManager.shared.startDeviceDiscovery() - NearbyConnectionManager.shared.addShareExtensionDelegate(self) - } - - override func viewWillDisappear() { - if chosenDevice == nil { - NearbyConnectionManager.shared.stopDeviceDiscovery() - } - NearbyConnectionManager.shared.removeShareExtensionDelegate(self) - } - - @IBAction func cancel(_ sender: AnyObject?) { - if let device = chosenDevice { - NearbyConnectionManager.shared.cancelOutgoingTransfer(id: device.id!) - } - cancelRequest() - } - - private func cancelRequest() { - let cancelError = NSError(domain: NSCocoaErrorDomain, code: NSUserCancelledError, userInfo: nil) - self.extensionContext!.cancelRequest(withError: cancelError) - } - - private func urlsReady() { - for url in urls { - if url.isFileURL { - var isDirectory: ObjCBool = false - if FileManager.default.fileExists(atPath: url.path, isDirectory: &isDirectory) && isDirectory.boolValue { - cancelRequest() - return - } - } - } - - if urls.count == 1 { - let url = urls[0] - if url.isFileURL { - filesLabel!.stringValue = url.lastPathComponent - generateThumbnail(for: url) { [weak self] image in - self?.filesIcon?.image = image ?? NSWorkspace.shared.icon(forFile: url.path) - } - } else if ["http", "https"].contains(url.scheme) { - filesLabel!.stringValue = url.absoluteString - filesIcon!.image = NSImage(named: NSImage.networkName) - } - } else { - filesLabel!.stringValue = String.localizedStringWithFormat(NSLocalizedString("NFiles", value: "%d files", comment: ""), urls.count) - filesIcon!.image = NSImage(named: NSImage.multipleDocumentsName) - } - } - - /// Generates a thumbnail for a given file URL. - private func generateThumbnail(for url: URL, completion: @escaping (NSImage?) -> Void) { - let size = CGSize(width: 128, height: 128) - let request = QLThumbnailGenerator.Request(fileAt: url, size: size, scale: view.window?.backingScaleFactor ?? 2.0, representationTypes: .all) - - QLThumbnailGenerator.shared.generateBestRepresentation(for: request) { thumbnail, error in - DispatchQueue.main.async { - completion(thumbnail?.nsImage) - } - } - } - - func addDevice(device: RemoteDeviceInfo) { - if foundDevices.isEmpty { loadingOverlay?.animator().isHidden = true } - foundDevices.append(device) - listView?.animator().insertItems(at: [[0, foundDevices.count - 1]]) - } - - func removeDevice(id: String) { - if chosenDevice != nil { return } - if let i = foundDevices.firstIndex(where: { $0.id == id }) { - foundDevices.remove(at: i) - listView?.animator().deleteItems(at: [[0, i]]) - } - if foundDevices.isEmpty { loadingOverlay?.animator().isHidden = false } - } - - func connectionWasEstablished(pinCode: String) { - progressState?.stringValue = String(format:NSLocalizedString("PinCode", value: "PIN: %@", comment: ""), arguments: [pinCode]) - progressProgressBar?.isIndeterminate = false - progressProgressBar?.maxValue = 1000 - progressProgressBar?.doubleValue = 0 - } - - func connectionFailed(with error: Error) { - progressProgressBar?.isIndeterminate = false; progressProgressBar?.maxValue = 1000; progressProgressBar?.doubleValue = 0 - lastError = error - if let ne = (error as? NearbyError), case let .canceled(reason) = ne { - switch reason { - case .userRejected: progressState?.stringValue = NSLocalizedString("TransferDeclined", value: "Declined", comment: "") - case .userCanceled: progressState?.stringValue = NSLocalizedString("TransferCanceled", value: "Canceled", comment: "") - case .notEnoughSpace: progressState?.stringValue = NSLocalizedString("NotEnoughSpace", value: "Not enough disk space", comment: "") - case .unsupportedType: progressState?.stringValue = NSLocalizedString("UnsupportedType", value: "Attachment type not supported", comment: "") - case .timedOut: progressState?.stringValue = NSLocalizedString("TransferTimedOut", value: "Timed out", comment: "") - } - progressDeviceSecondaryIcon?.isHidden = false - dismissDelayed() - } else { - let alert = NSAlert(error: error) - alert.beginSheetModal(for: view.window!) { _ in self.extensionContext!.cancelRequest(withError: error) } - } - } - - func transferAccepted() { progressState?.stringValue = NSLocalizedString("Sending", value: "Sending...", comment: "") } - func transferProgress(progress: Double) { progressProgressBar!.doubleValue = progress * progressProgressBar!.maxValue } - - func transferFinished() { - progressState?.stringValue = NSLocalizedString("TransferFinished", value: "Transfer finished", comment: "") - dismissDelayed() - } - - func selectDevice(device: RemoteDeviceInfo) { - NearbyConnectionManager.shared.stopDeviceDiscovery() - listViewWrapper?.animator().isHidden = true - progressView?.animator().isHidden = false - progressDeviceName?.stringValue = device.name - progressDeviceIcon?.image = imageForDeviceType(type: device.type) - progressProgressBar?.startAnimation(nil) - progressState?.stringValue = NSLocalizedString("Connecting", value: "Connecting...", comment: "") - chosenDevice = device - NearbyConnectionManager.shared.startOutgoingTransfer(deviceID: device.id!, delegate: self, urls: urls) - } - - private func dismissDelayed() { - DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { - if let error = self.lastError { self.extensionContext!.cancelRequest(withError: error) } - else { self.extensionContext!.completeRequest(returningItems: nil, completionHandler: nil) } - } - } -} - -fileprivate func imageForDeviceType(type: RemoteDeviceInfo.DeviceType) -> NSImage { - let imageName: String - switch type { - case .tablet: imageName = "com.apple.ipad" - case .computer: imageName = "com.apple.macbookpro-13-unibody" - default: imageName = "com.apple.iphone" - } - return NSImage(contentsOfFile: "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/\(imageName).icns")! -} - -extension ShareViewController: NSCollectionViewDataSource { - func numberOfSections(in collectionView: NSCollectionView) -> Int { return 1 } - func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { return foundDevices.count } - - func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { - let item = collectionView.makeItem(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DeviceListCell"), for: indexPath) - guard let collectionViewItem = item as? DeviceListCell else { return item } - let device = foundDevices[indexPath.item] - collectionViewItem.textField?.stringValue = device.name - collectionViewItem.imageView?.image = imageForDeviceType(type: device.type) - collectionViewItem.clickHandler = { self.selectDevice(device: device) } - return collectionViewItem - } -} diff --git a/submissions/sapphire/Nearby/TransferDirection.swift b/submissions/sapphire/Nearby/TransferDirection.swift deleted file mode 100644 index 4108a936..00000000 --- a/submissions/sapphire/Nearby/TransferDirection.swift +++ /dev/null @@ -1,26 +0,0 @@ -// -// TransferDirection.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-03. -// - -import Foundation - -public enum TransferDirection { - case incoming, outgoing -} - -public enum TransferState { - case waiting, inProgress, finished, failed, canceled -} - -public struct TransferProgressInfo: Identifiable, Equatable { - public let id: String - public var deviceName: String - public var fileDescription: String - public var direction: TransferDirection - public var state: TransferState = .waiting - public var progress: Double = 0.0 - public var iconName: String = "doc" -} From 722d1bdfb7806a8a24ad8f593cebe52729e47267 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:44:48 -0400 Subject: [PATCH 08/16] Delete submissions/sapphire/ObjC directory --- submissions/sapphire/ObjC/Bridging-Header.h | 11 --------- .../ObjC/NDNotificationCenterHackery.h | 24 ------------------- .../ObjC/NDNotificationCenterHackery.m | 18 -------------- submissions/sapphire/ObjC/PrivateAPI.h | 20 ---------------- 4 files changed, 73 deletions(-) delete mode 100644 submissions/sapphire/ObjC/Bridging-Header.h delete mode 100644 submissions/sapphire/ObjC/NDNotificationCenterHackery.h delete mode 100644 submissions/sapphire/ObjC/NDNotificationCenterHackery.m delete mode 100644 submissions/sapphire/ObjC/PrivateAPI.h diff --git a/submissions/sapphire/ObjC/Bridging-Header.h b/submissions/sapphire/ObjC/Bridging-Header.h deleted file mode 100644 index 8d8e26a6..00000000 --- a/submissions/sapphire/ObjC/Bridging-Header.h +++ /dev/null @@ -1,11 +0,0 @@ -// -// Bridging-Header.h -// Sapphire -// -// Created by Shariq Charolia on 2025-07-02. -// - -#import "NDNotificationCenterHackery.h" -#import -int DisplayServicesGetBrightness(CGDirectDisplayID display, float *brightness); -int DisplayServicesSetBrightness(CGDirectDisplayID display, float brightness); diff --git a/submissions/sapphire/ObjC/NDNotificationCenterHackery.h b/submissions/sapphire/ObjC/NDNotificationCenterHackery.h deleted file mode 100644 index 0e264717..00000000 --- a/submissions/sapphire/ObjC/NDNotificationCenterHackery.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// UNMutableNotificationContent.h -// Sapphire -// -// Created by Shariq Charolia on 2025-06-30. -// - - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface UNMutableNotificationContent (NDPrivateAPIs) -@property BOOL hasDefaultAction; -@end - -@interface NDNotificationCenterHackery : NSObject - -+ (void)removeDefaultAction:(UNMutableNotificationContent*) content; - -@end - -NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/submissions/sapphire/ObjC/NDNotificationCenterHackery.m b/submissions/sapphire/ObjC/NDNotificationCenterHackery.m deleted file mode 100644 index 33ec2743..00000000 --- a/submissions/sapphire/ObjC/NDNotificationCenterHackery.m +++ /dev/null @@ -1,18 +0,0 @@ -// -// NDNotificationCenterHackery.m -// Sapphire -// -// Created by Shariq Charolia on 2025-06-30. -// - - -#import -#import "NDNotificationCenterHackery.h" - -@implementation NDNotificationCenterHackery - -+ (void)removeDefaultAction:(UNMutableNotificationContent*) content{ - content.hasDefaultAction = NO; -} - -@end \ No newline at end of file diff --git a/submissions/sapphire/ObjC/PrivateAPI.h b/submissions/sapphire/ObjC/PrivateAPI.h deleted file mode 100644 index 754c27e1..00000000 --- a/submissions/sapphire/ObjC/PrivateAPI.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// PrivateAPI.h -// DynamicNotch -// - -#ifndef PrivateAPI_h -#define PrivateAPI_h - -#import -#import - -// This is the private function to disable the native macOS bezel HUDs -// for volume, brightness, etc. -void CGSSetBezelHUDEnabled(bool enabled); - -// These are private functions for getting and setting the keyboard backlight brightness. -void HIDPostRequest(uint32_t a, uint32_t b, uint32_t c); -uint32_t HIDGetRequest(uint32_t a, uint32_t b); - -#endif /* PrivateAPI_h */ From d563bd757ee733e88041071196a444b67a68b53c Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:45:59 -0400 Subject: [PATCH 09/16] Delete submissions/sapphire/Util directory --- .../sapphire/Util/Data+Extensions.swift | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 submissions/sapphire/Util/Data+Extensions.swift diff --git a/submissions/sapphire/Util/Data+Extensions.swift b/submissions/sapphire/Util/Data+Extensions.swift deleted file mode 100644 index efa8472a..00000000 --- a/submissions/sapphire/Util/Data+Extensions.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// Data+URLSafeBase64.swift -// NearDrop -// -// Created by Grishka on 08.04.2023. -// - -import Foundation -import CoreFoundation - -extension Data{ - func urlSafeBase64EncodedString() -> String { - return String(base64EncodedString().replacingOccurrences(of: "=", with: "").map { - if $0=="/"{ - return "_" - } else if $0=="+" { - return "-" - } else { - return $0 - } - }) - } - - static func randomData(length: Int) -> Data{ - var data=Data(count: length) - data.withUnsafeMutableBytes { - guard 0 == SecRandomCopyBytes(kSecRandomDefault, length, $0.baseAddress!) else { fatalError() } - } - return data - } - - static func dataFromUrlSafeBase64(_ str:String)->Data?{ - var regularB64=String(str.map{ - if $0=="_"{ - return "/" - }else if $0=="-"{ - return "+" - }else{ - return $0 - } - }) - while (regularB64.count%4) != 0{ - regularB64=regularB64+"=" - } - return Data(base64Encoded: regularB64, options: .ignoreUnknownCharacters) - } -} From e7587d4fd435728cc41348de96597deea9ef0156 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:46:07 -0400 Subject: [PATCH 10/16] Delete submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents directory --- .../Contents/Info.plist | 40 ------------------- .../Contents/Resources/PrivacyInfo.xcprivacy | 14 ------- 2 files changed, 54 deletions(-) delete mode 100644 submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist delete mode 100644 submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy diff --git a/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist b/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist deleted file mode 100644 index 8ffa2b0b..00000000 --- a/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Info.plist +++ /dev/null @@ -1,40 +0,0 @@ - - - - - BuildMachineOSBuild - 25A5306g - CFBundleDevelopmentRegion - en - CFBundleIdentifier - swift-protobuf.SwiftProtobuf.resources - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - SwiftProtobuf_SwiftProtobuf - CFBundlePackageType - BNDL - CFBundleSupportedPlatforms - - MacOSX - - DTCompiler - com.apple.compilers.llvm.clang.1_0 - DTPlatformBuild - 24F74 - DTPlatformName - macosx - DTPlatformVersion - 15.5 - DTSDKBuild - 24F74 - DTSDKName - macosx15.5 - DTXcode - 1640 - DTXcodeBuild - 16F6 - LSMinimumSystemVersion - 10.13 - - diff --git a/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy b/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy deleted file mode 100644 index e5407507..00000000 --- a/submissions/sapphire/SwiftProtobuf_SwiftProtobuf.bundle/Contents/Resources/PrivacyInfo.xcprivacy +++ /dev/null @@ -1,14 +0,0 @@ - - - - - NSPrivacyTracking - - NSPrivacyAccessedAPITypes - - NSPrivacyCollectedDataTypes - - NSPrivacyTrackingDomains - - - From cf32799c258f7a9149e08c59d7e25facf52604ed Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:47:00 -0400 Subject: [PATCH 11/16] Delete submissions/sapphire/SapphireNotchUITests directory --- .../DynamicNotchUITests.swift | 41 ------------------- .../DynamicNotchUITestsLaunchTests.swift | 33 --------------- 2 files changed, 74 deletions(-) delete mode 100644 submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift delete mode 100644 submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift diff --git a/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift b/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift deleted file mode 100644 index d2ba60f2..00000000 --- a/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITests.swift +++ /dev/null @@ -1,41 +0,0 @@ -// -// DynamicNotchUITests.swift -// DynamicNotchUITests -// -// Created by Shariq Charolia on 2025-05-07. -// - -import XCTest - -final class DynamicNotchUITests: XCTestCase { - - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false - - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - @MainActor - func testExample() throws { - // UI tests must launch the application that they test. - let app = XCUIApplication() - app.launch() - - // Use XCTAssert and related functions to verify your tests produce the correct results. - } - - @MainActor - func testLaunchPerformance() throws { - // This measures how long it takes to launch your application. - measure(metrics: [XCTApplicationLaunchMetric()]) { - XCUIApplication().launch() - } - } -} diff --git a/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift b/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift deleted file mode 100644 index 721f0454..00000000 --- a/submissions/sapphire/SapphireNotchUITests/DynamicNotchUITestsLaunchTests.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// DynamicNotchUITestsLaunchTests.swift -// DynamicNotchUITests -// -// Created by Shariq Charolia on 2025-05-07. -// - -import XCTest - -final class DynamicNotchUITestsLaunchTests: XCTestCase { - - override class var runsForEachTargetApplicationUIConfiguration: Bool { - true - } - - override func setUpWithError() throws { - continueAfterFailure = false - } - - @MainActor - func testLaunch() throws { - let app = XCUIApplication() - app.launch() - - // Insert steps here to perform after app launch but before taking a screenshot, - // such as logging into a test account or navigating somewhere in the app - - let attachment = XCTAttachment(screenshot: app.screenshot()) - attachment.name = "Launch Screen" - attachment.lifetime = .keepAlways - add(attachment) - } -} From b3f5e58488d555719a43726863458865b69ae6cf Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:47:08 -0400 Subject: [PATCH 12/16] Delete submissions/sapphire/ProtobufGenerated directory --- .../device_to_device_messages.pb.swift | 540 --- .../offline_wire_formats.pb.swift | 3653 ----------------- .../ProtobufGenerated/securegcm.pb.swift | 1522 ------- .../ProtobufGenerated/securemessage.pb.swift | 951 ----- .../sapphire/ProtobufGenerated/ukey.pb.swift | 735 ---- .../ProtobufGenerated/wire_format.pb.swift | 1617 -------- 6 files changed, 9018 deletions(-) delete mode 100644 submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift delete mode 100644 submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift delete mode 100644 submissions/sapphire/ProtobufGenerated/securegcm.pb.swift delete mode 100644 submissions/sapphire/ProtobufGenerated/securemessage.pb.swift delete mode 100644 submissions/sapphire/ProtobufGenerated/ukey.pb.swift delete mode 100644 submissions/sapphire/ProtobufGenerated/wire_format.pb.swift diff --git a/submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift b/submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift deleted file mode 100644 index 61ccd84b..00000000 --- a/submissions/sapphire/ProtobufGenerated/device_to_device_messages.pb.swift +++ /dev/null @@ -1,540 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: device_to_device_messages.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that you are building against the same version of the API -// that was used to generate this file. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -/// Type of curve -enum Securegcm_Curve: SwiftProtobuf.Enum { - typealias RawValue = Int - case ed25519 // = 1 - - init() { - self = .ed25519 - } - - init?(rawValue: Int) { - switch rawValue { - case 1: self = .ed25519 - default: return nil - } - } - - var rawValue: Int { - switch self { - case .ed25519: return 1 - } - } - -} - -#if swift(>=4.2) - -extension Securegcm_Curve: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// Used by protocols between devices -struct Securegcm_DeviceToDeviceMessage { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// the payload of the message - var message: Data { - get {return _message ?? Data()} - set {_message = newValue} - } - /// Returns true if `message` has been explicitly set. - var hasMessage: Bool {return self._message != nil} - /// Clears the value of `message`. Subsequent reads from it will return its default value. - mutating func clearMessage() {self._message = nil} - - /// the sequence number of the message - must be increasing. - var sequenceNumber: Int32 { - get {return _sequenceNumber ?? 0} - set {_sequenceNumber = newValue} - } - /// Returns true if `sequenceNumber` has been explicitly set. - var hasSequenceNumber: Bool {return self._sequenceNumber != nil} - /// Clears the value of `sequenceNumber`. Subsequent reads from it will return its default value. - mutating func clearSequenceNumber() {self._sequenceNumber = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _message: Data? = nil - fileprivate var _sequenceNumber: Int32? = nil -} - -/// sent as the first message from initiator to responder -/// in an unauthenticated Diffie-Hellman Key Exchange -struct Securegcm_InitiatorHello { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The session public key to send to the responder - var publicDhKey: Securemessage_GenericPublicKey { - get {return _publicDhKey ?? Securemessage_GenericPublicKey()} - set {_publicDhKey = newValue} - } - /// Returns true if `publicDhKey` has been explicitly set. - var hasPublicDhKey: Bool {return self._publicDhKey != nil} - /// Clears the value of `publicDhKey`. Subsequent reads from it will return its default value. - mutating func clearPublicDhKey() {self._publicDhKey = nil} - - /// The protocol version - var protocolVersion: Int32 { - get {return _protocolVersion ?? 0} - set {_protocolVersion = newValue} - } - /// Returns true if `protocolVersion` has been explicitly set. - var hasProtocolVersion: Bool {return self._protocolVersion != nil} - /// Clears the value of `protocolVersion`. Subsequent reads from it will return its default value. - mutating func clearProtocolVersion() {self._protocolVersion = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _publicDhKey: Securemessage_GenericPublicKey? = nil - fileprivate var _protocolVersion: Int32? = nil -} - -/// sent inside the header of the first message from the responder to the -/// initiator in an unauthenticated Diffie-Hellman Key Exchange -struct Securegcm_ResponderHello { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The session public key to send to the initiator - var publicDhKey: Securemessage_GenericPublicKey { - get {return _publicDhKey ?? Securemessage_GenericPublicKey()} - set {_publicDhKey = newValue} - } - /// Returns true if `publicDhKey` has been explicitly set. - var hasPublicDhKey: Bool {return self._publicDhKey != nil} - /// Clears the value of `publicDhKey`. Subsequent reads from it will return its default value. - mutating func clearPublicDhKey() {self._publicDhKey = nil} - - /// The protocol version - var protocolVersion: Int32 { - get {return _protocolVersion ?? 0} - set {_protocolVersion = newValue} - } - /// Returns true if `protocolVersion` has been explicitly set. - var hasProtocolVersion: Bool {return self._protocolVersion != nil} - /// Clears the value of `protocolVersion`. Subsequent reads from it will return its default value. - mutating func clearProtocolVersion() {self._protocolVersion = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _publicDhKey: Securemessage_GenericPublicKey? = nil - fileprivate var _protocolVersion: Int32? = nil -} - -/// A convenience proto for encoding curve points in affine representation -struct Securegcm_EcPoint { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var curve: Securegcm_Curve { - get {return _curve ?? .ed25519} - set {_curve = newValue} - } - /// Returns true if `curve` has been explicitly set. - var hasCurve: Bool {return self._curve != nil} - /// Clears the value of `curve`. Subsequent reads from it will return its default value. - mutating func clearCurve() {self._curve = nil} - - /// x and y are encoded in big-endian two's complement - /// client MUST verify (x,y) is a valid point on the specified curve - var x: Data { - get {return _x ?? Data()} - set {_x = newValue} - } - /// Returns true if `x` has been explicitly set. - var hasX: Bool {return self._x != nil} - /// Clears the value of `x`. Subsequent reads from it will return its default value. - mutating func clearX() {self._x = nil} - - var y: Data { - get {return _y ?? Data()} - set {_y = newValue} - } - /// Returns true if `y` has been explicitly set. - var hasY: Bool {return self._y != nil} - /// Clears the value of `y`. Subsequent reads from it will return its default value. - mutating func clearY() {self._y = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _curve: Securegcm_Curve? = nil - fileprivate var _x: Data? = nil - fileprivate var _y: Data? = nil -} - -struct Securegcm_SpakeHandshakeMessage { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Each flow in the protocol bumps this counter - var flowNumber: Int32 { - get {return _flowNumber ?? 0} - set {_flowNumber = newValue} - } - /// Returns true if `flowNumber` has been explicitly set. - var hasFlowNumber: Bool {return self._flowNumber != nil} - /// Clears the value of `flowNumber`. Subsequent reads from it will return its default value. - mutating func clearFlowNumber() {self._flowNumber = nil} - - /// Some (but not all) SPAKE flows send a point on an elliptic curve - var ecPoint: Securegcm_EcPoint { - get {return _ecPoint ?? Securegcm_EcPoint()} - set {_ecPoint = newValue} - } - /// Returns true if `ecPoint` has been explicitly set. - var hasEcPoint: Bool {return self._ecPoint != nil} - /// Clears the value of `ecPoint`. Subsequent reads from it will return its default value. - mutating func clearEcPoint() {self._ecPoint = nil} - - /// Some (but not all) SPAKE flows send a hash value - var hashValue_p: Data { - get {return _hashValue_p ?? Data()} - set {_hashValue_p = newValue} - } - /// Returns true if `hashValue_p` has been explicitly set. - var hasHashValue_p: Bool {return self._hashValue_p != nil} - /// Clears the value of `hashValue_p`. Subsequent reads from it will return its default value. - mutating func clearHashValue_p() {self._hashValue_p = nil} - - /// The last flow of a SPAKE protocol can send an optional payload, - /// since the key exchange is already complete on the sender's side. - var payload: Data { - get {return _payload ?? Data()} - set {_payload = newValue} - } - /// Returns true if `payload` has been explicitly set. - var hasPayload: Bool {return self._payload != nil} - /// Clears the value of `payload`. Subsequent reads from it will return its default value. - mutating func clearPayload() {self._payload = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _flowNumber: Int32? = nil - fileprivate var _ecPoint: Securegcm_EcPoint? = nil - fileprivate var _hashValue_p: Data? = nil - fileprivate var _payload: Data? = nil -} - -#if swift(>=5.5) && canImport(_Concurrency) -extension Securegcm_Curve: @unchecked Sendable {} -extension Securegcm_DeviceToDeviceMessage: @unchecked Sendable {} -extension Securegcm_InitiatorHello: @unchecked Sendable {} -extension Securegcm_ResponderHello: @unchecked Sendable {} -extension Securegcm_EcPoint: @unchecked Sendable {} -extension Securegcm_SpakeHandshakeMessage: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "securegcm" - -extension Securegcm_Curve: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "ED_25519"), - ] -} - -extension Securegcm_DeviceToDeviceMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".DeviceToDeviceMessage" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "message"), - 2: .standard(proto: "sequence_number"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._message) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self._sequenceNumber) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._message { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._sequenceNumber { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_DeviceToDeviceMessage, rhs: Securegcm_DeviceToDeviceMessage) -> Bool { - if lhs._message != rhs._message {return false} - if lhs._sequenceNumber != rhs._sequenceNumber {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_InitiatorHello: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".InitiatorHello" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "public_dh_key"), - 2: .standard(proto: "protocol_version"), - ] - - public var isInitialized: Bool { - if let v = self._publicDhKey, !v.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &self._publicDhKey) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self._protocolVersion) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._publicDhKey { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try { if let v = self._protocolVersion { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_InitiatorHello, rhs: Securegcm_InitiatorHello) -> Bool { - if lhs._publicDhKey != rhs._publicDhKey {return false} - if lhs._protocolVersion != rhs._protocolVersion {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_ResponderHello: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".ResponderHello" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "public_dh_key"), - 2: .standard(proto: "protocol_version"), - ] - - public var isInitialized: Bool { - if let v = self._publicDhKey, !v.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &self._publicDhKey) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self._protocolVersion) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._publicDhKey { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try { if let v = self._protocolVersion { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_ResponderHello, rhs: Securegcm_ResponderHello) -> Bool { - if lhs._publicDhKey != rhs._publicDhKey {return false} - if lhs._protocolVersion != rhs._protocolVersion {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_EcPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".EcPoint" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "curve"), - 2: .same(proto: "x"), - 3: .same(proto: "y"), - ] - - public var isInitialized: Bool { - if self._curve == nil {return false} - if self._x == nil {return false} - if self._y == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._curve) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._x) }() - case 3: try { try decoder.decodeSingularBytesField(value: &self._y) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._curve { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._x { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try { if let v = self._y { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_EcPoint, rhs: Securegcm_EcPoint) -> Bool { - if lhs._curve != rhs._curve {return false} - if lhs._x != rhs._x {return false} - if lhs._y != rhs._y {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_SpakeHandshakeMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".SpakeHandshakeMessage" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "flow_number"), - 2: .standard(proto: "ec_point"), - 3: .standard(proto: "hash_value"), - 4: .same(proto: "payload"), - ] - - public var isInitialized: Bool { - if let v = self._ecPoint, !v.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularInt32Field(value: &self._flowNumber) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._ecPoint) }() - case 3: try { try decoder.decodeSingularBytesField(value: &self._hashValue_p) }() - case 4: try { try decoder.decodeSingularBytesField(value: &self._payload) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._flowNumber { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) - } }() - try { if let v = self._ecPoint { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._hashValue_p { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try { if let v = self._payload { - try visitor.visitSingularBytesField(value: v, fieldNumber: 4) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_SpakeHandshakeMessage, rhs: Securegcm_SpakeHandshakeMessage) -> Bool { - if lhs._flowNumber != rhs._flowNumber {return false} - if lhs._ecPoint != rhs._ecPoint {return false} - if lhs._hashValue_p != rhs._hashValue_p {return false} - if lhs._payload != rhs._payload {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift b/submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift deleted file mode 100644 index 7524b1ce..00000000 --- a/submissions/sapphire/ProtobufGenerated/offline_wire_formats.pb.swift +++ /dev/null @@ -1,3653 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: offline_wire_formats.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that you are building against the same version of the API -// that was used to generate this file. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -struct Location_Nearby_Connections_OfflineFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var version: Location_Nearby_Connections_OfflineFrame.Version { - get {return _version ?? .unknownVersion} - set {_version = newValue} - } - /// Returns true if `version` has been explicitly set. - var hasVersion: Bool {return self._version != nil} - /// Clears the value of `version`. Subsequent reads from it will return its default value. - mutating func clearVersion() {self._version = nil} - - /// Right now there's only 1 version, but if there are more, exactly one of - /// the following fields will be set. - var v1: Location_Nearby_Connections_V1Frame { - get {return _v1 ?? Location_Nearby_Connections_V1Frame()} - set {_v1 = newValue} - } - /// Returns true if `v1` has been explicitly set. - var hasV1: Bool {return self._v1 != nil} - /// Clears the value of `v1`. Subsequent reads from it will return its default value. - mutating func clearV1() {self._v1 = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum Version: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownVersion // = 0 - case v1 // = 1 - - init() { - self = .unknownVersion - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownVersion - case 1: self = .v1 - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownVersion: return 0 - case .v1: return 1 - } - } - - } - - init() {} - - fileprivate var _version: Location_Nearby_Connections_OfflineFrame.Version? = nil - fileprivate var _v1: Location_Nearby_Connections_V1Frame? = nil -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_OfflineFrame.Version: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Location_Nearby_Connections_V1Frame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var type: Location_Nearby_Connections_V1Frame.FrameType { - get {return _storage._type ?? .unknownFrameType} - set {_uniqueStorage()._type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return _storage._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {_uniqueStorage()._type = nil} - - /// Exactly one of the following fields will be set. - var connectionRequest: Location_Nearby_Connections_ConnectionRequestFrame { - get {return _storage._connectionRequest ?? Location_Nearby_Connections_ConnectionRequestFrame()} - set {_uniqueStorage()._connectionRequest = newValue} - } - /// Returns true if `connectionRequest` has been explicitly set. - var hasConnectionRequest: Bool {return _storage._connectionRequest != nil} - /// Clears the value of `connectionRequest`. Subsequent reads from it will return its default value. - mutating func clearConnectionRequest() {_uniqueStorage()._connectionRequest = nil} - - var connectionResponse: Location_Nearby_Connections_ConnectionResponseFrame { - get {return _storage._connectionResponse ?? Location_Nearby_Connections_ConnectionResponseFrame()} - set {_uniqueStorage()._connectionResponse = newValue} - } - /// Returns true if `connectionResponse` has been explicitly set. - var hasConnectionResponse: Bool {return _storage._connectionResponse != nil} - /// Clears the value of `connectionResponse`. Subsequent reads from it will return its default value. - mutating func clearConnectionResponse() {_uniqueStorage()._connectionResponse = nil} - - var payloadTransfer: Location_Nearby_Connections_PayloadTransferFrame { - get {return _storage._payloadTransfer ?? Location_Nearby_Connections_PayloadTransferFrame()} - set {_uniqueStorage()._payloadTransfer = newValue} - } - /// Returns true if `payloadTransfer` has been explicitly set. - var hasPayloadTransfer: Bool {return _storage._payloadTransfer != nil} - /// Clears the value of `payloadTransfer`. Subsequent reads from it will return its default value. - mutating func clearPayloadTransfer() {_uniqueStorage()._payloadTransfer = nil} - - var bandwidthUpgradeNegotiation: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame { - get {return _storage._bandwidthUpgradeNegotiation ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame()} - set {_uniqueStorage()._bandwidthUpgradeNegotiation = newValue} - } - /// Returns true if `bandwidthUpgradeNegotiation` has been explicitly set. - var hasBandwidthUpgradeNegotiation: Bool {return _storage._bandwidthUpgradeNegotiation != nil} - /// Clears the value of `bandwidthUpgradeNegotiation`. Subsequent reads from it will return its default value. - mutating func clearBandwidthUpgradeNegotiation() {_uniqueStorage()._bandwidthUpgradeNegotiation = nil} - - var keepAlive: Location_Nearby_Connections_KeepAliveFrame { - get {return _storage._keepAlive ?? Location_Nearby_Connections_KeepAliveFrame()} - set {_uniqueStorage()._keepAlive = newValue} - } - /// Returns true if `keepAlive` has been explicitly set. - var hasKeepAlive: Bool {return _storage._keepAlive != nil} - /// Clears the value of `keepAlive`. Subsequent reads from it will return its default value. - mutating func clearKeepAlive() {_uniqueStorage()._keepAlive = nil} - - var disconnection: Location_Nearby_Connections_DisconnectionFrame { - get {return _storage._disconnection ?? Location_Nearby_Connections_DisconnectionFrame()} - set {_uniqueStorage()._disconnection = newValue} - } - /// Returns true if `disconnection` has been explicitly set. - var hasDisconnection: Bool {return _storage._disconnection != nil} - /// Clears the value of `disconnection`. Subsequent reads from it will return its default value. - mutating func clearDisconnection() {_uniqueStorage()._disconnection = nil} - - var pairedKeyEncryption: Location_Nearby_Connections_PairedKeyEncryptionFrame { - get {return _storage._pairedKeyEncryption ?? Location_Nearby_Connections_PairedKeyEncryptionFrame()} - set {_uniqueStorage()._pairedKeyEncryption = newValue} - } - /// Returns true if `pairedKeyEncryption` has been explicitly set. - var hasPairedKeyEncryption: Bool {return _storage._pairedKeyEncryption != nil} - /// Clears the value of `pairedKeyEncryption`. Subsequent reads from it will return its default value. - mutating func clearPairedKeyEncryption() {_uniqueStorage()._pairedKeyEncryption = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum FrameType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownFrameType // = 0 - case connectionRequest // = 1 - case connectionResponse // = 2 - case payloadTransfer // = 3 - case bandwidthUpgradeNegotiation // = 4 - case keepAlive // = 5 - case disconnection // = 6 - case pairedKeyEncryption // = 7 - - init() { - self = .unknownFrameType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownFrameType - case 1: self = .connectionRequest - case 2: self = .connectionResponse - case 3: self = .payloadTransfer - case 4: self = .bandwidthUpgradeNegotiation - case 5: self = .keepAlive - case 6: self = .disconnection - case 7: self = .pairedKeyEncryption - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownFrameType: return 0 - case .connectionRequest: return 1 - case .connectionResponse: return 2 - case .payloadTransfer: return 3 - case .bandwidthUpgradeNegotiation: return 4 - case .keepAlive: return 5 - case .disconnection: return 6 - case .pairedKeyEncryption: return 7 - } - } - - } - - init() {} - - fileprivate var _storage = _StorageClass.defaultInstance -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_V1Frame.FrameType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Location_Nearby_Connections_ConnectionRequestFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var endpointID: String { - get {return _storage._endpointID ?? String()} - set {_uniqueStorage()._endpointID = newValue} - } - /// Returns true if `endpointID` has been explicitly set. - var hasEndpointID: Bool {return _storage._endpointID != nil} - /// Clears the value of `endpointID`. Subsequent reads from it will return its default value. - mutating func clearEndpointID() {_uniqueStorage()._endpointID = nil} - - var endpointName: String { - get {return _storage._endpointName ?? String()} - set {_uniqueStorage()._endpointName = newValue} - } - /// Returns true if `endpointName` has been explicitly set. - var hasEndpointName: Bool {return _storage._endpointName != nil} - /// Clears the value of `endpointName`. Subsequent reads from it will return its default value. - mutating func clearEndpointName() {_uniqueStorage()._endpointName = nil} - - var handshakeData: Data { - get {return _storage._handshakeData ?? Data()} - set {_uniqueStorage()._handshakeData = newValue} - } - /// Returns true if `handshakeData` has been explicitly set. - var hasHandshakeData: Bool {return _storage._handshakeData != nil} - /// Clears the value of `handshakeData`. Subsequent reads from it will return its default value. - mutating func clearHandshakeData() {_uniqueStorage()._handshakeData = nil} - - /// A random number generated for each outgoing connection that is presently - /// used to act as a tiebreaker when 2 devices connect to each other - /// simultaneously; this can also be used for other initialization-scoped - /// things in the future. - var nonce: Int32 { - get {return _storage._nonce ?? 0} - set {_uniqueStorage()._nonce = newValue} - } - /// Returns true if `nonce` has been explicitly set. - var hasNonce: Bool {return _storage._nonce != nil} - /// Clears the value of `nonce`. Subsequent reads from it will return its default value. - mutating func clearNonce() {_uniqueStorage()._nonce = nil} - - /// The mediums this device supports upgrading to. This list should be filtered - /// by both the strategy and this device's individual limitations. - var mediums: [Location_Nearby_Connections_ConnectionRequestFrame.Medium] { - get {return _storage._mediums} - set {_uniqueStorage()._mediums = newValue} - } - - var endpointInfo: Data { - get {return _storage._endpointInfo ?? Data()} - set {_uniqueStorage()._endpointInfo = newValue} - } - /// Returns true if `endpointInfo` has been explicitly set. - var hasEndpointInfo: Bool {return _storage._endpointInfo != nil} - /// Clears the value of `endpointInfo`. Subsequent reads from it will return its default value. - mutating func clearEndpointInfo() {_uniqueStorage()._endpointInfo = nil} - - var mediumMetadata: Location_Nearby_Connections_MediumMetadata { - get {return _storage._mediumMetadata ?? Location_Nearby_Connections_MediumMetadata()} - set {_uniqueStorage()._mediumMetadata = newValue} - } - /// Returns true if `mediumMetadata` has been explicitly set. - var hasMediumMetadata: Bool {return _storage._mediumMetadata != nil} - /// Clears the value of `mediumMetadata`. Subsequent reads from it will return its default value. - mutating func clearMediumMetadata() {_uniqueStorage()._mediumMetadata = nil} - - var keepAliveIntervalMillis: Int32 { - get {return _storage._keepAliveIntervalMillis ?? 0} - set {_uniqueStorage()._keepAliveIntervalMillis = newValue} - } - /// Returns true if `keepAliveIntervalMillis` has been explicitly set. - var hasKeepAliveIntervalMillis: Bool {return _storage._keepAliveIntervalMillis != nil} - /// Clears the value of `keepAliveIntervalMillis`. Subsequent reads from it will return its default value. - mutating func clearKeepAliveIntervalMillis() {_uniqueStorage()._keepAliveIntervalMillis = nil} - - var keepAliveTimeoutMillis: Int32 { - get {return _storage._keepAliveTimeoutMillis ?? 0} - set {_uniqueStorage()._keepAliveTimeoutMillis = newValue} - } - /// Returns true if `keepAliveTimeoutMillis` has been explicitly set. - var hasKeepAliveTimeoutMillis: Bool {return _storage._keepAliveTimeoutMillis != nil} - /// Clears the value of `keepAliveTimeoutMillis`. Subsequent reads from it will return its default value. - mutating func clearKeepAliveTimeoutMillis() {_uniqueStorage()._keepAliveTimeoutMillis = nil} - - /// The type of {@link Device} object. - var deviceType: Int32 { - get {return _storage._deviceType ?? 0} - set {_uniqueStorage()._deviceType = newValue} - } - /// Returns true if `deviceType` has been explicitly set. - var hasDeviceType: Bool {return _storage._deviceType != nil} - /// Clears the value of `deviceType`. Subsequent reads from it will return its default value. - mutating func clearDeviceType() {_uniqueStorage()._deviceType = nil} - - /// The bytes of serialized {@link Device} object. - var deviceInfo: Data { - get {return _storage._deviceInfo ?? Data()} - set {_uniqueStorage()._deviceInfo = newValue} - } - /// Returns true if `deviceInfo` has been explicitly set. - var hasDeviceInfo: Bool {return _storage._deviceInfo != nil} - /// Clears the value of `deviceInfo`. Subsequent reads from it will return its default value. - mutating func clearDeviceInfo() {_uniqueStorage()._deviceInfo = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - /// Should always match cs/symbol:location.nearby.proto.connections.Medium - /// LINT.IfChange - enum Medium: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownMedium // = 0 - case mdns // = 1 - case bluetooth // = 2 - case wifiHotspot // = 3 - case ble // = 4 - case wifiLan // = 5 - case wifiAware // = 6 - case nfc // = 7 - case wifiDirect // = 8 - case webRtc // = 9 - case bleL2Cap // = 10 - case usb // = 11 - - init() { - self = .unknownMedium - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownMedium - case 1: self = .mdns - case 2: self = .bluetooth - case 3: self = .wifiHotspot - case 4: self = .ble - case 5: self = .wifiLan - case 6: self = .wifiAware - case 7: self = .nfc - case 8: self = .wifiDirect - case 9: self = .webRtc - case 10: self = .bleL2Cap - case 11: self = .usb - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownMedium: return 0 - case .mdns: return 1 - case .bluetooth: return 2 - case .wifiHotspot: return 3 - case .ble: return 4 - case .wifiLan: return 5 - case .wifiAware: return 6 - case .nfc: return 7 - case .wifiDirect: return 8 - case .webRtc: return 9 - case .bleL2Cap: return 10 - case .usb: return 11 - } - } - - } - - init() {} - - fileprivate var _storage = _StorageClass.defaultInstance -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_ConnectionRequestFrame.Medium: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// This doesn't need to send back endpoint_id and endpoint_name (like -/// the ConnectionRequestFrame does) because those have already been -/// transmitted out-of-band, at the time this endpoint was discovered. -struct Location_Nearby_Connections_ConnectionResponseFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// One of: - /// - /// - ConnectionsStatusCodes.STATUS_OK - /// - ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED. - var status: Int32 { - get {return _status ?? 0} - set {_status = newValue} - } - /// Returns true if `status` has been explicitly set. - var hasStatus: Bool {return self._status != nil} - /// Clears the value of `status`. Subsequent reads from it will return its default value. - mutating func clearStatus() {self._status = nil} - - var handshakeData: Data { - get {return _handshakeData ?? Data()} - set {_handshakeData = newValue} - } - /// Returns true if `handshakeData` has been explicitly set. - var hasHandshakeData: Bool {return self._handshakeData != nil} - /// Clears the value of `handshakeData`. Subsequent reads from it will return its default value. - mutating func clearHandshakeData() {self._handshakeData = nil} - - var response: Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus { - get {return _response ?? .unknownResponseStatus} - set {_response = newValue} - } - /// Returns true if `response` has been explicitly set. - var hasResponse: Bool {return self._response != nil} - /// Clears the value of `response`. Subsequent reads from it will return its default value. - mutating func clearResponse() {self._response = nil} - - var osInfo: Location_Nearby_Connections_OsInfo { - get {return _osInfo ?? Location_Nearby_Connections_OsInfo()} - set {_osInfo = newValue} - } - /// Returns true if `osInfo` has been explicitly set. - var hasOsInfo: Bool {return self._osInfo != nil} - /// Clears the value of `osInfo`. Subsequent reads from it will return its default value. - mutating func clearOsInfo() {self._osInfo = nil} - - /// A bitmask value to indicate which medium supports Multiplex transmission - /// feature. Each supporting medium could utilize one bit starting from the - /// least significant bit in this field. eq. BT utilizes the LSB bit which 0x01 - /// means bt supports multiplex while 0x00 means not. Refer to ClientProxy.java - /// for the bit usages. - var multiplexSocketBitmask: Int32 { - get {return _multiplexSocketBitmask ?? 0} - set {_multiplexSocketBitmask = newValue} - } - /// Returns true if `multiplexSocketBitmask` has been explicitly set. - var hasMultiplexSocketBitmask: Bool {return self._multiplexSocketBitmask != nil} - /// Clears the value of `multiplexSocketBitmask`. Subsequent reads from it will return its default value. - mutating func clearMultiplexSocketBitmask() {self._multiplexSocketBitmask = nil} - - var nearbyConnectionsVersion: Int32 { - get {return _nearbyConnectionsVersion ?? 0} - set {_nearbyConnectionsVersion = newValue} - } - /// Returns true if `nearbyConnectionsVersion` has been explicitly set. - var hasNearbyConnectionsVersion: Bool {return self._nearbyConnectionsVersion != nil} - /// Clears the value of `nearbyConnectionsVersion`. Subsequent reads from it will return its default value. - mutating func clearNearbyConnectionsVersion() {self._nearbyConnectionsVersion = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - /// Used to replace the status integer parameter with a meaningful enum item. - /// Map ConnectionsStatusCodes.STATUS_OK to ACCEPT and - /// ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED to REJECT. - /// Flag: connection_replace_status_with_response_connectionResponseFrame - enum ResponseStatus: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownResponseStatus // = 0 - case accept // = 1 - case reject // = 2 - - init() { - self = .unknownResponseStatus - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownResponseStatus - case 1: self = .accept - case 2: self = .reject - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownResponseStatus: return 0 - case .accept: return 1 - case .reject: return 2 - } - } - - } - - init() {} - - fileprivate var _status: Int32? = nil - fileprivate var _handshakeData: Data? = nil - fileprivate var _response: Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus? = nil - fileprivate var _osInfo: Location_Nearby_Connections_OsInfo? = nil - fileprivate var _multiplexSocketBitmask: Int32? = nil - fileprivate var _nearbyConnectionsVersion: Int32? = nil -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Location_Nearby_Connections_PayloadTransferFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var packetType: Location_Nearby_Connections_PayloadTransferFrame.PacketType { - get {return _packetType ?? .unknownPacketType} - set {_packetType = newValue} - } - /// Returns true if `packetType` has been explicitly set. - var hasPacketType: Bool {return self._packetType != nil} - /// Clears the value of `packetType`. Subsequent reads from it will return its default value. - mutating func clearPacketType() {self._packetType = nil} - - var payloadHeader: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader { - get {return _payloadHeader ?? Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader()} - set {_payloadHeader = newValue} - } - /// Returns true if `payloadHeader` has been explicitly set. - var hasPayloadHeader: Bool {return self._payloadHeader != nil} - /// Clears the value of `payloadHeader`. Subsequent reads from it will return its default value. - mutating func clearPayloadHeader() {self._payloadHeader = nil} - - /// Exactly one of the following fields will be set, depending on the type. - var payloadChunk: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk { - get {return _payloadChunk ?? Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk()} - set {_payloadChunk = newValue} - } - /// Returns true if `payloadChunk` has been explicitly set. - var hasPayloadChunk: Bool {return self._payloadChunk != nil} - /// Clears the value of `payloadChunk`. Subsequent reads from it will return its default value. - mutating func clearPayloadChunk() {self._payloadChunk = nil} - - var controlMessage: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage { - get {return _controlMessage ?? Location_Nearby_Connections_PayloadTransferFrame.ControlMessage()} - set {_controlMessage = newValue} - } - /// Returns true if `controlMessage` has been explicitly set. - var hasControlMessage: Bool {return self._controlMessage != nil} - /// Clears the value of `controlMessage`. Subsequent reads from it will return its default value. - mutating func clearControlMessage() {self._controlMessage = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum PacketType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownPacketType // = 0 - case data // = 1 - case control // = 2 - - init() { - self = .unknownPacketType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownPacketType - case 1: self = .data - case 2: self = .control - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownPacketType: return 0 - case .data: return 1 - case .control: return 2 - } - } - - } - - struct PayloadHeader { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var id: Int64 { - get {return _id ?? 0} - set {_id = newValue} - } - /// Returns true if `id` has been explicitly set. - var hasID: Bool {return self._id != nil} - /// Clears the value of `id`. Subsequent reads from it will return its default value. - mutating func clearID() {self._id = nil} - - var type: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType { - get {return _type ?? .unknownPayloadType} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - var totalSize: Int64 { - get {return _totalSize ?? 0} - set {_totalSize = newValue} - } - /// Returns true if `totalSize` has been explicitly set. - var hasTotalSize: Bool {return self._totalSize != nil} - /// Clears the value of `totalSize`. Subsequent reads from it will return its default value. - mutating func clearTotalSize() {self._totalSize = nil} - - var isSensitive: Bool { - get {return _isSensitive ?? false} - set {_isSensitive = newValue} - } - /// Returns true if `isSensitive` has been explicitly set. - var hasIsSensitive: Bool {return self._isSensitive != nil} - /// Clears the value of `isSensitive`. Subsequent reads from it will return its default value. - mutating func clearIsSensitive() {self._isSensitive = nil} - - var fileName: String { - get {return _fileName ?? String()} - set {_fileName = newValue} - } - /// Returns true if `fileName` has been explicitly set. - var hasFileName: Bool {return self._fileName != nil} - /// Clears the value of `fileName`. Subsequent reads from it will return its default value. - mutating func clearFileName() {self._fileName = nil} - - var parentFolder: String { - get {return _parentFolder ?? String()} - set {_parentFolder = newValue} - } - /// Returns true if `parentFolder` has been explicitly set. - var hasParentFolder: Bool {return self._parentFolder != nil} - /// Clears the value of `parentFolder`. Subsequent reads from it will return its default value. - mutating func clearParentFolder() {self._parentFolder = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum PayloadType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownPayloadType // = 0 - case bytes // = 1 - case file // = 2 - case stream // = 3 - - init() { - self = .unknownPayloadType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownPayloadType - case 1: self = .bytes - case 2: self = .file - case 3: self = .stream - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownPayloadType: return 0 - case .bytes: return 1 - case .file: return 2 - case .stream: return 3 - } - } - - } - - init() {} - - fileprivate var _id: Int64? = nil - fileprivate var _type: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType? = nil - fileprivate var _totalSize: Int64? = nil - fileprivate var _isSensitive: Bool? = nil - fileprivate var _fileName: String? = nil - fileprivate var _parentFolder: String? = nil - } - - /// Accompanies DATA packets. - struct PayloadChunk { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var flags: Int32 { - get {return _flags ?? 0} - set {_flags = newValue} - } - /// Returns true if `flags` has been explicitly set. - var hasFlags: Bool {return self._flags != nil} - /// Clears the value of `flags`. Subsequent reads from it will return its default value. - mutating func clearFlags() {self._flags = nil} - - var offset: Int64 { - get {return _offset ?? 0} - set {_offset = newValue} - } - /// Returns true if `offset` has been explicitly set. - var hasOffset: Bool {return self._offset != nil} - /// Clears the value of `offset`. Subsequent reads from it will return its default value. - mutating func clearOffset() {self._offset = nil} - - var body: Data { - get {return _body ?? Data()} - set {_body = newValue} - } - /// Returns true if `body` has been explicitly set. - var hasBody: Bool {return self._body != nil} - /// Clears the value of `body`. Subsequent reads from it will return its default value. - mutating func clearBody() {self._body = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum Flags: SwiftProtobuf.Enum { - typealias RawValue = Int - case lastChunk // = 1 - - init() { - self = .lastChunk - } - - init?(rawValue: Int) { - switch rawValue { - case 1: self = .lastChunk - default: return nil - } - } - - var rawValue: Int { - switch self { - case .lastChunk: return 1 - } - } - - } - - init() {} - - fileprivate var _flags: Int32? = nil - fileprivate var _offset: Int64? = nil - fileprivate var _body: Data? = nil - } - - /// Accompanies CONTROL packets. - struct ControlMessage { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var event: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType { - get {return _event ?? .unknownEventType} - set {_event = newValue} - } - /// Returns true if `event` has been explicitly set. - var hasEvent: Bool {return self._event != nil} - /// Clears the value of `event`. Subsequent reads from it will return its default value. - mutating func clearEvent() {self._event = nil} - - var offset: Int64 { - get {return _offset ?? 0} - set {_offset = newValue} - } - /// Returns true if `offset` has been explicitly set. - var hasOffset: Bool {return self._offset != nil} - /// Clears the value of `offset`. Subsequent reads from it will return its default value. - mutating func clearOffset() {self._offset = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum EventType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownEventType // = 0 - case payloadError // = 1 - case payloadCanceled // = 2 - case payloadReceivedAck // = 3 - - init() { - self = .unknownEventType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownEventType - case 1: self = .payloadError - case 2: self = .payloadCanceled - case 3: self = .payloadReceivedAck - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownEventType: return 0 - case .payloadError: return 1 - case .payloadCanceled: return 2 - case .payloadReceivedAck: return 3 - } - } - - } - - init() {} - - fileprivate var _event: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType? = nil - fileprivate var _offset: Int64? = nil - } - - init() {} - - fileprivate var _packetType: Location_Nearby_Connections_PayloadTransferFrame.PacketType? = nil - fileprivate var _payloadHeader: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader? = nil - fileprivate var _payloadChunk: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk? = nil - fileprivate var _controlMessage: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage? = nil -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_PayloadTransferFrame.PacketType: CaseIterable { - // Support synthesized by the compiler. -} - -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType: CaseIterable { - // Support synthesized by the compiler. -} - -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk.Flags: CaseIterable { - // Support synthesized by the compiler. -} - -extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var eventType: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType { - get {return _eventType ?? .unknownEventType} - set {_eventType = newValue} - } - /// Returns true if `eventType` has been explicitly set. - var hasEventType: Bool {return self._eventType != nil} - /// Clears the value of `eventType`. Subsequent reads from it will return its default value. - mutating func clearEventType() {self._eventType = nil} - - /// Exactly one of the following fields will be set. - var upgradePathInfo: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo { - get {return _upgradePathInfo ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo()} - set {_upgradePathInfo = newValue} - } - /// Returns true if `upgradePathInfo` has been explicitly set. - var hasUpgradePathInfo: Bool {return self._upgradePathInfo != nil} - /// Clears the value of `upgradePathInfo`. Subsequent reads from it will return its default value. - mutating func clearUpgradePathInfo() {self._upgradePathInfo = nil} - - var clientIntroduction: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction { - get {return _clientIntroduction ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction()} - set {_clientIntroduction = newValue} - } - /// Returns true if `clientIntroduction` has been explicitly set. - var hasClientIntroduction: Bool {return self._clientIntroduction != nil} - /// Clears the value of `clientIntroduction`. Subsequent reads from it will return its default value. - mutating func clearClientIntroduction() {self._clientIntroduction = nil} - - var clientIntroductionAck: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck { - get {return _clientIntroductionAck ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck()} - set {_clientIntroductionAck = newValue} - } - /// Returns true if `clientIntroductionAck` has been explicitly set. - var hasClientIntroductionAck: Bool {return self._clientIntroductionAck != nil} - /// Clears the value of `clientIntroductionAck`. Subsequent reads from it will return its default value. - mutating func clearClientIntroductionAck() {self._clientIntroductionAck = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum EventType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownEventType // = 0 - case upgradePathAvailable // = 1 - case lastWriteToPriorChannel // = 2 - case safeToClosePriorChannel // = 3 - case clientIntroduction // = 4 - case upgradeFailure // = 5 - case clientIntroductionAck // = 6 - - init() { - self = .unknownEventType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownEventType - case 1: self = .upgradePathAvailable - case 2: self = .lastWriteToPriorChannel - case 3: self = .safeToClosePriorChannel - case 4: self = .clientIntroduction - case 5: self = .upgradeFailure - case 6: self = .clientIntroductionAck - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownEventType: return 0 - case .upgradePathAvailable: return 1 - case .lastWriteToPriorChannel: return 2 - case .safeToClosePriorChannel: return 3 - case .clientIntroduction: return 4 - case .upgradeFailure: return 5 - case .clientIntroductionAck: return 6 - } - } - - } - - /// Accompanies UPGRADE_PATH_AVAILABLE and UPGRADE_FAILURE events. - struct UpgradePathInfo { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var medium: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium { - get {return _storage._medium ?? .unknownMedium} - set {_uniqueStorage()._medium = newValue} - } - /// Returns true if `medium` has been explicitly set. - var hasMedium: Bool {return _storage._medium != nil} - /// Clears the value of `medium`. Subsequent reads from it will return its default value. - mutating func clearMedium() {_uniqueStorage()._medium = nil} - - /// Exactly one of the following fields will be set. - var wifiHotspotCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials { - get {return _storage._wifiHotspotCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials()} - set {_uniqueStorage()._wifiHotspotCredentials = newValue} - } - /// Returns true if `wifiHotspotCredentials` has been explicitly set. - var hasWifiHotspotCredentials: Bool {return _storage._wifiHotspotCredentials != nil} - /// Clears the value of `wifiHotspotCredentials`. Subsequent reads from it will return its default value. - mutating func clearWifiHotspotCredentials() {_uniqueStorage()._wifiHotspotCredentials = nil} - - var wifiLanSocket: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket { - get {return _storage._wifiLanSocket ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket()} - set {_uniqueStorage()._wifiLanSocket = newValue} - } - /// Returns true if `wifiLanSocket` has been explicitly set. - var hasWifiLanSocket: Bool {return _storage._wifiLanSocket != nil} - /// Clears the value of `wifiLanSocket`. Subsequent reads from it will return its default value. - mutating func clearWifiLanSocket() {_uniqueStorage()._wifiLanSocket = nil} - - var bluetoothCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials { - get {return _storage._bluetoothCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials()} - set {_uniqueStorage()._bluetoothCredentials = newValue} - } - /// Returns true if `bluetoothCredentials` has been explicitly set. - var hasBluetoothCredentials: Bool {return _storage._bluetoothCredentials != nil} - /// Clears the value of `bluetoothCredentials`. Subsequent reads from it will return its default value. - mutating func clearBluetoothCredentials() {_uniqueStorage()._bluetoothCredentials = nil} - - var wifiAwareCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials { - get {return _storage._wifiAwareCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials()} - set {_uniqueStorage()._wifiAwareCredentials = newValue} - } - /// Returns true if `wifiAwareCredentials` has been explicitly set. - var hasWifiAwareCredentials: Bool {return _storage._wifiAwareCredentials != nil} - /// Clears the value of `wifiAwareCredentials`. Subsequent reads from it will return its default value. - mutating func clearWifiAwareCredentials() {_uniqueStorage()._wifiAwareCredentials = nil} - - var wifiDirectCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials { - get {return _storage._wifiDirectCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials()} - set {_uniqueStorage()._wifiDirectCredentials = newValue} - } - /// Returns true if `wifiDirectCredentials` has been explicitly set. - var hasWifiDirectCredentials: Bool {return _storage._wifiDirectCredentials != nil} - /// Clears the value of `wifiDirectCredentials`. Subsequent reads from it will return its default value. - mutating func clearWifiDirectCredentials() {_uniqueStorage()._wifiDirectCredentials = nil} - - var webRtcCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials { - get {return _storage._webRtcCredentials ?? Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials()} - set {_uniqueStorage()._webRtcCredentials = newValue} - } - /// Returns true if `webRtcCredentials` has been explicitly set. - var hasWebRtcCredentials: Bool {return _storage._webRtcCredentials != nil} - /// Clears the value of `webRtcCredentials`. Subsequent reads from it will return its default value. - mutating func clearWebRtcCredentials() {_uniqueStorage()._webRtcCredentials = nil} - - /// Disable Encryption for this upgrade medium to improve throughput. - var supportsDisablingEncryption: Bool { - get {return _storage._supportsDisablingEncryption ?? false} - set {_uniqueStorage()._supportsDisablingEncryption = newValue} - } - /// Returns true if `supportsDisablingEncryption` has been explicitly set. - var hasSupportsDisablingEncryption: Bool {return _storage._supportsDisablingEncryption != nil} - /// Clears the value of `supportsDisablingEncryption`. Subsequent reads from it will return its default value. - mutating func clearSupportsDisablingEncryption() {_uniqueStorage()._supportsDisablingEncryption = nil} - - /// An ack will be sent after the CLIENT_INTRODUCTION frame. - var supportsClientIntroductionAck: Bool { - get {return _storage._supportsClientIntroductionAck ?? false} - set {_uniqueStorage()._supportsClientIntroductionAck = newValue} - } - /// Returns true if `supportsClientIntroductionAck` has been explicitly set. - var hasSupportsClientIntroductionAck: Bool {return _storage._supportsClientIntroductionAck != nil} - /// Clears the value of `supportsClientIntroductionAck`. Subsequent reads from it will return its default value. - mutating func clearSupportsClientIntroductionAck() {_uniqueStorage()._supportsClientIntroductionAck = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - /// Should always match cs/symbol:location.nearby.proto.connections.Medium - enum Medium: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownMedium // = 0 - case mdns // = 1 - case bluetooth // = 2 - case wifiHotspot // = 3 - case ble // = 4 - case wifiLan // = 5 - case wifiAware // = 6 - case nfc // = 7 - case wifiDirect // = 8 - case webRtc // = 9 - - /// 10 is reserved. - case usb // = 11 - - init() { - self = .unknownMedium - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownMedium - case 1: self = .mdns - case 2: self = .bluetooth - case 3: self = .wifiHotspot - case 4: self = .ble - case 5: self = .wifiLan - case 6: self = .wifiAware - case 7: self = .nfc - case 8: self = .wifiDirect - case 9: self = .webRtc - case 11: self = .usb - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownMedium: return 0 - case .mdns: return 1 - case .bluetooth: return 2 - case .wifiHotspot: return 3 - case .ble: return 4 - case .wifiLan: return 5 - case .wifiAware: return 6 - case .nfc: return 7 - case .wifiDirect: return 8 - case .webRtc: return 9 - case .usb: return 11 - } - } - - } - - /// Accompanies Medium.WIFI_HOTSPOT. - struct WifiHotspotCredentials { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var ssid: String { - get {return _ssid ?? String()} - set {_ssid = newValue} - } - /// Returns true if `ssid` has been explicitly set. - var hasSsid: Bool {return self._ssid != nil} - /// Clears the value of `ssid`. Subsequent reads from it will return its default value. - mutating func clearSsid() {self._ssid = nil} - - var password: String { - get {return _password ?? String()} - set {_password = newValue} - } - /// Returns true if `password` has been explicitly set. - var hasPassword: Bool {return self._password != nil} - /// Clears the value of `password`. Subsequent reads from it will return its default value. - mutating func clearPassword() {self._password = nil} - - var port: Int32 { - get {return _port ?? 0} - set {_port = newValue} - } - /// Returns true if `port` has been explicitly set. - var hasPort: Bool {return self._port != nil} - /// Clears the value of `port`. Subsequent reads from it will return its default value. - mutating func clearPort() {self._port = nil} - - var gateway: String { - get {return _gateway ?? "0.0.0.0"} - set {_gateway = newValue} - } - /// Returns true if `gateway` has been explicitly set. - var hasGateway: Bool {return self._gateway != nil} - /// Clears the value of `gateway`. Subsequent reads from it will return its default value. - mutating func clearGateway() {self._gateway = nil} - - /// This field can be a band or frequency - var frequency: Int32 { - get {return _frequency ?? -1} - set {_frequency = newValue} - } - /// Returns true if `frequency` has been explicitly set. - var hasFrequency: Bool {return self._frequency != nil} - /// Clears the value of `frequency`. Subsequent reads from it will return its default value. - mutating func clearFrequency() {self._frequency = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _ssid: String? = nil - fileprivate var _password: String? = nil - fileprivate var _port: Int32? = nil - fileprivate var _gateway: String? = nil - fileprivate var _frequency: Int32? = nil - } - - /// Accompanies Medium.WIFI_LAN. - struct WifiLanSocket { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var ipAddress: Data { - get {return _ipAddress ?? Data()} - set {_ipAddress = newValue} - } - /// Returns true if `ipAddress` has been explicitly set. - var hasIpAddress: Bool {return self._ipAddress != nil} - /// Clears the value of `ipAddress`. Subsequent reads from it will return its default value. - mutating func clearIpAddress() {self._ipAddress = nil} - - var wifiPort: Int32 { - get {return _wifiPort ?? 0} - set {_wifiPort = newValue} - } - /// Returns true if `wifiPort` has been explicitly set. - var hasWifiPort: Bool {return self._wifiPort != nil} - /// Clears the value of `wifiPort`. Subsequent reads from it will return its default value. - mutating func clearWifiPort() {self._wifiPort = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _ipAddress: Data? = nil - fileprivate var _wifiPort: Int32? = nil - } - - /// Accompanies Medium.BLUETOOTH. - struct BluetoothCredentials { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var serviceName: String { - get {return _serviceName ?? String()} - set {_serviceName = newValue} - } - /// Returns true if `serviceName` has been explicitly set. - var hasServiceName: Bool {return self._serviceName != nil} - /// Clears the value of `serviceName`. Subsequent reads from it will return its default value. - mutating func clearServiceName() {self._serviceName = nil} - - var macAddress: String { - get {return _macAddress ?? String()} - set {_macAddress = newValue} - } - /// Returns true if `macAddress` has been explicitly set. - var hasMacAddress: Bool {return self._macAddress != nil} - /// Clears the value of `macAddress`. Subsequent reads from it will return its default value. - mutating func clearMacAddress() {self._macAddress = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _serviceName: String? = nil - fileprivate var _macAddress: String? = nil - } - - /// Accompanies Medium.WIFI_AWARE. - struct WifiAwareCredentials { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var serviceID: String { - get {return _serviceID ?? String()} - set {_serviceID = newValue} - } - /// Returns true if `serviceID` has been explicitly set. - var hasServiceID: Bool {return self._serviceID != nil} - /// Clears the value of `serviceID`. Subsequent reads from it will return its default value. - mutating func clearServiceID() {self._serviceID = nil} - - var serviceInfo: Data { - get {return _serviceInfo ?? Data()} - set {_serviceInfo = newValue} - } - /// Returns true if `serviceInfo` has been explicitly set. - var hasServiceInfo: Bool {return self._serviceInfo != nil} - /// Clears the value of `serviceInfo`. Subsequent reads from it will return its default value. - mutating func clearServiceInfo() {self._serviceInfo = nil} - - var password: String { - get {return _password ?? String()} - set {_password = newValue} - } - /// Returns true if `password` has been explicitly set. - var hasPassword: Bool {return self._password != nil} - /// Clears the value of `password`. Subsequent reads from it will return its default value. - mutating func clearPassword() {self._password = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _serviceID: String? = nil - fileprivate var _serviceInfo: Data? = nil - fileprivate var _password: String? = nil - } - - /// Accompanies Medium.WIFI_DIRECT. - struct WifiDirectCredentials { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var ssid: String { - get {return _ssid ?? String()} - set {_ssid = newValue} - } - /// Returns true if `ssid` has been explicitly set. - var hasSsid: Bool {return self._ssid != nil} - /// Clears the value of `ssid`. Subsequent reads from it will return its default value. - mutating func clearSsid() {self._ssid = nil} - - var password: String { - get {return _password ?? String()} - set {_password = newValue} - } - /// Returns true if `password` has been explicitly set. - var hasPassword: Bool {return self._password != nil} - /// Clears the value of `password`. Subsequent reads from it will return its default value. - mutating func clearPassword() {self._password = nil} - - var port: Int32 { - get {return _port ?? 0} - set {_port = newValue} - } - /// Returns true if `port` has been explicitly set. - var hasPort: Bool {return self._port != nil} - /// Clears the value of `port`. Subsequent reads from it will return its default value. - mutating func clearPort() {self._port = nil} - - var frequency: Int32 { - get {return _frequency ?? 0} - set {_frequency = newValue} - } - /// Returns true if `frequency` has been explicitly set. - var hasFrequency: Bool {return self._frequency != nil} - /// Clears the value of `frequency`. Subsequent reads from it will return its default value. - mutating func clearFrequency() {self._frequency = nil} - - var gateway: String { - get {return _gateway ?? "0.0.0.0"} - set {_gateway = newValue} - } - /// Returns true if `gateway` has been explicitly set. - var hasGateway: Bool {return self._gateway != nil} - /// Clears the value of `gateway`. Subsequent reads from it will return its default value. - mutating func clearGateway() {self._gateway = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _ssid: String? = nil - fileprivate var _password: String? = nil - fileprivate var _port: Int32? = nil - fileprivate var _frequency: Int32? = nil - fileprivate var _gateway: String? = nil - } - - /// Accompanies Medium.WEB_RTC - struct WebRtcCredentials { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var peerID: String { - get {return _peerID ?? String()} - set {_peerID = newValue} - } - /// Returns true if `peerID` has been explicitly set. - var hasPeerID: Bool {return self._peerID != nil} - /// Clears the value of `peerID`. Subsequent reads from it will return its default value. - mutating func clearPeerID() {self._peerID = nil} - - var locationHint: Location_Nearby_Connections_LocationHint { - get {return _locationHint ?? Location_Nearby_Connections_LocationHint()} - set {_locationHint = newValue} - } - /// Returns true if `locationHint` has been explicitly set. - var hasLocationHint: Bool {return self._locationHint != nil} - /// Clears the value of `locationHint`. Subsequent reads from it will return its default value. - mutating func clearLocationHint() {self._locationHint = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _peerID: String? = nil - fileprivate var _locationHint: Location_Nearby_Connections_LocationHint? = nil - } - - init() {} - - fileprivate var _storage = _StorageClass.defaultInstance - } - - /// Accompanies CLIENT_INTRODUCTION events. - struct ClientIntroduction { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var endpointID: String { - get {return _endpointID ?? String()} - set {_endpointID = newValue} - } - /// Returns true if `endpointID` has been explicitly set. - var hasEndpointID: Bool {return self._endpointID != nil} - /// Clears the value of `endpointID`. Subsequent reads from it will return its default value. - mutating func clearEndpointID() {self._endpointID = nil} - - var supportsDisablingEncryption: Bool { - get {return _supportsDisablingEncryption ?? false} - set {_supportsDisablingEncryption = newValue} - } - /// Returns true if `supportsDisablingEncryption` has been explicitly set. - var hasSupportsDisablingEncryption: Bool {return self._supportsDisablingEncryption != nil} - /// Clears the value of `supportsDisablingEncryption`. Subsequent reads from it will return its default value. - mutating func clearSupportsDisablingEncryption() {self._supportsDisablingEncryption = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _endpointID: String? = nil - fileprivate var _supportsDisablingEncryption: Bool? = nil - } - - /// Accompanies CLIENT_INTRODUCTION_ACK events. - struct ClientIntroductionAck { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - } - - init() {} - - fileprivate var _eventType: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType? = nil - fileprivate var _upgradePathInfo: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo? = nil - fileprivate var _clientIntroduction: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction? = nil - fileprivate var _clientIntroductionAck: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck? = nil -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType: CaseIterable { - // Support synthesized by the compiler. -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Location_Nearby_Connections_KeepAliveFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// And ack will be sent after receiving KEEP_ALIVE frame. - var ack: Bool { - get {return _ack ?? false} - set {_ack = newValue} - } - /// Returns true if `ack` has been explicitly set. - var hasAck: Bool {return self._ack != nil} - /// Clears the value of `ack`. Subsequent reads from it will return its default value. - mutating func clearAck() {self._ack = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _ack: Bool? = nil -} - -/// Informs the remote side to immediately severe the socket connection. -/// Used in bandwidth upgrades to get around a race condition, but may be used -/// in other situations to trigger a faster disconnection event than waiting for -/// socket closed on the remote side. -struct Location_Nearby_Connections_DisconnectionFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Apply safe-to-disconnect protocol if true. - var requestSafeToDisconnect: Bool { - get {return _requestSafeToDisconnect ?? false} - set {_requestSafeToDisconnect = newValue} - } - /// Returns true if `requestSafeToDisconnect` has been explicitly set. - var hasRequestSafeToDisconnect: Bool {return self._requestSafeToDisconnect != nil} - /// Clears the value of `requestSafeToDisconnect`. Subsequent reads from it will return its default value. - mutating func clearRequestSafeToDisconnect() {self._requestSafeToDisconnect = nil} - - /// Ack of receiving Disconnection frame will be sent to the sender - /// frame. - var ackSafeToDisconnect: Bool { - get {return _ackSafeToDisconnect ?? false} - set {_ackSafeToDisconnect = newValue} - } - /// Returns true if `ackSafeToDisconnect` has been explicitly set. - var hasAckSafeToDisconnect: Bool {return self._ackSafeToDisconnect != nil} - /// Clears the value of `ackSafeToDisconnect`. Subsequent reads from it will return its default value. - mutating func clearAckSafeToDisconnect() {self._ackSafeToDisconnect = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _requestSafeToDisconnect: Bool? = nil - fileprivate var _ackSafeToDisconnect: Bool? = nil -} - -/// A paired key encryption packet sent between devices, contains signed data. -struct Location_Nearby_Connections_PairedKeyEncryptionFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The encrypted data (raw authentication token for the established - /// connection) in byte array format. - var signedData: Data { - get {return _signedData ?? Data()} - set {_signedData = newValue} - } - /// Returns true if `signedData` has been explicitly set. - var hasSignedData: Bool {return self._signedData != nil} - /// Clears the value of `signedData`. Subsequent reads from it will return its default value. - mutating func clearSignedData() {self._signedData = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _signedData: Data? = nil -} - -struct Location_Nearby_Connections_MediumMetadata { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// True if local device supports 5GHz. - var supports5Ghz: Bool { - get {return _supports5Ghz ?? false} - set {_supports5Ghz = newValue} - } - /// Returns true if `supports5Ghz` has been explicitly set. - var hasSupports5Ghz: Bool {return self._supports5Ghz != nil} - /// Clears the value of `supports5Ghz`. Subsequent reads from it will return its default value. - mutating func clearSupports5Ghz() {self._supports5Ghz = nil} - - /// WiFi LAN BSSID, in the form of a six-byte MAC address: XX:XX:XX:XX:XX:XX - var bssid: String { - get {return _bssid ?? String()} - set {_bssid = newValue} - } - /// Returns true if `bssid` has been explicitly set. - var hasBssid: Bool {return self._bssid != nil} - /// Clears the value of `bssid`. Subsequent reads from it will return its default value. - mutating func clearBssid() {self._bssid = nil} - - /// IP address, in network byte order: the highest order byte of the address is - /// in byte[0]. - var ipAddress: Data { - get {return _ipAddress ?? Data()} - set {_ipAddress = newValue} - } - /// Returns true if `ipAddress` has been explicitly set. - var hasIpAddress: Bool {return self._ipAddress != nil} - /// Clears the value of `ipAddress`. Subsequent reads from it will return its default value. - mutating func clearIpAddress() {self._ipAddress = nil} - - /// True if local device supports 6GHz. - var supports6Ghz: Bool { - get {return _supports6Ghz ?? false} - set {_supports6Ghz = newValue} - } - /// Returns true if `supports6Ghz` has been explicitly set. - var hasSupports6Ghz: Bool {return self._supports6Ghz != nil} - /// Clears the value of `supports6Ghz`. Subsequent reads from it will return its default value. - mutating func clearSupports6Ghz() {self._supports6Ghz = nil} - - /// True if local device has mobile radio. - var mobileRadio: Bool { - get {return _mobileRadio ?? false} - set {_mobileRadio = newValue} - } - /// Returns true if `mobileRadio` has been explicitly set. - var hasMobileRadio: Bool {return self._mobileRadio != nil} - /// Clears the value of `mobileRadio`. Subsequent reads from it will return its default value. - mutating func clearMobileRadio() {self._mobileRadio = nil} - - /// The frequency of the WiFi LAN AP(in MHz). Or -1 is not associated with an - /// AP over WiFi, -2 represents the active network uses an Ethernet transport. - var apFrequency: Int32 { - get {return _apFrequency ?? -1} - set {_apFrequency = newValue} - } - /// Returns true if `apFrequency` has been explicitly set. - var hasApFrequency: Bool {return self._apFrequency != nil} - /// Clears the value of `apFrequency`. Subsequent reads from it will return its default value. - mutating func clearApFrequency() {self._apFrequency = nil} - - /// Available channels on the local device. - var availableChannels: Location_Nearby_Connections_AvailableChannels { - get {return _availableChannels ?? Location_Nearby_Connections_AvailableChannels()} - set {_availableChannels = newValue} - } - /// Returns true if `availableChannels` has been explicitly set. - var hasAvailableChannels: Bool {return self._availableChannels != nil} - /// Clears the value of `availableChannels`. Subsequent reads from it will return its default value. - mutating func clearAvailableChannels() {self._availableChannels = nil} - - /// Usable WiFi Direct client channels on the local device. - var wifiDirectCliUsableChannels: Location_Nearby_Connections_WifiDirectCliUsableChannels { - get {return _wifiDirectCliUsableChannels ?? Location_Nearby_Connections_WifiDirectCliUsableChannels()} - set {_wifiDirectCliUsableChannels = newValue} - } - /// Returns true if `wifiDirectCliUsableChannels` has been explicitly set. - var hasWifiDirectCliUsableChannels: Bool {return self._wifiDirectCliUsableChannels != nil} - /// Clears the value of `wifiDirectCliUsableChannels`. Subsequent reads from it will return its default value. - mutating func clearWifiDirectCliUsableChannels() {self._wifiDirectCliUsableChannels = nil} - - /// Usable WiFi LAN channels on the local device. - var wifiLanUsableChannels: Location_Nearby_Connections_WifiLanUsableChannels { - get {return _wifiLanUsableChannels ?? Location_Nearby_Connections_WifiLanUsableChannels()} - set {_wifiLanUsableChannels = newValue} - } - /// Returns true if `wifiLanUsableChannels` has been explicitly set. - var hasWifiLanUsableChannels: Bool {return self._wifiLanUsableChannels != nil} - /// Clears the value of `wifiLanUsableChannels`. Subsequent reads from it will return its default value. - mutating func clearWifiLanUsableChannels() {self._wifiLanUsableChannels = nil} - - /// Usable WiFi Aware channels on the local device. - var wifiAwareUsableChannels: Location_Nearby_Connections_WifiAwareUsableChannels { - get {return _wifiAwareUsableChannels ?? Location_Nearby_Connections_WifiAwareUsableChannels()} - set {_wifiAwareUsableChannels = newValue} - } - /// Returns true if `wifiAwareUsableChannels` has been explicitly set. - var hasWifiAwareUsableChannels: Bool {return self._wifiAwareUsableChannels != nil} - /// Clears the value of `wifiAwareUsableChannels`. Subsequent reads from it will return its default value. - mutating func clearWifiAwareUsableChannels() {self._wifiAwareUsableChannels = nil} - - /// Usable WiFi Hotspot STA channels on the local device. - var wifiHotspotStaUsableChannels: Location_Nearby_Connections_WifiHotspotStaUsableChannels { - get {return _wifiHotspotStaUsableChannels ?? Location_Nearby_Connections_WifiHotspotStaUsableChannels()} - set {_wifiHotspotStaUsableChannels = newValue} - } - /// Returns true if `wifiHotspotStaUsableChannels` has been explicitly set. - var hasWifiHotspotStaUsableChannels: Bool {return self._wifiHotspotStaUsableChannels != nil} - /// Clears the value of `wifiHotspotStaUsableChannels`. Subsequent reads from it will return its default value. - mutating func clearWifiHotspotStaUsableChannels() {self._wifiHotspotStaUsableChannels = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _supports5Ghz: Bool? = nil - fileprivate var _bssid: String? = nil - fileprivate var _ipAddress: Data? = nil - fileprivate var _supports6Ghz: Bool? = nil - fileprivate var _mobileRadio: Bool? = nil - fileprivate var _apFrequency: Int32? = nil - fileprivate var _availableChannels: Location_Nearby_Connections_AvailableChannels? = nil - fileprivate var _wifiDirectCliUsableChannels: Location_Nearby_Connections_WifiDirectCliUsableChannels? = nil - fileprivate var _wifiLanUsableChannels: Location_Nearby_Connections_WifiLanUsableChannels? = nil - fileprivate var _wifiAwareUsableChannels: Location_Nearby_Connections_WifiAwareUsableChannels? = nil - fileprivate var _wifiHotspotStaUsableChannels: Location_Nearby_Connections_WifiHotspotStaUsableChannels? = nil -} - -/// Available channels on the local device. -struct Location_Nearby_Connections_AvailableChannels { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var channels: [Int32] = [] - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// Usable WiFi Direct client channels on the local device. -struct Location_Nearby_Connections_WifiDirectCliUsableChannels { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var channels: [Int32] = [] - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// Usable WiFi LAN channels on the local device. -struct Location_Nearby_Connections_WifiLanUsableChannels { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var channels: [Int32] = [] - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// Usable WiFi Aware channels on the local device. -struct Location_Nearby_Connections_WifiAwareUsableChannels { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var channels: [Int32] = [] - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// Usable WiFi Hotspot STA channels on the local device. -struct Location_Nearby_Connections_WifiHotspotStaUsableChannels { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var channels: [Int32] = [] - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// LocationHint is used to specify a location as well as format. -struct Location_Nearby_Connections_LocationHint { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Location is the location, provided in the format specified by format. - var location: String { - get {return _location ?? String()} - set {_location = newValue} - } - /// Returns true if `location` has been explicitly set. - var hasLocation: Bool {return self._location != nil} - /// Clears the value of `location`. Subsequent reads from it will return its default value. - mutating func clearLocation() {self._location = nil} - - /// the format of location. - var format: Location_Nearby_Connections_LocationStandard.Format { - get {return _format ?? .unknown} - set {_format = newValue} - } - /// Returns true if `format` has been explicitly set. - var hasFormat: Bool {return self._format != nil} - /// Clears the value of `format`. Subsequent reads from it will return its default value. - mutating func clearFormat() {self._format = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _location: String? = nil - fileprivate var _format: Location_Nearby_Connections_LocationStandard.Format? = nil -} - -struct Location_Nearby_Connections_LocationStandard { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum Format: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknown // = 0 - - /// E164 country codes: - /// https://en.wikipedia.org/wiki/List_of_country_calling_codes - /// e.g. +1 for USA - case e164Calling // = 1 - - /// ISO 3166-1 alpha-2 country codes: - /// https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - case iso31661Alpha2 // = 2 - - init() { - self = .unknown - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknown - case 1: self = .e164Calling - case 2: self = .iso31661Alpha2 - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknown: return 0 - case .e164Calling: return 1 - case .iso31661Alpha2: return 2 - } - } - - } - - init() {} -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_LocationStandard.Format: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// Device capability for OS information. -struct Location_Nearby_Connections_OsInfo { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var type: Location_Nearby_Connections_OsInfo.OsType { - get {return _type ?? .unknownOsType} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum OsType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownOsType // = 0 - case android // = 1 - case chromeOs // = 2 - case windows // = 3 - case apple // = 4 - - /// g3 test environment - case linux // = 100 - - init() { - self = .unknownOsType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownOsType - case 1: self = .android - case 2: self = .chromeOs - case 3: self = .windows - case 4: self = .apple - case 100: self = .linux - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownOsType: return 0 - case .android: return 1 - case .chromeOs: return 2 - case .windows: return 3 - case .apple: return 4 - case .linux: return 100 - } - } - - } - - init() {} - - fileprivate var _type: Location_Nearby_Connections_OsInfo.OsType? = nil -} - -#if swift(>=4.2) - -extension Location_Nearby_Connections_OsInfo.OsType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -#if swift(>=5.5) && canImport(_Concurrency) -extension Location_Nearby_Connections_OfflineFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_OfflineFrame.Version: @unchecked Sendable {} -extension Location_Nearby_Connections_V1Frame: @unchecked Sendable {} -extension Location_Nearby_Connections_V1Frame.FrameType: @unchecked Sendable {} -extension Location_Nearby_Connections_ConnectionRequestFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_ConnectionRequestFrame.Medium: @unchecked Sendable {} -extension Location_Nearby_Connections_ConnectionResponseFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame.PacketType: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk.Flags: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage: @unchecked Sendable {} -extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction: @unchecked Sendable {} -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck: @unchecked Sendable {} -extension Location_Nearby_Connections_KeepAliveFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_DisconnectionFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_PairedKeyEncryptionFrame: @unchecked Sendable {} -extension Location_Nearby_Connections_MediumMetadata: @unchecked Sendable {} -extension Location_Nearby_Connections_AvailableChannels: @unchecked Sendable {} -extension Location_Nearby_Connections_WifiDirectCliUsableChannels: @unchecked Sendable {} -extension Location_Nearby_Connections_WifiLanUsableChannels: @unchecked Sendable {} -extension Location_Nearby_Connections_WifiAwareUsableChannels: @unchecked Sendable {} -extension Location_Nearby_Connections_WifiHotspotStaUsableChannels: @unchecked Sendable {} -extension Location_Nearby_Connections_LocationHint: @unchecked Sendable {} -extension Location_Nearby_Connections_LocationStandard: @unchecked Sendable {} -extension Location_Nearby_Connections_LocationStandard.Format: @unchecked Sendable {} -extension Location_Nearby_Connections_OsInfo: @unchecked Sendable {} -extension Location_Nearby_Connections_OsInfo.OsType: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "location.nearby.connections" - -extension Location_Nearby_Connections_OfflineFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".OfflineFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "version"), - 2: .same(proto: "v1"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._version) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._v1) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._version { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._v1 { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_OfflineFrame, rhs: Location_Nearby_Connections_OfflineFrame) -> Bool { - if lhs._version != rhs._version {return false} - if lhs._v1 != rhs._v1 {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_OfflineFrame.Version: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_VERSION"), - 1: .same(proto: "V1"), - ] -} - -extension Location_Nearby_Connections_V1Frame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".V1Frame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .standard(proto: "connection_request"), - 3: .standard(proto: "connection_response"), - 4: .standard(proto: "payload_transfer"), - 5: .standard(proto: "bandwidth_upgrade_negotiation"), - 6: .standard(proto: "keep_alive"), - 7: .same(proto: "disconnection"), - 8: .standard(proto: "paired_key_encryption"), - ] - - fileprivate class _StorageClass { - var _type: Location_Nearby_Connections_V1Frame.FrameType? = nil - var _connectionRequest: Location_Nearby_Connections_ConnectionRequestFrame? = nil - var _connectionResponse: Location_Nearby_Connections_ConnectionResponseFrame? = nil - var _payloadTransfer: Location_Nearby_Connections_PayloadTransferFrame? = nil - var _bandwidthUpgradeNegotiation: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame? = nil - var _keepAlive: Location_Nearby_Connections_KeepAliveFrame? = nil - var _disconnection: Location_Nearby_Connections_DisconnectionFrame? = nil - var _pairedKeyEncryption: Location_Nearby_Connections_PairedKeyEncryptionFrame? = nil - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _type = source._type - _connectionRequest = source._connectionRequest - _connectionResponse = source._connectionResponse - _payloadTransfer = source._payloadTransfer - _bandwidthUpgradeNegotiation = source._bandwidthUpgradeNegotiation - _keepAlive = source._keepAlive - _disconnection = source._disconnection - _pairedKeyEncryption = source._pairedKeyEncryption - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &_storage._type) }() - case 2: try { try decoder.decodeSingularMessageField(value: &_storage._connectionRequest) }() - case 3: try { try decoder.decodeSingularMessageField(value: &_storage._connectionResponse) }() - case 4: try { try decoder.decodeSingularMessageField(value: &_storage._payloadTransfer) }() - case 5: try { try decoder.decodeSingularMessageField(value: &_storage._bandwidthUpgradeNegotiation) }() - case 6: try { try decoder.decodeSingularMessageField(value: &_storage._keepAlive) }() - case 7: try { try decoder.decodeSingularMessageField(value: &_storage._disconnection) }() - case 8: try { try decoder.decodeSingularMessageField(value: &_storage._pairedKeyEncryption) }() - default: break - } - } - } - } - - func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._connectionRequest { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = _storage._connectionResponse { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() - try { if let v = _storage._payloadTransfer { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } }() - try { if let v = _storage._bandwidthUpgradeNegotiation { - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - } }() - try { if let v = _storage._keepAlive { - try visitor.visitSingularMessageField(value: v, fieldNumber: 6) - } }() - try { if let v = _storage._disconnection { - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - } }() - try { if let v = _storage._pairedKeyEncryption { - try visitor.visitSingularMessageField(value: v, fieldNumber: 8) - } }() - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_V1Frame, rhs: Location_Nearby_Connections_V1Frame) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._type != rhs_storage._type {return false} - if _storage._connectionRequest != rhs_storage._connectionRequest {return false} - if _storage._connectionResponse != rhs_storage._connectionResponse {return false} - if _storage._payloadTransfer != rhs_storage._payloadTransfer {return false} - if _storage._bandwidthUpgradeNegotiation != rhs_storage._bandwidthUpgradeNegotiation {return false} - if _storage._keepAlive != rhs_storage._keepAlive {return false} - if _storage._disconnection != rhs_storage._disconnection {return false} - if _storage._pairedKeyEncryption != rhs_storage._pairedKeyEncryption {return false} - return true - } - if !storagesAreEqual {return false} - } - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_V1Frame.FrameType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_FRAME_TYPE"), - 1: .same(proto: "CONNECTION_REQUEST"), - 2: .same(proto: "CONNECTION_RESPONSE"), - 3: .same(proto: "PAYLOAD_TRANSFER"), - 4: .same(proto: "BANDWIDTH_UPGRADE_NEGOTIATION"), - 5: .same(proto: "KEEP_ALIVE"), - 6: .same(proto: "DISCONNECTION"), - 7: .same(proto: "PAIRED_KEY_ENCRYPTION"), - ] -} - -extension Location_Nearby_Connections_ConnectionRequestFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".ConnectionRequestFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "endpoint_id"), - 2: .standard(proto: "endpoint_name"), - 3: .standard(proto: "handshake_data"), - 4: .same(proto: "nonce"), - 5: .same(proto: "mediums"), - 6: .standard(proto: "endpoint_info"), - 7: .standard(proto: "medium_metadata"), - 8: .standard(proto: "keep_alive_interval_millis"), - 9: .standard(proto: "keep_alive_timeout_millis"), - 10: .standard(proto: "device_type"), - 11: .standard(proto: "device_info"), - ] - - fileprivate class _StorageClass { - var _endpointID: String? = nil - var _endpointName: String? = nil - var _handshakeData: Data? = nil - var _nonce: Int32? = nil - var _mediums: [Location_Nearby_Connections_ConnectionRequestFrame.Medium] = [] - var _endpointInfo: Data? = nil - var _mediumMetadata: Location_Nearby_Connections_MediumMetadata? = nil - var _keepAliveIntervalMillis: Int32? = nil - var _keepAliveTimeoutMillis: Int32? = nil - var _deviceType: Int32? = nil - var _deviceInfo: Data? = nil - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _endpointID = source._endpointID - _endpointName = source._endpointName - _handshakeData = source._handshakeData - _nonce = source._nonce - _mediums = source._mediums - _endpointInfo = source._endpointInfo - _mediumMetadata = source._mediumMetadata - _keepAliveIntervalMillis = source._keepAliveIntervalMillis - _keepAliveTimeoutMillis = source._keepAliveTimeoutMillis - _deviceType = source._deviceType - _deviceInfo = source._deviceInfo - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &_storage._endpointID) }() - case 2: try { try decoder.decodeSingularStringField(value: &_storage._endpointName) }() - case 3: try { try decoder.decodeSingularBytesField(value: &_storage._handshakeData) }() - case 4: try { try decoder.decodeSingularInt32Field(value: &_storage._nonce) }() - case 5: try { try decoder.decodeRepeatedEnumField(value: &_storage._mediums) }() - case 6: try { try decoder.decodeSingularBytesField(value: &_storage._endpointInfo) }() - case 7: try { try decoder.decodeSingularMessageField(value: &_storage._mediumMetadata) }() - case 8: try { try decoder.decodeSingularInt32Field(value: &_storage._keepAliveIntervalMillis) }() - case 9: try { try decoder.decodeSingularInt32Field(value: &_storage._keepAliveTimeoutMillis) }() - case 10: try { try decoder.decodeSingularInt32Field(value: &_storage._deviceType) }() - case 11: try { try decoder.decodeSingularBytesField(value: &_storage._deviceInfo) }() - default: break - } - } - } - } - - func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._endpointID { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._endpointName { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try { if let v = _storage._handshakeData { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try { if let v = _storage._nonce { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 4) - } }() - if !_storage._mediums.isEmpty { - try visitor.visitRepeatedEnumField(value: _storage._mediums, fieldNumber: 5) - } - try { if let v = _storage._endpointInfo { - try visitor.visitSingularBytesField(value: v, fieldNumber: 6) - } }() - try { if let v = _storage._mediumMetadata { - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - } }() - try { if let v = _storage._keepAliveIntervalMillis { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 8) - } }() - try { if let v = _storage._keepAliveTimeoutMillis { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 9) - } }() - try { if let v = _storage._deviceType { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 10) - } }() - try { if let v = _storage._deviceInfo { - try visitor.visitSingularBytesField(value: v, fieldNumber: 11) - } }() - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_ConnectionRequestFrame, rhs: Location_Nearby_Connections_ConnectionRequestFrame) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._endpointID != rhs_storage._endpointID {return false} - if _storage._endpointName != rhs_storage._endpointName {return false} - if _storage._handshakeData != rhs_storage._handshakeData {return false} - if _storage._nonce != rhs_storage._nonce {return false} - if _storage._mediums != rhs_storage._mediums {return false} - if _storage._endpointInfo != rhs_storage._endpointInfo {return false} - if _storage._mediumMetadata != rhs_storage._mediumMetadata {return false} - if _storage._keepAliveIntervalMillis != rhs_storage._keepAliveIntervalMillis {return false} - if _storage._keepAliveTimeoutMillis != rhs_storage._keepAliveTimeoutMillis {return false} - if _storage._deviceType != rhs_storage._deviceType {return false} - if _storage._deviceInfo != rhs_storage._deviceInfo {return false} - return true - } - if !storagesAreEqual {return false} - } - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_ConnectionRequestFrame.Medium: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_MEDIUM"), - 1: .same(proto: "MDNS"), - 2: .same(proto: "BLUETOOTH"), - 3: .same(proto: "WIFI_HOTSPOT"), - 4: .same(proto: "BLE"), - 5: .same(proto: "WIFI_LAN"), - 6: .same(proto: "WIFI_AWARE"), - 7: .same(proto: "NFC"), - 8: .same(proto: "WIFI_DIRECT"), - 9: .same(proto: "WEB_RTC"), - 10: .same(proto: "BLE_L2CAP"), - 11: .same(proto: "USB"), - ] -} - -extension Location_Nearby_Connections_ConnectionResponseFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".ConnectionResponseFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "status"), - 2: .standard(proto: "handshake_data"), - 3: .same(proto: "response"), - 4: .standard(proto: "os_info"), - 5: .standard(proto: "multiplex_socket_bitmask"), - 6: .standard(proto: "nearby_connections_version"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularInt32Field(value: &self._status) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._handshakeData) }() - case 3: try { try decoder.decodeSingularEnumField(value: &self._response) }() - case 4: try { try decoder.decodeSingularMessageField(value: &self._osInfo) }() - case 5: try { try decoder.decodeSingularInt32Field(value: &self._multiplexSocketBitmask) }() - case 6: try { try decoder.decodeSingularInt32Field(value: &self._nearbyConnectionsVersion) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._status { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) - } }() - try { if let v = self._handshakeData { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try { if let v = self._response { - try visitor.visitSingularEnumField(value: v, fieldNumber: 3) - } }() - try { if let v = self._osInfo { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } }() - try { if let v = self._multiplexSocketBitmask { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 5) - } }() - try { if let v = self._nearbyConnectionsVersion { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_ConnectionResponseFrame, rhs: Location_Nearby_Connections_ConnectionResponseFrame) -> Bool { - if lhs._status != rhs._status {return false} - if lhs._handshakeData != rhs._handshakeData {return false} - if lhs._response != rhs._response {return false} - if lhs._osInfo != rhs._osInfo {return false} - if lhs._multiplexSocketBitmask != rhs._multiplexSocketBitmask {return false} - if lhs._nearbyConnectionsVersion != rhs._nearbyConnectionsVersion {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_ConnectionResponseFrame.ResponseStatus: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_RESPONSE_STATUS"), - 1: .same(proto: "ACCEPT"), - 2: .same(proto: "REJECT"), - ] -} - -extension Location_Nearby_Connections_PayloadTransferFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".PayloadTransferFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "packet_type"), - 2: .standard(proto: "payload_header"), - 3: .standard(proto: "payload_chunk"), - 4: .standard(proto: "control_message"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._packetType) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._payloadHeader) }() - case 3: try { try decoder.decodeSingularMessageField(value: &self._payloadChunk) }() - case 4: try { try decoder.decodeSingularMessageField(value: &self._controlMessage) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._packetType { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._payloadHeader { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._payloadChunk { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() - try { if let v = self._controlMessage { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame, rhs: Location_Nearby_Connections_PayloadTransferFrame) -> Bool { - if lhs._packetType != rhs._packetType {return false} - if lhs._payloadHeader != rhs._payloadHeader {return false} - if lhs._payloadChunk != rhs._payloadChunk {return false} - if lhs._controlMessage != rhs._controlMessage {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_PayloadTransferFrame.PacketType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_PACKET_TYPE"), - 1: .same(proto: "DATA"), - 2: .same(proto: "CONTROL"), - ] -} - -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_PayloadTransferFrame.protoMessageName + ".PayloadHeader" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "id"), - 2: .same(proto: "type"), - 3: .standard(proto: "total_size"), - 4: .standard(proto: "is_sensitive"), - 5: .standard(proto: "file_name"), - 6: .standard(proto: "parent_folder"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularInt64Field(value: &self._id) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self._type) }() - case 3: try { try decoder.decodeSingularInt64Field(value: &self._totalSize) }() - case 4: try { try decoder.decodeSingularBoolField(value: &self._isSensitive) }() - case 5: try { try decoder.decodeSingularStringField(value: &self._fileName) }() - case 6: try { try decoder.decodeSingularStringField(value: &self._parentFolder) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._id { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 1) - } }() - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 2) - } }() - try { if let v = self._totalSize { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 3) - } }() - try { if let v = self._isSensitive { - try visitor.visitSingularBoolField(value: v, fieldNumber: 4) - } }() - try { if let v = self._fileName { - try visitor.visitSingularStringField(value: v, fieldNumber: 5) - } }() - try { if let v = self._parentFolder { - try visitor.visitSingularStringField(value: v, fieldNumber: 6) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader, rhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader) -> Bool { - if lhs._id != rhs._id {return false} - if lhs._type != rhs._type {return false} - if lhs._totalSize != rhs._totalSize {return false} - if lhs._isSensitive != rhs._isSensitive {return false} - if lhs._fileName != rhs._fileName {return false} - if lhs._parentFolder != rhs._parentFolder {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadHeader.PayloadType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_PAYLOAD_TYPE"), - 1: .same(proto: "BYTES"), - 2: .same(proto: "FILE"), - 3: .same(proto: "STREAM"), - ] -} - -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_PayloadTransferFrame.protoMessageName + ".PayloadChunk" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "flags"), - 2: .same(proto: "offset"), - 3: .same(proto: "body"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularInt32Field(value: &self._flags) }() - case 2: try { try decoder.decodeSingularInt64Field(value: &self._offset) }() - case 3: try { try decoder.decodeSingularBytesField(value: &self._body) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._flags { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) - } }() - try { if let v = self._offset { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 2) - } }() - try { if let v = self._body { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk, rhs: Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk) -> Bool { - if lhs._flags != rhs._flags {return false} - if lhs._offset != rhs._offset {return false} - if lhs._body != rhs._body {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_PayloadTransferFrame.PayloadChunk.Flags: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "LAST_CHUNK"), - ] -} - -extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_PayloadTransferFrame.protoMessageName + ".ControlMessage" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "event"), - 2: .same(proto: "offset"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._event) }() - case 2: try { try decoder.decodeSingularInt64Field(value: &self._offset) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._event { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._offset { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage, rhs: Location_Nearby_Connections_PayloadTransferFrame.ControlMessage) -> Bool { - if lhs._event != rhs._event {return false} - if lhs._offset != rhs._offset {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_PayloadTransferFrame.ControlMessage.EventType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_EVENT_TYPE"), - 1: .same(proto: "PAYLOAD_ERROR"), - 2: .same(proto: "PAYLOAD_CANCELED"), - 3: .same(proto: "PAYLOAD_RECEIVED_ACK"), - ] -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".BandwidthUpgradeNegotiationFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "event_type"), - 2: .standard(proto: "upgrade_path_info"), - 3: .standard(proto: "client_introduction"), - 4: .standard(proto: "client_introduction_ack"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._eventType) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._upgradePathInfo) }() - case 3: try { try decoder.decodeSingularMessageField(value: &self._clientIntroduction) }() - case 4: try { try decoder.decodeSingularMessageField(value: &self._clientIntroductionAck) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._eventType { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._upgradePathInfo { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._clientIntroduction { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() - try { if let v = self._clientIntroductionAck { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame) -> Bool { - if lhs._eventType != rhs._eventType {return false} - if lhs._upgradePathInfo != rhs._upgradePathInfo {return false} - if lhs._clientIntroduction != rhs._clientIntroduction {return false} - if lhs._clientIntroductionAck != rhs._clientIntroductionAck {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.EventType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_EVENT_TYPE"), - 1: .same(proto: "UPGRADE_PATH_AVAILABLE"), - 2: .same(proto: "LAST_WRITE_TO_PRIOR_CHANNEL"), - 3: .same(proto: "SAFE_TO_CLOSE_PRIOR_CHANNEL"), - 4: .same(proto: "CLIENT_INTRODUCTION"), - 5: .same(proto: "UPGRADE_FAILURE"), - 6: .same(proto: "CLIENT_INTRODUCTION_ACK"), - ] -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.protoMessageName + ".UpgradePathInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "medium"), - 2: .standard(proto: "wifi_hotspot_credentials"), - 3: .standard(proto: "wifi_lan_socket"), - 4: .standard(proto: "bluetooth_credentials"), - 5: .standard(proto: "wifi_aware_credentials"), - 6: .standard(proto: "wifi_direct_credentials"), - 8: .standard(proto: "web_rtc_credentials"), - 7: .standard(proto: "supports_disabling_encryption"), - 9: .standard(proto: "supports_client_introduction_ack"), - ] - - fileprivate class _StorageClass { - var _medium: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium? = nil - var _wifiHotspotCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials? = nil - var _wifiLanSocket: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket? = nil - var _bluetoothCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials? = nil - var _wifiAwareCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials? = nil - var _wifiDirectCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials? = nil - var _webRtcCredentials: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials? = nil - var _supportsDisablingEncryption: Bool? = nil - var _supportsClientIntroductionAck: Bool? = nil - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _medium = source._medium - _wifiHotspotCredentials = source._wifiHotspotCredentials - _wifiLanSocket = source._wifiLanSocket - _bluetoothCredentials = source._bluetoothCredentials - _wifiAwareCredentials = source._wifiAwareCredentials - _wifiDirectCredentials = source._wifiDirectCredentials - _webRtcCredentials = source._webRtcCredentials - _supportsDisablingEncryption = source._supportsDisablingEncryption - _supportsClientIntroductionAck = source._supportsClientIntroductionAck - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &_storage._medium) }() - case 2: try { try decoder.decodeSingularMessageField(value: &_storage._wifiHotspotCredentials) }() - case 3: try { try decoder.decodeSingularMessageField(value: &_storage._wifiLanSocket) }() - case 4: try { try decoder.decodeSingularMessageField(value: &_storage._bluetoothCredentials) }() - case 5: try { try decoder.decodeSingularMessageField(value: &_storage._wifiAwareCredentials) }() - case 6: try { try decoder.decodeSingularMessageField(value: &_storage._wifiDirectCredentials) }() - case 7: try { try decoder.decodeSingularBoolField(value: &_storage._supportsDisablingEncryption) }() - case 8: try { try decoder.decodeSingularMessageField(value: &_storage._webRtcCredentials) }() - case 9: try { try decoder.decodeSingularBoolField(value: &_storage._supportsClientIntroductionAck) }() - default: break - } - } - } - } - - func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._medium { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._wifiHotspotCredentials { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = _storage._wifiLanSocket { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() - try { if let v = _storage._bluetoothCredentials { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } }() - try { if let v = _storage._wifiAwareCredentials { - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - } }() - try { if let v = _storage._wifiDirectCredentials { - try visitor.visitSingularMessageField(value: v, fieldNumber: 6) - } }() - try { if let v = _storage._supportsDisablingEncryption { - try visitor.visitSingularBoolField(value: v, fieldNumber: 7) - } }() - try { if let v = _storage._webRtcCredentials { - try visitor.visitSingularMessageField(value: v, fieldNumber: 8) - } }() - try { if let v = _storage._supportsClientIntroductionAck { - try visitor.visitSingularBoolField(value: v, fieldNumber: 9) - } }() - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._medium != rhs_storage._medium {return false} - if _storage._wifiHotspotCredentials != rhs_storage._wifiHotspotCredentials {return false} - if _storage._wifiLanSocket != rhs_storage._wifiLanSocket {return false} - if _storage._bluetoothCredentials != rhs_storage._bluetoothCredentials {return false} - if _storage._wifiAwareCredentials != rhs_storage._wifiAwareCredentials {return false} - if _storage._wifiDirectCredentials != rhs_storage._wifiDirectCredentials {return false} - if _storage._webRtcCredentials != rhs_storage._webRtcCredentials {return false} - if _storage._supportsDisablingEncryption != rhs_storage._supportsDisablingEncryption {return false} - if _storage._supportsClientIntroductionAck != rhs_storage._supportsClientIntroductionAck {return false} - return true - } - if !storagesAreEqual {return false} - } - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.Medium: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_MEDIUM"), - 1: .same(proto: "MDNS"), - 2: .same(proto: "BLUETOOTH"), - 3: .same(proto: "WIFI_HOTSPOT"), - 4: .same(proto: "BLE"), - 5: .same(proto: "WIFI_LAN"), - 6: .same(proto: "WIFI_AWARE"), - 7: .same(proto: "NFC"), - 8: .same(proto: "WIFI_DIRECT"), - 9: .same(proto: "WEB_RTC"), - 11: .same(proto: "USB"), - ] -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiHotspotCredentials" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "ssid"), - 2: .same(proto: "password"), - 3: .same(proto: "port"), - 4: .same(proto: "gateway"), - 5: .same(proto: "frequency"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._ssid) }() - case 2: try { try decoder.decodeSingularStringField(value: &self._password) }() - case 3: try { try decoder.decodeSingularInt32Field(value: &self._port) }() - case 4: try { try decoder.decodeSingularStringField(value: &self._gateway) }() - case 5: try { try decoder.decodeSingularInt32Field(value: &self._frequency) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._ssid { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._password { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try { if let v = self._port { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 3) - } }() - try { if let v = self._gateway { - try visitor.visitSingularStringField(value: v, fieldNumber: 4) - } }() - try { if let v = self._frequency { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 5) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiHotspotCredentials) -> Bool { - if lhs._ssid != rhs._ssid {return false} - if lhs._password != rhs._password {return false} - if lhs._port != rhs._port {return false} - if lhs._gateway != rhs._gateway {return false} - if lhs._frequency != rhs._frequency {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiLanSocket" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "ip_address"), - 2: .standard(proto: "wifi_port"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._ipAddress) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self._wifiPort) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._ipAddress { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._wifiPort { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiLanSocket) -> Bool { - if lhs._ipAddress != rhs._ipAddress {return false} - if lhs._wifiPort != rhs._wifiPort {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".BluetoothCredentials" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "service_name"), - 2: .standard(proto: "mac_address"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._serviceName) }() - case 2: try { try decoder.decodeSingularStringField(value: &self._macAddress) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._serviceName { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._macAddress { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.BluetoothCredentials) -> Bool { - if lhs._serviceName != rhs._serviceName {return false} - if lhs._macAddress != rhs._macAddress {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiAwareCredentials" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "service_id"), - 2: .standard(proto: "service_info"), - 3: .same(proto: "password"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._serviceID) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._serviceInfo) }() - case 3: try { try decoder.decodeSingularStringField(value: &self._password) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._serviceID { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._serviceInfo { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try { if let v = self._password { - try visitor.visitSingularStringField(value: v, fieldNumber: 3) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiAwareCredentials) -> Bool { - if lhs._serviceID != rhs._serviceID {return false} - if lhs._serviceInfo != rhs._serviceInfo {return false} - if lhs._password != rhs._password {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WifiDirectCredentials" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "ssid"), - 2: .same(proto: "password"), - 3: .same(proto: "port"), - 4: .same(proto: "frequency"), - 5: .same(proto: "gateway"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._ssid) }() - case 2: try { try decoder.decodeSingularStringField(value: &self._password) }() - case 3: try { try decoder.decodeSingularInt32Field(value: &self._port) }() - case 4: try { try decoder.decodeSingularInt32Field(value: &self._frequency) }() - case 5: try { try decoder.decodeSingularStringField(value: &self._gateway) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._ssid { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._password { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try { if let v = self._port { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 3) - } }() - try { if let v = self._frequency { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 4) - } }() - try { if let v = self._gateway { - try visitor.visitSingularStringField(value: v, fieldNumber: 5) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WifiDirectCredentials) -> Bool { - if lhs._ssid != rhs._ssid {return false} - if lhs._password != rhs._password {return false} - if lhs._port != rhs._port {return false} - if lhs._frequency != rhs._frequency {return false} - if lhs._gateway != rhs._gateway {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.protoMessageName + ".WebRtcCredentials" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "peer_id"), - 2: .standard(proto: "location_hint"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._peerID) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._locationHint) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._peerID { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._locationHint { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.UpgradePathInfo.WebRtcCredentials) -> Bool { - if lhs._peerID != rhs._peerID {return false} - if lhs._locationHint != rhs._locationHint {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.protoMessageName + ".ClientIntroduction" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "endpoint_id"), - 2: .standard(proto: "supports_disabling_encryption"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._endpointID) }() - case 2: try { try decoder.decodeSingularBoolField(value: &self._supportsDisablingEncryption) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._endpointID { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._supportsDisablingEncryption { - try visitor.visitSingularBoolField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroduction) -> Bool { - if lhs._endpointID != rhs._endpointID {return false} - if lhs._supportsDisablingEncryption != rhs._supportsDisablingEncryption {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.protoMessageName + ".ClientIntroductionAck" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck, rhs: Location_Nearby_Connections_BandwidthUpgradeNegotiationFrame.ClientIntroductionAck) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_KeepAliveFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".KeepAliveFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "ack"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBoolField(value: &self._ack) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._ack { - try visitor.visitSingularBoolField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_KeepAliveFrame, rhs: Location_Nearby_Connections_KeepAliveFrame) -> Bool { - if lhs._ack != rhs._ack {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_DisconnectionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".DisconnectionFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "request_safe_to_disconnect"), - 2: .standard(proto: "ack_safe_to_disconnect"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBoolField(value: &self._requestSafeToDisconnect) }() - case 2: try { try decoder.decodeSingularBoolField(value: &self._ackSafeToDisconnect) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._requestSafeToDisconnect { - try visitor.visitSingularBoolField(value: v, fieldNumber: 1) - } }() - try { if let v = self._ackSafeToDisconnect { - try visitor.visitSingularBoolField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_DisconnectionFrame, rhs: Location_Nearby_Connections_DisconnectionFrame) -> Bool { - if lhs._requestSafeToDisconnect != rhs._requestSafeToDisconnect {return false} - if lhs._ackSafeToDisconnect != rhs._ackSafeToDisconnect {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_PairedKeyEncryptionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".PairedKeyEncryptionFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "signed_data"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._signedData) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._signedData { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_PairedKeyEncryptionFrame, rhs: Location_Nearby_Connections_PairedKeyEncryptionFrame) -> Bool { - if lhs._signedData != rhs._signedData {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_MediumMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".MediumMetadata" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "supports_5_ghz"), - 2: .same(proto: "bssid"), - 3: .standard(proto: "ip_address"), - 4: .standard(proto: "supports_6_ghz"), - 5: .standard(proto: "mobile_radio"), - 6: .standard(proto: "ap_frequency"), - 7: .standard(proto: "available_channels"), - 8: .standard(proto: "wifi_direct_cli_usable_channels"), - 9: .standard(proto: "wifi_lan_usable_channels"), - 10: .standard(proto: "wifi_aware_usable_channels"), - 11: .standard(proto: "wifi_hotspot_sta_usable_channels"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBoolField(value: &self._supports5Ghz) }() - case 2: try { try decoder.decodeSingularStringField(value: &self._bssid) }() - case 3: try { try decoder.decodeSingularBytesField(value: &self._ipAddress) }() - case 4: try { try decoder.decodeSingularBoolField(value: &self._supports6Ghz) }() - case 5: try { try decoder.decodeSingularBoolField(value: &self._mobileRadio) }() - case 6: try { try decoder.decodeSingularInt32Field(value: &self._apFrequency) }() - case 7: try { try decoder.decodeSingularMessageField(value: &self._availableChannels) }() - case 8: try { try decoder.decodeSingularMessageField(value: &self._wifiDirectCliUsableChannels) }() - case 9: try { try decoder.decodeSingularMessageField(value: &self._wifiLanUsableChannels) }() - case 10: try { try decoder.decodeSingularMessageField(value: &self._wifiAwareUsableChannels) }() - case 11: try { try decoder.decodeSingularMessageField(value: &self._wifiHotspotStaUsableChannels) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._supports5Ghz { - try visitor.visitSingularBoolField(value: v, fieldNumber: 1) - } }() - try { if let v = self._bssid { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try { if let v = self._ipAddress { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try { if let v = self._supports6Ghz { - try visitor.visitSingularBoolField(value: v, fieldNumber: 4) - } }() - try { if let v = self._mobileRadio { - try visitor.visitSingularBoolField(value: v, fieldNumber: 5) - } }() - try { if let v = self._apFrequency { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 6) - } }() - try { if let v = self._availableChannels { - try visitor.visitSingularMessageField(value: v, fieldNumber: 7) - } }() - try { if let v = self._wifiDirectCliUsableChannels { - try visitor.visitSingularMessageField(value: v, fieldNumber: 8) - } }() - try { if let v = self._wifiLanUsableChannels { - try visitor.visitSingularMessageField(value: v, fieldNumber: 9) - } }() - try { if let v = self._wifiAwareUsableChannels { - try visitor.visitSingularMessageField(value: v, fieldNumber: 10) - } }() - try { if let v = self._wifiHotspotStaUsableChannels { - try visitor.visitSingularMessageField(value: v, fieldNumber: 11) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_MediumMetadata, rhs: Location_Nearby_Connections_MediumMetadata) -> Bool { - if lhs._supports5Ghz != rhs._supports5Ghz {return false} - if lhs._bssid != rhs._bssid {return false} - if lhs._ipAddress != rhs._ipAddress {return false} - if lhs._supports6Ghz != rhs._supports6Ghz {return false} - if lhs._mobileRadio != rhs._mobileRadio {return false} - if lhs._apFrequency != rhs._apFrequency {return false} - if lhs._availableChannels != rhs._availableChannels {return false} - if lhs._wifiDirectCliUsableChannels != rhs._wifiDirectCliUsableChannels {return false} - if lhs._wifiLanUsableChannels != rhs._wifiLanUsableChannels {return false} - if lhs._wifiAwareUsableChannels != rhs._wifiAwareUsableChannels {return false} - if lhs._wifiHotspotStaUsableChannels != rhs._wifiHotspotStaUsableChannels {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_AvailableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".AvailableChannels" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "channels"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.channels.isEmpty { - try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_AvailableChannels, rhs: Location_Nearby_Connections_AvailableChannels) -> Bool { - if lhs.channels != rhs.channels {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_WifiDirectCliUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".WifiDirectCliUsableChannels" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "channels"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.channels.isEmpty { - try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_WifiDirectCliUsableChannels, rhs: Location_Nearby_Connections_WifiDirectCliUsableChannels) -> Bool { - if lhs.channels != rhs.channels {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_WifiLanUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".WifiLanUsableChannels" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "channels"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.channels.isEmpty { - try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_WifiLanUsableChannels, rhs: Location_Nearby_Connections_WifiLanUsableChannels) -> Bool { - if lhs.channels != rhs.channels {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_WifiAwareUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".WifiAwareUsableChannels" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "channels"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.channels.isEmpty { - try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_WifiAwareUsableChannels, rhs: Location_Nearby_Connections_WifiAwareUsableChannels) -> Bool { - if lhs.channels != rhs.channels {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_WifiHotspotStaUsableChannels: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".WifiHotspotStaUsableChannels" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "channels"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeRepeatedInt32Field(value: &self.channels) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.channels.isEmpty { - try visitor.visitPackedInt32Field(value: self.channels, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_WifiHotspotStaUsableChannels, rhs: Location_Nearby_Connections_WifiHotspotStaUsableChannels) -> Bool { - if lhs.channels != rhs.channels {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_LocationHint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".LocationHint" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "location"), - 2: .same(proto: "format"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._location) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self._format) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._location { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._format { - try visitor.visitSingularEnumField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_LocationHint, rhs: Location_Nearby_Connections_LocationHint) -> Bool { - if lhs._location != rhs._location {return false} - if lhs._format != rhs._format {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_LocationStandard: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".LocationStandard" - static let _protobuf_nameMap = SwiftProtobuf._NameMap() - - mutating func decodeMessage(decoder: inout D) throws { - while let _ = try decoder.nextFieldNumber() { - } - } - - func traverse(visitor: inout V) throws { - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_LocationStandard, rhs: Location_Nearby_Connections_LocationStandard) -> Bool { - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_LocationStandard.Format: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "E164_CALLING"), - 2: .same(proto: "ISO_3166_1_ALPHA_2"), - ] -} - -extension Location_Nearby_Connections_OsInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".OsInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Location_Nearby_Connections_OsInfo, rhs: Location_Nearby_Connections_OsInfo) -> Bool { - if lhs._type != rhs._type {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Location_Nearby_Connections_OsInfo.OsType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_OS_TYPE"), - 1: .same(proto: "ANDROID"), - 2: .same(proto: "CHROME_OS"), - 3: .same(proto: "WINDOWS"), - 4: .same(proto: "APPLE"), - 100: .same(proto: "LINUX"), - ] -} diff --git a/submissions/sapphire/ProtobufGenerated/securegcm.pb.swift b/submissions/sapphire/ProtobufGenerated/securegcm.pb.swift deleted file mode 100644 index 5da7ecc7..00000000 --- a/submissions/sapphire/ProtobufGenerated/securegcm.pb.swift +++ /dev/null @@ -1,1522 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: securegcm.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that you are building against the same version of the API -// that was used to generate this file. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -/// This enum is used by iOS devices as values for device_display_diagonal_mils -/// in GcmDeviceInfo. There is no good way to calculate it on those devices. -enum Securegcm_AppleDeviceDiagonalMils: SwiftProtobuf.Enum { - typealias RawValue = Int - - /// This is the mils diagonal on an iPhone 5. - case applePhone // = 4000 - - /// This is the mils diagonal on an iPad mini. - case applePad // = 7900 - - init() { - self = .applePhone - } - - init?(rawValue: Int) { - switch rawValue { - case 4000: self = .applePhone - case 7900: self = .applePad - default: return nil - } - } - - var rawValue: Int { - switch self { - case .applePhone: return 4000 - case .applePad: return 7900 - } - } - -} - -#if swift(>=4.2) - -extension Securegcm_AppleDeviceDiagonalMils: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// This should be kept in sync with DeviceType in: -/// java/com/google/security/cryptauth/backend/services/common/common_enums.proto -enum Securegcm_DeviceType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknown // = 0 - case android // = 1 - case chrome // = 2 - case ios // = 3 - case browser // = 4 - case osx // = 5 - - init() { - self = .unknown - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknown - case 1: self = .android - case 2: self = .chrome - case 3: self = .ios - case 4: self = .browser - case 5: self = .osx - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknown: return 0 - case .android: return 1 - case .chrome: return 2 - case .ios: return 3 - case .browser: return 4 - case .osx: return 5 - } - } - -} - -#if swift(>=4.2) - -extension Securegcm_DeviceType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// MultiDevice features which may be supported and enabled on a device. See -enum Securegcm_SoftwareFeature: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownFeature // = 0 - case betterTogetherHost // = 1 - case betterTogetherClient // = 2 - case easyUnlockHost // = 3 - case easyUnlockClient // = 4 - case magicTetherHost // = 5 - case magicTetherClient // = 6 - case smsConnectHost // = 7 - case smsConnectClient // = 8 - - init() { - self = .unknownFeature - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownFeature - case 1: self = .betterTogetherHost - case 2: self = .betterTogetherClient - case 3: self = .easyUnlockHost - case 4: self = .easyUnlockClient - case 5: self = .magicTetherHost - case 6: self = .magicTetherClient - case 7: self = .smsConnectHost - case 8: self = .smsConnectClient - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownFeature: return 0 - case .betterTogetherHost: return 1 - case .betterTogetherClient: return 2 - case .easyUnlockHost: return 3 - case .easyUnlockClient: return 4 - case .magicTetherHost: return 5 - case .magicTetherClient: return 6 - case .smsConnectHost: return 7 - case .smsConnectClient: return 8 - } - } - -} - -#if swift(>=4.2) - -extension Securegcm_SoftwareFeature: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// A list of "reasons" that can be provided for calling server-side APIs. -/// This is particularly important for calls that can be triggered by different -/// kinds of events. Please try to keep reasons as generic as possible, so that -/// codes can be re-used by various callers in a sensible fashion. -enum Securegcm_InvocationReason: SwiftProtobuf.Enum { - typealias RawValue = Int - case reasonUnknown // = 0 - - /// First run of the software package invoking this call - case reasonInitialization // = 1 - - /// Ordinary periodic actions (e.g. monthly master key rotation) - case reasonPeriodic // = 2 - - /// Slow-cycle periodic action (e.g. yearly keypair rotation???) - case reasonSlowPeriodic // = 3 - - /// Fast-cycle periodic action (e.g. daily sync for Smart Lock users) - case reasonFastPeriodic // = 4 - - /// Expired state (e.g. expired credentials, or cached entries) was detected - case reasonExpiration // = 5 - - /// An unexpected protocol failure occurred (so attempting to repair state) - case reasonFailureRecovery // = 6 - - /// A new account has been added to the device - case reasonNewAccount // = 7 - - /// An existing account on the device has been changed - case reasonChangedAccount // = 8 - - /// The user toggled the state of a feature (e.g. Smart Lock enabled via BT) - case reasonFeatureToggled // = 9 - - /// A "push" from the server caused this action (e.g. a sync tickle) - case reasonServerInitiated // = 10 - - /// A local address change triggered this (e.g. GCM registration id changed) - case reasonAddressChange // = 11 - - /// A software update has triggered this - case reasonSoftwareUpdate // = 12 - - /// A manual action by the user triggered this (e.g. commands sent via adb) - case reasonManual // = 13 - - /// A custom key has been invalidated on the device (e.g. screen lock is - /// disabled). - case reasonCustomKeyInvalidation // = 14 - - /// Periodic action triggered by auth_proximity - case reasonProximityPeriodic // = 15 - - init() { - self = .reasonUnknown - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .reasonUnknown - case 1: self = .reasonInitialization - case 2: self = .reasonPeriodic - case 3: self = .reasonSlowPeriodic - case 4: self = .reasonFastPeriodic - case 5: self = .reasonExpiration - case 6: self = .reasonFailureRecovery - case 7: self = .reasonNewAccount - case 8: self = .reasonChangedAccount - case 9: self = .reasonFeatureToggled - case 10: self = .reasonServerInitiated - case 11: self = .reasonAddressChange - case 12: self = .reasonSoftwareUpdate - case 13: self = .reasonManual - case 14: self = .reasonCustomKeyInvalidation - case 15: self = .reasonProximityPeriodic - default: return nil - } - } - - var rawValue: Int { - switch self { - case .reasonUnknown: return 0 - case .reasonInitialization: return 1 - case .reasonPeriodic: return 2 - case .reasonSlowPeriodic: return 3 - case .reasonFastPeriodic: return 4 - case .reasonExpiration: return 5 - case .reasonFailureRecovery: return 6 - case .reasonNewAccount: return 7 - case .reasonChangedAccount: return 8 - case .reasonFeatureToggled: return 9 - case .reasonServerInitiated: return 10 - case .reasonAddressChange: return 11 - case .reasonSoftwareUpdate: return 12 - case .reasonManual: return 13 - case .reasonCustomKeyInvalidation: return 14 - case .reasonProximityPeriodic: return 15 - } - } - -} - -#if swift(>=4.2) - -extension Securegcm_InvocationReason: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -enum Securegcm_Type: SwiftProtobuf.Enum { - typealias RawValue = Int - case enrollment // = 0 - case tickle // = 1 - case txRequest // = 2 - case txReply // = 3 - case txSyncRequest // = 4 - case txSyncResponse // = 5 - case txPing // = 6 - case deviceInfoUpdate // = 7 - case txCancelRequest // = 8 - - /// DEPRECATED (can be re-used after Aug 2015) - case proximityauthPairing // = 10 - - /// The kind of identity assertion generated by a "GCM V1" device (i.e., - /// an Android phone that has registered with us a public and a symmetric - /// key) - case gcmv1IdentityAssertion // = 11 - - /// Device-to-device communications are protected by an unauthenticated - /// Diffie-Hellman exchange. The InitiatorHello message is simply the - /// initiator's public DH key, and is not encoded as a SecureMessage, so - /// it doesn't have a tag. - /// The ResponderHello message (which is sent by the responder - /// to the initiator), on the other hand, carries a payload that is protected - /// by the derived shared key. It also contains the responder's - /// public DH key. ResponderHelloAndPayload messages have the - /// DEVICE_TO_DEVICE_RESPONDER_HELLO tag. - case deviceToDeviceResponderHelloPayload // = 12 - - /// Device-to-device communications are protected by an unauthenticated - /// Diffie-Hellman exchange. Once the initiator and responder - /// agree on a shared key (through Diffie-Hellman), they will use messages - /// tagged with DEVICE_TO_DEVICE_MESSAGE to exchange data. - case deviceToDeviceMessage // = 13 - - /// Notification to let a device know it should contact a nearby device. - case deviceProximityCallback // = 14 - - /// Device-to-device communications are protected by an unauthenticated - /// Diffie-Hellman exchange. During device-to-device authentication, the first - /// message from initiator (the challenge) is signed and put into the payload - /// of the message sent back to the initiator. - case unlockKeySignedChallenge // = 15 - - /// Specialty (corp only) features - case loginNotification // = 101 - - init() { - self = .enrollment - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .enrollment - case 1: self = .tickle - case 2: self = .txRequest - case 3: self = .txReply - case 4: self = .txSyncRequest - case 5: self = .txSyncResponse - case 6: self = .txPing - case 7: self = .deviceInfoUpdate - case 8: self = .txCancelRequest - case 10: self = .proximityauthPairing - case 11: self = .gcmv1IdentityAssertion - case 12: self = .deviceToDeviceResponderHelloPayload - case 13: self = .deviceToDeviceMessage - case 14: self = .deviceProximityCallback - case 15: self = .unlockKeySignedChallenge - case 101: self = .loginNotification - default: return nil - } - } - - var rawValue: Int { - switch self { - case .enrollment: return 0 - case .tickle: return 1 - case .txRequest: return 2 - case .txReply: return 3 - case .txSyncRequest: return 4 - case .txSyncResponse: return 5 - case .txPing: return 6 - case .deviceInfoUpdate: return 7 - case .txCancelRequest: return 8 - case .proximityauthPairing: return 10 - case .gcmv1IdentityAssertion: return 11 - case .deviceToDeviceResponderHelloPayload: return 12 - case .deviceToDeviceMessage: return 13 - case .deviceProximityCallback: return 14 - case .unlockKeySignedChallenge: return 15 - case .loginNotification: return 101 - } - } - -} - -#if swift(>=4.2) - -extension Securegcm_Type: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// Message used only during enrollment -/// Field numbers should be kept in sync with DeviceInfo in: -/// java/com/google/security/cryptauth/backend/services/common/common.proto -struct Securegcm_GcmDeviceInfo { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// This field's name does not match the one in DeviceInfo for legacy reasons. - /// Consider using long_device_id and device_type instead when enrolling - /// non-android devices. - var androidDeviceID: UInt64 { - get {return _storage._androidDeviceID ?? 0} - set {_uniqueStorage()._androidDeviceID = newValue} - } - /// Returns true if `androidDeviceID` has been explicitly set. - var hasAndroidDeviceID: Bool {return _storage._androidDeviceID != nil} - /// Clears the value of `androidDeviceID`. Subsequent reads from it will return its default value. - mutating func clearAndroidDeviceID() {_uniqueStorage()._androidDeviceID = nil} - - /// Used for device_address of DeviceInfo field 2, but for GCM capable devices. - var gcmRegistrationID: Data { - get {return _storage._gcmRegistrationID ?? Data()} - set {_uniqueStorage()._gcmRegistrationID = newValue} - } - /// Returns true if `gcmRegistrationID` has been explicitly set. - var hasGcmRegistrationID: Bool {return _storage._gcmRegistrationID != nil} - /// Clears the value of `gcmRegistrationID`. Subsequent reads from it will return its default value. - mutating func clearGcmRegistrationID() {_uniqueStorage()._gcmRegistrationID = nil} - - /// Used for device_address of DeviceInfo field 2, but for iOS devices. - var apnRegistrationID: Data { - get {return _storage._apnRegistrationID ?? Data()} - set {_uniqueStorage()._apnRegistrationID = newValue} - } - /// Returns true if `apnRegistrationID` has been explicitly set. - var hasApnRegistrationID: Bool {return _storage._apnRegistrationID != nil} - /// Clears the value of `apnRegistrationID`. Subsequent reads from it will return its default value. - mutating func clearApnRegistrationID() {_uniqueStorage()._apnRegistrationID = nil} - - /// Does the user have notifications enabled for the given device address. - var notificationEnabled: Bool { - get {return _storage._notificationEnabled ?? true} - set {_uniqueStorage()._notificationEnabled = newValue} - } - /// Returns true if `notificationEnabled` has been explicitly set. - var hasNotificationEnabled: Bool {return _storage._notificationEnabled != nil} - /// Clears the value of `notificationEnabled`. Subsequent reads from it will return its default value. - mutating func clearNotificationEnabled() {_uniqueStorage()._notificationEnabled = nil} - - /// Used for device_address of DeviceInfo field 2, a Bluetooth Mac address for - /// the device (e.g., to be used with EasyUnlock) - var bluetoothMacAddress: String { - get {return _storage._bluetoothMacAddress ?? String()} - set {_uniqueStorage()._bluetoothMacAddress = newValue} - } - /// Returns true if `bluetoothMacAddress` has been explicitly set. - var hasBluetoothMacAddress: Bool {return _storage._bluetoothMacAddress != nil} - /// Clears the value of `bluetoothMacAddress`. Subsequent reads from it will return its default value. - mutating func clearBluetoothMacAddress() {_uniqueStorage()._bluetoothMacAddress = nil} - - /// SHA-256 hash of the device master key (from the key exchange). - /// Differs from DeviceInfo field 3, which contains the actual master key. - var deviceMasterKeyHash: Data { - get {return _storage._deviceMasterKeyHash ?? Data()} - set {_uniqueStorage()._deviceMasterKeyHash = newValue} - } - /// Returns true if `deviceMasterKeyHash` has been explicitly set. - var hasDeviceMasterKeyHash: Bool {return _storage._deviceMasterKeyHash != nil} - /// Clears the value of `deviceMasterKeyHash`. Subsequent reads from it will return its default value. - mutating func clearDeviceMasterKeyHash() {_uniqueStorage()._deviceMasterKeyHash = nil} - - /// A SecureMessage.EcP256PublicKey - var userPublicKey: Data { - get {return _storage._userPublicKey ?? Data()} - set {_uniqueStorage()._userPublicKey = newValue} - } - /// Returns true if `userPublicKey` has been explicitly set. - var hasUserPublicKey: Bool {return _storage._userPublicKey != nil} - /// Clears the value of `userPublicKey`. Subsequent reads from it will return its default value. - mutating func clearUserPublicKey() {_uniqueStorage()._userPublicKey = nil} - - /// device's model name - /// (e.g., an android.os.Build.MODEL or UIDevice.model) - var deviceModel: String { - get {return _storage._deviceModel ?? String()} - set {_uniqueStorage()._deviceModel = newValue} - } - /// Returns true if `deviceModel` has been explicitly set. - var hasDeviceModel: Bool {return _storage._deviceModel != nil} - /// Clears the value of `deviceModel`. Subsequent reads from it will return its default value. - mutating func clearDeviceModel() {_uniqueStorage()._deviceModel = nil} - - /// device's locale - var locale: String { - get {return _storage._locale ?? String()} - set {_uniqueStorage()._locale = newValue} - } - /// Returns true if `locale` has been explicitly set. - var hasLocale: Bool {return _storage._locale != nil} - /// Clears the value of `locale`. Subsequent reads from it will return its default value. - mutating func clearLocale() {_uniqueStorage()._locale = nil} - - /// The handle for user_public_key (and implicitly, a master key) - var keyHandle: Data { - get {return _storage._keyHandle ?? Data()} - set {_uniqueStorage()._keyHandle = newValue} - } - /// Returns true if `keyHandle` has been explicitly set. - var hasKeyHandle: Bool {return _storage._keyHandle != nil} - /// Clears the value of `keyHandle`. Subsequent reads from it will return its default value. - mutating func clearKeyHandle() {_uniqueStorage()._keyHandle = nil} - - /// The initial counter value for the device, sent by the device - var counter: Int64 { - get {return _storage._counter ?? 0} - set {_uniqueStorage()._counter = newValue} - } - /// Returns true if `counter` has been explicitly set. - var hasCounter: Bool {return _storage._counter != nil} - /// Clears the value of `counter`. Subsequent reads from it will return its default value. - mutating func clearCounter() {_uniqueStorage()._counter = nil} - - /// The Operating System version on the device - /// (e.g., an android.os.Build.DISPLAY or UIDevice.systemVersion) - var deviceOsVersion: String { - get {return _storage._deviceOsVersion ?? String()} - set {_uniqueStorage()._deviceOsVersion = newValue} - } - /// Returns true if `deviceOsVersion` has been explicitly set. - var hasDeviceOsVersion: Bool {return _storage._deviceOsVersion != nil} - /// Clears the value of `deviceOsVersion`. Subsequent reads from it will return its default value. - mutating func clearDeviceOsVersion() {_uniqueStorage()._deviceOsVersion = nil} - - /// The Operating System version number on the device - /// (e.g., an android.os.Build.VERSION.SDK_INT) - var deviceOsVersionCode: Int64 { - get {return _storage._deviceOsVersionCode ?? 0} - set {_uniqueStorage()._deviceOsVersionCode = newValue} - } - /// Returns true if `deviceOsVersionCode` has been explicitly set. - var hasDeviceOsVersionCode: Bool {return _storage._deviceOsVersionCode != nil} - /// Clears the value of `deviceOsVersionCode`. Subsequent reads from it will return its default value. - mutating func clearDeviceOsVersionCode() {_uniqueStorage()._deviceOsVersionCode = nil} - - /// The Operating System release on the device - /// (e.g., an android.os.Build.VERSION.RELEASE) - var deviceOsRelease: String { - get {return _storage._deviceOsRelease ?? String()} - set {_uniqueStorage()._deviceOsRelease = newValue} - } - /// Returns true if `deviceOsRelease` has been explicitly set. - var hasDeviceOsRelease: Bool {return _storage._deviceOsRelease != nil} - /// Clears the value of `deviceOsRelease`. Subsequent reads from it will return its default value. - mutating func clearDeviceOsRelease() {_uniqueStorage()._deviceOsRelease = nil} - - /// The Operating System codename on the device - /// (e.g., an android.os.Build.VERSION.CODENAME or UIDevice.systemName) - var deviceOsCodename: String { - get {return _storage._deviceOsCodename ?? String()} - set {_uniqueStorage()._deviceOsCodename = newValue} - } - /// Returns true if `deviceOsCodename` has been explicitly set. - var hasDeviceOsCodename: Bool {return _storage._deviceOsCodename != nil} - /// Clears the value of `deviceOsCodename`. Subsequent reads from it will return its default value. - mutating func clearDeviceOsCodename() {_uniqueStorage()._deviceOsCodename = nil} - - /// The software version running on the device - /// (e.g., Authenticator app version string) - var deviceSoftwareVersion: String { - get {return _storage._deviceSoftwareVersion ?? String()} - set {_uniqueStorage()._deviceSoftwareVersion = newValue} - } - /// Returns true if `deviceSoftwareVersion` has been explicitly set. - var hasDeviceSoftwareVersion: Bool {return _storage._deviceSoftwareVersion != nil} - /// Clears the value of `deviceSoftwareVersion`. Subsequent reads from it will return its default value. - mutating func clearDeviceSoftwareVersion() {_uniqueStorage()._deviceSoftwareVersion = nil} - - /// The software version number running on the device - /// (e.g., Authenticator app version code) - var deviceSoftwareVersionCode: Int64 { - get {return _storage._deviceSoftwareVersionCode ?? 0} - set {_uniqueStorage()._deviceSoftwareVersionCode = newValue} - } - /// Returns true if `deviceSoftwareVersionCode` has been explicitly set. - var hasDeviceSoftwareVersionCode: Bool {return _storage._deviceSoftwareVersionCode != nil} - /// Clears the value of `deviceSoftwareVersionCode`. Subsequent reads from it will return its default value. - mutating func clearDeviceSoftwareVersionCode() {_uniqueStorage()._deviceSoftwareVersionCode = nil} - - /// Software package information if applicable - /// (e.g., com.google.android.apps.authenticator2) - var deviceSoftwarePackage: String { - get {return _storage._deviceSoftwarePackage ?? String()} - set {_uniqueStorage()._deviceSoftwarePackage = newValue} - } - /// Returns true if `deviceSoftwarePackage` has been explicitly set. - var hasDeviceSoftwarePackage: Bool {return _storage._deviceSoftwarePackage != nil} - /// Clears the value of `deviceSoftwarePackage`. Subsequent reads from it will return its default value. - mutating func clearDeviceSoftwarePackage() {_uniqueStorage()._deviceSoftwarePackage = nil} - - /// Size of the display in thousandths of an inch (e.g., 7000 mils = 7 in) - var deviceDisplayDiagonalMils: Int32 { - get {return _storage._deviceDisplayDiagonalMils ?? 0} - set {_uniqueStorage()._deviceDisplayDiagonalMils = newValue} - } - /// Returns true if `deviceDisplayDiagonalMils` has been explicitly set. - var hasDeviceDisplayDiagonalMils: Bool {return _storage._deviceDisplayDiagonalMils != nil} - /// Clears the value of `deviceDisplayDiagonalMils`. Subsequent reads from it will return its default value. - mutating func clearDeviceDisplayDiagonalMils() {_uniqueStorage()._deviceDisplayDiagonalMils = nil} - - /// For Authzen capable devices, their Authzen protocol version - var deviceAuthzenVersion: Int32 { - get {return _storage._deviceAuthzenVersion ?? 0} - set {_uniqueStorage()._deviceAuthzenVersion = newValue} - } - /// Returns true if `deviceAuthzenVersion` has been explicitly set. - var hasDeviceAuthzenVersion: Bool {return _storage._deviceAuthzenVersion != nil} - /// Clears the value of `deviceAuthzenVersion`. Subsequent reads from it will return its default value. - mutating func clearDeviceAuthzenVersion() {_uniqueStorage()._deviceAuthzenVersion = nil} - - /// Not all devices have device identifiers that fit in 64 bits. - var longDeviceID: Data { - get {return _storage._longDeviceID ?? Data()} - set {_uniqueStorage()._longDeviceID = newValue} - } - /// Returns true if `longDeviceID` has been explicitly set. - var hasLongDeviceID: Bool {return _storage._longDeviceID != nil} - /// Clears the value of `longDeviceID`. Subsequent reads from it will return its default value. - mutating func clearLongDeviceID() {_uniqueStorage()._longDeviceID = nil} - - /// The device manufacturer name - /// (e.g., android.os.Build.MANUFACTURER) - var deviceManufacturer: String { - get {return _storage._deviceManufacturer ?? String()} - set {_uniqueStorage()._deviceManufacturer = newValue} - } - /// Returns true if `deviceManufacturer` has been explicitly set. - var hasDeviceManufacturer: Bool {return _storage._deviceManufacturer != nil} - /// Clears the value of `deviceManufacturer`. Subsequent reads from it will return its default value. - mutating func clearDeviceManufacturer() {_uniqueStorage()._deviceManufacturer = nil} - - /// Used to indicate which type of device this is. - var deviceType: Securegcm_DeviceType { - get {return _storage._deviceType ?? .android} - set {_uniqueStorage()._deviceType = newValue} - } - /// Returns true if `deviceType` has been explicitly set. - var hasDeviceType: Bool {return _storage._deviceType != nil} - /// Clears the value of `deviceType`. Subsequent reads from it will return its default value. - mutating func clearDeviceType() {_uniqueStorage()._deviceType = nil} - - /// Is this device using a secure screenlock (e.g., pattern or pin unlock) - var usingSecureScreenlock: Bool { - get {return _storage._usingSecureScreenlock ?? false} - set {_uniqueStorage()._usingSecureScreenlock = newValue} - } - /// Returns true if `usingSecureScreenlock` has been explicitly set. - var hasUsingSecureScreenlock: Bool {return _storage._usingSecureScreenlock != nil} - /// Clears the value of `usingSecureScreenlock`. Subsequent reads from it will return its default value. - mutating func clearUsingSecureScreenlock() {_uniqueStorage()._usingSecureScreenlock = nil} - - /// Is auto-unlocking the screenlock (e.g., when at "home") supported? - var autoUnlockScreenlockSupported: Bool { - get {return _storage._autoUnlockScreenlockSupported ?? false} - set {_uniqueStorage()._autoUnlockScreenlockSupported = newValue} - } - /// Returns true if `autoUnlockScreenlockSupported` has been explicitly set. - var hasAutoUnlockScreenlockSupported: Bool {return _storage._autoUnlockScreenlockSupported != nil} - /// Clears the value of `autoUnlockScreenlockSupported`. Subsequent reads from it will return its default value. - mutating func clearAutoUnlockScreenlockSupported() {_uniqueStorage()._autoUnlockScreenlockSupported = nil} - - /// Is auto-unlocking the screenlock (e.g., when at "home") enabled? - var autoUnlockScreenlockEnabled: Bool { - get {return _storage._autoUnlockScreenlockEnabled ?? false} - set {_uniqueStorage()._autoUnlockScreenlockEnabled = newValue} - } - /// Returns true if `autoUnlockScreenlockEnabled` has been explicitly set. - var hasAutoUnlockScreenlockEnabled: Bool {return _storage._autoUnlockScreenlockEnabled != nil} - /// Clears the value of `autoUnlockScreenlockEnabled`. Subsequent reads from it will return its default value. - mutating func clearAutoUnlockScreenlockEnabled() {_uniqueStorage()._autoUnlockScreenlockEnabled = nil} - - /// Does the device have a Bluetooth (classic) radio? - var bluetoothRadioSupported: Bool { - get {return _storage._bluetoothRadioSupported ?? false} - set {_uniqueStorage()._bluetoothRadioSupported = newValue} - } - /// Returns true if `bluetoothRadioSupported` has been explicitly set. - var hasBluetoothRadioSupported: Bool {return _storage._bluetoothRadioSupported != nil} - /// Clears the value of `bluetoothRadioSupported`. Subsequent reads from it will return its default value. - mutating func clearBluetoothRadioSupported() {_uniqueStorage()._bluetoothRadioSupported = nil} - - /// Is the Bluetooth (classic) radio on? - var bluetoothRadioEnabled: Bool { - get {return _storage._bluetoothRadioEnabled ?? false} - set {_uniqueStorage()._bluetoothRadioEnabled = newValue} - } - /// Returns true if `bluetoothRadioEnabled` has been explicitly set. - var hasBluetoothRadioEnabled: Bool {return _storage._bluetoothRadioEnabled != nil} - /// Clears the value of `bluetoothRadioEnabled`. Subsequent reads from it will return its default value. - mutating func clearBluetoothRadioEnabled() {_uniqueStorage()._bluetoothRadioEnabled = nil} - - /// Does the device hardware support a mobile data connection? - var mobileDataSupported: Bool { - get {return _storage._mobileDataSupported ?? false} - set {_uniqueStorage()._mobileDataSupported = newValue} - } - /// Returns true if `mobileDataSupported` has been explicitly set. - var hasMobileDataSupported: Bool {return _storage._mobileDataSupported != nil} - /// Clears the value of `mobileDataSupported`. Subsequent reads from it will return its default value. - mutating func clearMobileDataSupported() {_uniqueStorage()._mobileDataSupported = nil} - - /// Does the device support tethering? - var tetheringSupported: Bool { - get {return _storage._tetheringSupported ?? false} - set {_uniqueStorage()._tetheringSupported = newValue} - } - /// Returns true if `tetheringSupported` has been explicitly set. - var hasTetheringSupported: Bool {return _storage._tetheringSupported != nil} - /// Clears the value of `tetheringSupported`. Subsequent reads from it will return its default value. - mutating func clearTetheringSupported() {_uniqueStorage()._tetheringSupported = nil} - - /// Does the device have a BLE radio? - var bleRadioSupported: Bool { - get {return _storage._bleRadioSupported ?? false} - set {_uniqueStorage()._bleRadioSupported = newValue} - } - /// Returns true if `bleRadioSupported` has been explicitly set. - var hasBleRadioSupported: Bool {return _storage._bleRadioSupported != nil} - /// Clears the value of `bleRadioSupported`. Subsequent reads from it will return its default value. - mutating func clearBleRadioSupported() {_uniqueStorage()._bleRadioSupported = nil} - - /// Is the device a "Pixel Experience" Android device? - var pixelExperience: Bool { - get {return _storage._pixelExperience ?? false} - set {_uniqueStorage()._pixelExperience = newValue} - } - /// Returns true if `pixelExperience` has been explicitly set. - var hasPixelExperience: Bool {return _storage._pixelExperience != nil} - /// Clears the value of `pixelExperience`. Subsequent reads from it will return its default value. - mutating func clearPixelExperience() {_uniqueStorage()._pixelExperience = nil} - - /// Is the device running in the ARC++ container on a chromebook? - var arcPlusPlus: Bool { - get {return _storage._arcPlusPlus ?? false} - set {_uniqueStorage()._arcPlusPlus = newValue} - } - /// Returns true if `arcPlusPlus` has been explicitly set. - var hasArcPlusPlus: Bool {return _storage._arcPlusPlus != nil} - /// Clears the value of `arcPlusPlus`. Subsequent reads from it will return its default value. - mutating func clearArcPlusPlus() {_uniqueStorage()._arcPlusPlus = nil} - - /// Is the value set in |using_secure_screenlock| reliable? On some Android - /// devices, the platform API to get the screenlock state is not trustworthy. - /// See b/32212161. - var isScreenlockStateFlaky: Bool { - get {return _storage._isScreenlockStateFlaky ?? false} - set {_uniqueStorage()._isScreenlockStateFlaky = newValue} - } - /// Returns true if `isScreenlockStateFlaky` has been explicitly set. - var hasIsScreenlockStateFlaky: Bool {return _storage._isScreenlockStateFlaky != nil} - /// Clears the value of `isScreenlockStateFlaky`. Subsequent reads from it will return its default value. - mutating func clearIsScreenlockStateFlaky() {_uniqueStorage()._isScreenlockStateFlaky = nil} - - /// A list of multi-device software features supported by the device. - var supportedSoftwareFeatures: [Securegcm_SoftwareFeature] { - get {return _storage._supportedSoftwareFeatures} - set {_uniqueStorage()._supportedSoftwareFeatures = newValue} - } - - /// A list of multi-device software features currently enabled (active) on the - /// device. - var enabledSoftwareFeatures: [Securegcm_SoftwareFeature] { - get {return _storage._enabledSoftwareFeatures} - set {_uniqueStorage()._enabledSoftwareFeatures = newValue} - } - - /// The enrollment session id this is sent with - var enrollmentSessionID: Data { - get {return _storage._enrollmentSessionID ?? Data()} - set {_uniqueStorage()._enrollmentSessionID = newValue} - } - /// Returns true if `enrollmentSessionID` has been explicitly set. - var hasEnrollmentSessionID: Bool {return _storage._enrollmentSessionID != nil} - /// Clears the value of `enrollmentSessionID`. Subsequent reads from it will return its default value. - mutating func clearEnrollmentSessionID() {_uniqueStorage()._enrollmentSessionID = nil} - - /// A copy of the user's OAuth token - var oauthToken: String { - get {return _storage._oauthToken ?? String()} - set {_uniqueStorage()._oauthToken = newValue} - } - /// Returns true if `oauthToken` has been explicitly set. - var hasOauthToken: Bool {return _storage._oauthToken != nil} - /// Clears the value of `oauthToken`. Subsequent reads from it will return its default value. - mutating func clearOauthToken() {_uniqueStorage()._oauthToken = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _storage = _StorageClass.defaultInstance -} - -struct Securegcm_GcmMetadata { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var type: Securegcm_Type { - get {return _type ?? .enrollment} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - var version: Int32 { - get {return _version ?? 0} - set {_version = newValue} - } - /// Returns true if `version` has been explicitly set. - var hasVersion: Bool {return self._version != nil} - /// Clears the value of `version`. Subsequent reads from it will return its default value. - mutating func clearVersion() {self._version = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _type: Securegcm_Type? = nil - fileprivate var _version: Int32? = nil -} - -struct Securegcm_Tickle { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Time after which this tickle should expire - var expiryTime: UInt64 { - get {return _expiryTime ?? 0} - set {_expiryTime = newValue} - } - /// Returns true if `expiryTime` has been explicitly set. - var hasExpiryTime: Bool {return self._expiryTime != nil} - /// Clears the value of `expiryTime`. Subsequent reads from it will return its default value. - mutating func clearExpiryTime() {self._expiryTime = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _expiryTime: UInt64? = nil -} - -struct Securegcm_LoginNotificationInfo { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Time at which the server received the login notification request. - var creationTime: UInt64 { - get {return _creationTime ?? 0} - set {_creationTime = newValue} - } - /// Returns true if `creationTime` has been explicitly set. - var hasCreationTime: Bool {return self._creationTime != nil} - /// Clears the value of `creationTime`. Subsequent reads from it will return its default value. - mutating func clearCreationTime() {self._creationTime = nil} - - /// Must correspond to user_id in LoginNotificationRequest, if set. - var email: String { - get {return _email ?? String()} - set {_email = newValue} - } - /// Returns true if `email` has been explicitly set. - var hasEmail: Bool {return self._email != nil} - /// Clears the value of `email`. Subsequent reads from it will return its default value. - mutating func clearEmail() {self._email = nil} - - /// Host where the user's credentials were used to login, if meaningful. - var host: String { - get {return _host ?? String()} - set {_host = newValue} - } - /// Returns true if `host` has been explicitly set. - var hasHost: Bool {return self._host != nil} - /// Clears the value of `host`. Subsequent reads from it will return its default value. - mutating func clearHost() {self._host = nil} - - /// Location from where the user's credentials were used, if meaningful. - var source: String { - get {return _source ?? String()} - set {_source = newValue} - } - /// Returns true if `source` has been explicitly set. - var hasSource: Bool {return self._source != nil} - /// Clears the value of `source`. Subsequent reads from it will return its default value. - mutating func clearSource() {self._source = nil} - - /// Type of login, e.g. ssh, gnome-screensaver, or web. - var eventType: String { - get {return _eventType ?? String()} - set {_eventType = newValue} - } - /// Returns true if `eventType` has been explicitly set. - var hasEventType: Bool {return self._eventType != nil} - /// Clears the value of `eventType`. Subsequent reads from it will return its default value. - mutating func clearEventType() {self._eventType = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _creationTime: UInt64? = nil - fileprivate var _email: String? = nil - fileprivate var _host: String? = nil - fileprivate var _source: String? = nil - fileprivate var _eventType: String? = nil -} - -#if swift(>=5.5) && canImport(_Concurrency) -extension Securegcm_AppleDeviceDiagonalMils: @unchecked Sendable {} -extension Securegcm_DeviceType: @unchecked Sendable {} -extension Securegcm_SoftwareFeature: @unchecked Sendable {} -extension Securegcm_InvocationReason: @unchecked Sendable {} -extension Securegcm_Type: @unchecked Sendable {} -extension Securegcm_GcmDeviceInfo: @unchecked Sendable {} -extension Securegcm_GcmMetadata: @unchecked Sendable {} -extension Securegcm_Tickle: @unchecked Sendable {} -extension Securegcm_LoginNotificationInfo: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "securegcm" - -extension Securegcm_AppleDeviceDiagonalMils: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 4000: .same(proto: "APPLE_PHONE"), - 7900: .same(proto: "APPLE_PAD"), - ] -} - -extension Securegcm_DeviceType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "ANDROID"), - 2: .same(proto: "CHROME"), - 3: .same(proto: "IOS"), - 4: .same(proto: "BROWSER"), - 5: .same(proto: "OSX"), - ] -} - -extension Securegcm_SoftwareFeature: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_FEATURE"), - 1: .same(proto: "BETTER_TOGETHER_HOST"), - 2: .same(proto: "BETTER_TOGETHER_CLIENT"), - 3: .same(proto: "EASY_UNLOCK_HOST"), - 4: .same(proto: "EASY_UNLOCK_CLIENT"), - 5: .same(proto: "MAGIC_TETHER_HOST"), - 6: .same(proto: "MAGIC_TETHER_CLIENT"), - 7: .same(proto: "SMS_CONNECT_HOST"), - 8: .same(proto: "SMS_CONNECT_CLIENT"), - ] -} - -extension Securegcm_InvocationReason: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "REASON_UNKNOWN"), - 1: .same(proto: "REASON_INITIALIZATION"), - 2: .same(proto: "REASON_PERIODIC"), - 3: .same(proto: "REASON_SLOW_PERIODIC"), - 4: .same(proto: "REASON_FAST_PERIODIC"), - 5: .same(proto: "REASON_EXPIRATION"), - 6: .same(proto: "REASON_FAILURE_RECOVERY"), - 7: .same(proto: "REASON_NEW_ACCOUNT"), - 8: .same(proto: "REASON_CHANGED_ACCOUNT"), - 9: .same(proto: "REASON_FEATURE_TOGGLED"), - 10: .same(proto: "REASON_SERVER_INITIATED"), - 11: .same(proto: "REASON_ADDRESS_CHANGE"), - 12: .same(proto: "REASON_SOFTWARE_UPDATE"), - 13: .same(proto: "REASON_MANUAL"), - 14: .same(proto: "REASON_CUSTOM_KEY_INVALIDATION"), - 15: .same(proto: "REASON_PROXIMITY_PERIODIC"), - ] -} - -extension Securegcm_Type: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "ENROLLMENT"), - 1: .same(proto: "TICKLE"), - 2: .same(proto: "TX_REQUEST"), - 3: .same(proto: "TX_REPLY"), - 4: .same(proto: "TX_SYNC_REQUEST"), - 5: .same(proto: "TX_SYNC_RESPONSE"), - 6: .same(proto: "TX_PING"), - 7: .same(proto: "DEVICE_INFO_UPDATE"), - 8: .same(proto: "TX_CANCEL_REQUEST"), - 10: .same(proto: "PROXIMITYAUTH_PAIRING"), - 11: .same(proto: "GCMV1_IDENTITY_ASSERTION"), - 12: .same(proto: "DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD"), - 13: .same(proto: "DEVICE_TO_DEVICE_MESSAGE"), - 14: .same(proto: "DEVICE_PROXIMITY_CALLBACK"), - 15: .same(proto: "UNLOCK_KEY_SIGNED_CHALLENGE"), - 101: .same(proto: "LOGIN_NOTIFICATION"), - ] -} - -extension Securegcm_GcmDeviceInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".GcmDeviceInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "android_device_id"), - 102: .standard(proto: "gcm_registration_id"), - 202: .standard(proto: "apn_registration_id"), - 203: .standard(proto: "notification_enabled"), - 302: .standard(proto: "bluetooth_mac_address"), - 103: .standard(proto: "device_master_key_hash"), - 4: .standard(proto: "user_public_key"), - 7: .standard(proto: "device_model"), - 8: .same(proto: "locale"), - 9: .standard(proto: "key_handle"), - 12: .same(proto: "counter"), - 13: .standard(proto: "device_os_version"), - 14: .standard(proto: "device_os_version_code"), - 15: .standard(proto: "device_os_release"), - 16: .standard(proto: "device_os_codename"), - 17: .standard(proto: "device_software_version"), - 18: .standard(proto: "device_software_version_code"), - 19: .standard(proto: "device_software_package"), - 22: .standard(proto: "device_display_diagonal_mils"), - 24: .standard(proto: "device_authzen_version"), - 29: .standard(proto: "long_device_id"), - 31: .standard(proto: "device_manufacturer"), - 32: .standard(proto: "device_type"), - 400: .standard(proto: "using_secure_screenlock"), - 401: .standard(proto: "auto_unlock_screenlock_supported"), - 402: .standard(proto: "auto_unlock_screenlock_enabled"), - 403: .standard(proto: "bluetooth_radio_supported"), - 404: .standard(proto: "bluetooth_radio_enabled"), - 405: .standard(proto: "mobile_data_supported"), - 406: .standard(proto: "tethering_supported"), - 407: .standard(proto: "ble_radio_supported"), - 408: .standard(proto: "pixel_experience"), - 409: .standard(proto: "arc_plus_plus"), - 410: .standard(proto: "is_screenlock_state_flaky"), - 411: .standard(proto: "supported_software_features"), - 412: .standard(proto: "enabled_software_features"), - 1000: .standard(proto: "enrollment_session_id"), - 1001: .standard(proto: "oauth_token"), - ] - - fileprivate class _StorageClass { - var _androidDeviceID: UInt64? = nil - var _gcmRegistrationID: Data? = nil - var _apnRegistrationID: Data? = nil - var _notificationEnabled: Bool? = nil - var _bluetoothMacAddress: String? = nil - var _deviceMasterKeyHash: Data? = nil - var _userPublicKey: Data? = nil - var _deviceModel: String? = nil - var _locale: String? = nil - var _keyHandle: Data? = nil - var _counter: Int64? = nil - var _deviceOsVersion: String? = nil - var _deviceOsVersionCode: Int64? = nil - var _deviceOsRelease: String? = nil - var _deviceOsCodename: String? = nil - var _deviceSoftwareVersion: String? = nil - var _deviceSoftwareVersionCode: Int64? = nil - var _deviceSoftwarePackage: String? = nil - var _deviceDisplayDiagonalMils: Int32? = nil - var _deviceAuthzenVersion: Int32? = nil - var _longDeviceID: Data? = nil - var _deviceManufacturer: String? = nil - var _deviceType: Securegcm_DeviceType? = nil - var _usingSecureScreenlock: Bool? = nil - var _autoUnlockScreenlockSupported: Bool? = nil - var _autoUnlockScreenlockEnabled: Bool? = nil - var _bluetoothRadioSupported: Bool? = nil - var _bluetoothRadioEnabled: Bool? = nil - var _mobileDataSupported: Bool? = nil - var _tetheringSupported: Bool? = nil - var _bleRadioSupported: Bool? = nil - var _pixelExperience: Bool? = nil - var _arcPlusPlus: Bool? = nil - var _isScreenlockStateFlaky: Bool? = nil - var _supportedSoftwareFeatures: [Securegcm_SoftwareFeature] = [] - var _enabledSoftwareFeatures: [Securegcm_SoftwareFeature] = [] - var _enrollmentSessionID: Data? = nil - var _oauthToken: String? = nil - - static let defaultInstance = _StorageClass() - - private init() {} - - init(copying source: _StorageClass) { - _androidDeviceID = source._androidDeviceID - _gcmRegistrationID = source._gcmRegistrationID - _apnRegistrationID = source._apnRegistrationID - _notificationEnabled = source._notificationEnabled - _bluetoothMacAddress = source._bluetoothMacAddress - _deviceMasterKeyHash = source._deviceMasterKeyHash - _userPublicKey = source._userPublicKey - _deviceModel = source._deviceModel - _locale = source._locale - _keyHandle = source._keyHandle - _counter = source._counter - _deviceOsVersion = source._deviceOsVersion - _deviceOsVersionCode = source._deviceOsVersionCode - _deviceOsRelease = source._deviceOsRelease - _deviceOsCodename = source._deviceOsCodename - _deviceSoftwareVersion = source._deviceSoftwareVersion - _deviceSoftwareVersionCode = source._deviceSoftwareVersionCode - _deviceSoftwarePackage = source._deviceSoftwarePackage - _deviceDisplayDiagonalMils = source._deviceDisplayDiagonalMils - _deviceAuthzenVersion = source._deviceAuthzenVersion - _longDeviceID = source._longDeviceID - _deviceManufacturer = source._deviceManufacturer - _deviceType = source._deviceType - _usingSecureScreenlock = source._usingSecureScreenlock - _autoUnlockScreenlockSupported = source._autoUnlockScreenlockSupported - _autoUnlockScreenlockEnabled = source._autoUnlockScreenlockEnabled - _bluetoothRadioSupported = source._bluetoothRadioSupported - _bluetoothRadioEnabled = source._bluetoothRadioEnabled - _mobileDataSupported = source._mobileDataSupported - _tetheringSupported = source._tetheringSupported - _bleRadioSupported = source._bleRadioSupported - _pixelExperience = source._pixelExperience - _arcPlusPlus = source._arcPlusPlus - _isScreenlockStateFlaky = source._isScreenlockStateFlaky - _supportedSoftwareFeatures = source._supportedSoftwareFeatures - _enabledSoftwareFeatures = source._enabledSoftwareFeatures - _enrollmentSessionID = source._enrollmentSessionID - _oauthToken = source._oauthToken - } - } - - fileprivate mutating func _uniqueStorage() -> _StorageClass { - if !isKnownUniquelyReferenced(&_storage) { - _storage = _StorageClass(copying: _storage) - } - return _storage - } - - public var isInitialized: Bool { - return withExtendedLifetime(_storage) { (_storage: _StorageClass) in - if _storage._userPublicKey == nil {return false} - return true - } - } - - mutating func decodeMessage(decoder: inout D) throws { - _ = _uniqueStorage() - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularFixed64Field(value: &_storage._androidDeviceID) }() - case 4: try { try decoder.decodeSingularBytesField(value: &_storage._userPublicKey) }() - case 7: try { try decoder.decodeSingularStringField(value: &_storage._deviceModel) }() - case 8: try { try decoder.decodeSingularStringField(value: &_storage._locale) }() - case 9: try { try decoder.decodeSingularBytesField(value: &_storage._keyHandle) }() - case 12: try { try decoder.decodeSingularInt64Field(value: &_storage._counter) }() - case 13: try { try decoder.decodeSingularStringField(value: &_storage._deviceOsVersion) }() - case 14: try { try decoder.decodeSingularInt64Field(value: &_storage._deviceOsVersionCode) }() - case 15: try { try decoder.decodeSingularStringField(value: &_storage._deviceOsRelease) }() - case 16: try { try decoder.decodeSingularStringField(value: &_storage._deviceOsCodename) }() - case 17: try { try decoder.decodeSingularStringField(value: &_storage._deviceSoftwareVersion) }() - case 18: try { try decoder.decodeSingularInt64Field(value: &_storage._deviceSoftwareVersionCode) }() - case 19: try { try decoder.decodeSingularStringField(value: &_storage._deviceSoftwarePackage) }() - case 22: try { try decoder.decodeSingularInt32Field(value: &_storage._deviceDisplayDiagonalMils) }() - case 24: try { try decoder.decodeSingularInt32Field(value: &_storage._deviceAuthzenVersion) }() - case 29: try { try decoder.decodeSingularBytesField(value: &_storage._longDeviceID) }() - case 31: try { try decoder.decodeSingularStringField(value: &_storage._deviceManufacturer) }() - case 32: try { try decoder.decodeSingularEnumField(value: &_storage._deviceType) }() - case 102: try { try decoder.decodeSingularBytesField(value: &_storage._gcmRegistrationID) }() - case 103: try { try decoder.decodeSingularBytesField(value: &_storage._deviceMasterKeyHash) }() - case 202: try { try decoder.decodeSingularBytesField(value: &_storage._apnRegistrationID) }() - case 203: try { try decoder.decodeSingularBoolField(value: &_storage._notificationEnabled) }() - case 302: try { try decoder.decodeSingularStringField(value: &_storage._bluetoothMacAddress) }() - case 400: try { try decoder.decodeSingularBoolField(value: &_storage._usingSecureScreenlock) }() - case 401: try { try decoder.decodeSingularBoolField(value: &_storage._autoUnlockScreenlockSupported) }() - case 402: try { try decoder.decodeSingularBoolField(value: &_storage._autoUnlockScreenlockEnabled) }() - case 403: try { try decoder.decodeSingularBoolField(value: &_storage._bluetoothRadioSupported) }() - case 404: try { try decoder.decodeSingularBoolField(value: &_storage._bluetoothRadioEnabled) }() - case 405: try { try decoder.decodeSingularBoolField(value: &_storage._mobileDataSupported) }() - case 406: try { try decoder.decodeSingularBoolField(value: &_storage._tetheringSupported) }() - case 407: try { try decoder.decodeSingularBoolField(value: &_storage._bleRadioSupported) }() - case 408: try { try decoder.decodeSingularBoolField(value: &_storage._pixelExperience) }() - case 409: try { try decoder.decodeSingularBoolField(value: &_storage._arcPlusPlus) }() - case 410: try { try decoder.decodeSingularBoolField(value: &_storage._isScreenlockStateFlaky) }() - case 411: try { try decoder.decodeRepeatedEnumField(value: &_storage._supportedSoftwareFeatures) }() - case 412: try { try decoder.decodeRepeatedEnumField(value: &_storage._enabledSoftwareFeatures) }() - case 1000: try { try decoder.decodeSingularBytesField(value: &_storage._enrollmentSessionID) }() - case 1001: try { try decoder.decodeSingularStringField(value: &_storage._oauthToken) }() - default: break - } - } - } - } - - func traverse(visitor: inout V) throws { - try withExtendedLifetime(_storage) { (_storage: _StorageClass) in - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = _storage._androidDeviceID { - try visitor.visitSingularFixed64Field(value: v, fieldNumber: 1) - } }() - try { if let v = _storage._userPublicKey { - try visitor.visitSingularBytesField(value: v, fieldNumber: 4) - } }() - try { if let v = _storage._deviceModel { - try visitor.visitSingularStringField(value: v, fieldNumber: 7) - } }() - try { if let v = _storage._locale { - try visitor.visitSingularStringField(value: v, fieldNumber: 8) - } }() - try { if let v = _storage._keyHandle { - try visitor.visitSingularBytesField(value: v, fieldNumber: 9) - } }() - try { if let v = _storage._counter { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 12) - } }() - try { if let v = _storage._deviceOsVersion { - try visitor.visitSingularStringField(value: v, fieldNumber: 13) - } }() - try { if let v = _storage._deviceOsVersionCode { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 14) - } }() - try { if let v = _storage._deviceOsRelease { - try visitor.visitSingularStringField(value: v, fieldNumber: 15) - } }() - try { if let v = _storage._deviceOsCodename { - try visitor.visitSingularStringField(value: v, fieldNumber: 16) - } }() - try { if let v = _storage._deviceSoftwareVersion { - try visitor.visitSingularStringField(value: v, fieldNumber: 17) - } }() - try { if let v = _storage._deviceSoftwareVersionCode { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 18) - } }() - try { if let v = _storage._deviceSoftwarePackage { - try visitor.visitSingularStringField(value: v, fieldNumber: 19) - } }() - try { if let v = _storage._deviceDisplayDiagonalMils { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 22) - } }() - try { if let v = _storage._deviceAuthzenVersion { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 24) - } }() - try { if let v = _storage._longDeviceID { - try visitor.visitSingularBytesField(value: v, fieldNumber: 29) - } }() - try { if let v = _storage._deviceManufacturer { - try visitor.visitSingularStringField(value: v, fieldNumber: 31) - } }() - try { if let v = _storage._deviceType { - try visitor.visitSingularEnumField(value: v, fieldNumber: 32) - } }() - try { if let v = _storage._gcmRegistrationID { - try visitor.visitSingularBytesField(value: v, fieldNumber: 102) - } }() - try { if let v = _storage._deviceMasterKeyHash { - try visitor.visitSingularBytesField(value: v, fieldNumber: 103) - } }() - try { if let v = _storage._apnRegistrationID { - try visitor.visitSingularBytesField(value: v, fieldNumber: 202) - } }() - try { if let v = _storage._notificationEnabled { - try visitor.visitSingularBoolField(value: v, fieldNumber: 203) - } }() - try { if let v = _storage._bluetoothMacAddress { - try visitor.visitSingularStringField(value: v, fieldNumber: 302) - } }() - try { if let v = _storage._usingSecureScreenlock { - try visitor.visitSingularBoolField(value: v, fieldNumber: 400) - } }() - try { if let v = _storage._autoUnlockScreenlockSupported { - try visitor.visitSingularBoolField(value: v, fieldNumber: 401) - } }() - try { if let v = _storage._autoUnlockScreenlockEnabled { - try visitor.visitSingularBoolField(value: v, fieldNumber: 402) - } }() - try { if let v = _storage._bluetoothRadioSupported { - try visitor.visitSingularBoolField(value: v, fieldNumber: 403) - } }() - try { if let v = _storage._bluetoothRadioEnabled { - try visitor.visitSingularBoolField(value: v, fieldNumber: 404) - } }() - try { if let v = _storage._mobileDataSupported { - try visitor.visitSingularBoolField(value: v, fieldNumber: 405) - } }() - try { if let v = _storage._tetheringSupported { - try visitor.visitSingularBoolField(value: v, fieldNumber: 406) - } }() - try { if let v = _storage._bleRadioSupported { - try visitor.visitSingularBoolField(value: v, fieldNumber: 407) - } }() - try { if let v = _storage._pixelExperience { - try visitor.visitSingularBoolField(value: v, fieldNumber: 408) - } }() - try { if let v = _storage._arcPlusPlus { - try visitor.visitSingularBoolField(value: v, fieldNumber: 409) - } }() - try { if let v = _storage._isScreenlockStateFlaky { - try visitor.visitSingularBoolField(value: v, fieldNumber: 410) - } }() - if !_storage._supportedSoftwareFeatures.isEmpty { - try visitor.visitRepeatedEnumField(value: _storage._supportedSoftwareFeatures, fieldNumber: 411) - } - if !_storage._enabledSoftwareFeatures.isEmpty { - try visitor.visitRepeatedEnumField(value: _storage._enabledSoftwareFeatures, fieldNumber: 412) - } - try { if let v = _storage._enrollmentSessionID { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1000) - } }() - try { if let v = _storage._oauthToken { - try visitor.visitSingularStringField(value: v, fieldNumber: 1001) - } }() - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_GcmDeviceInfo, rhs: Securegcm_GcmDeviceInfo) -> Bool { - if lhs._storage !== rhs._storage { - let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in - let _storage = _args.0 - let rhs_storage = _args.1 - if _storage._androidDeviceID != rhs_storage._androidDeviceID {return false} - if _storage._gcmRegistrationID != rhs_storage._gcmRegistrationID {return false} - if _storage._apnRegistrationID != rhs_storage._apnRegistrationID {return false} - if _storage._notificationEnabled != rhs_storage._notificationEnabled {return false} - if _storage._bluetoothMacAddress != rhs_storage._bluetoothMacAddress {return false} - if _storage._deviceMasterKeyHash != rhs_storage._deviceMasterKeyHash {return false} - if _storage._userPublicKey != rhs_storage._userPublicKey {return false} - if _storage._deviceModel != rhs_storage._deviceModel {return false} - if _storage._locale != rhs_storage._locale {return false} - if _storage._keyHandle != rhs_storage._keyHandle {return false} - if _storage._counter != rhs_storage._counter {return false} - if _storage._deviceOsVersion != rhs_storage._deviceOsVersion {return false} - if _storage._deviceOsVersionCode != rhs_storage._deviceOsVersionCode {return false} - if _storage._deviceOsRelease != rhs_storage._deviceOsRelease {return false} - if _storage._deviceOsCodename != rhs_storage._deviceOsCodename {return false} - if _storage._deviceSoftwareVersion != rhs_storage._deviceSoftwareVersion {return false} - if _storage._deviceSoftwareVersionCode != rhs_storage._deviceSoftwareVersionCode {return false} - if _storage._deviceSoftwarePackage != rhs_storage._deviceSoftwarePackage {return false} - if _storage._deviceDisplayDiagonalMils != rhs_storage._deviceDisplayDiagonalMils {return false} - if _storage._deviceAuthzenVersion != rhs_storage._deviceAuthzenVersion {return false} - if _storage._longDeviceID != rhs_storage._longDeviceID {return false} - if _storage._deviceManufacturer != rhs_storage._deviceManufacturer {return false} - if _storage._deviceType != rhs_storage._deviceType {return false} - if _storage._usingSecureScreenlock != rhs_storage._usingSecureScreenlock {return false} - if _storage._autoUnlockScreenlockSupported != rhs_storage._autoUnlockScreenlockSupported {return false} - if _storage._autoUnlockScreenlockEnabled != rhs_storage._autoUnlockScreenlockEnabled {return false} - if _storage._bluetoothRadioSupported != rhs_storage._bluetoothRadioSupported {return false} - if _storage._bluetoothRadioEnabled != rhs_storage._bluetoothRadioEnabled {return false} - if _storage._mobileDataSupported != rhs_storage._mobileDataSupported {return false} - if _storage._tetheringSupported != rhs_storage._tetheringSupported {return false} - if _storage._bleRadioSupported != rhs_storage._bleRadioSupported {return false} - if _storage._pixelExperience != rhs_storage._pixelExperience {return false} - if _storage._arcPlusPlus != rhs_storage._arcPlusPlus {return false} - if _storage._isScreenlockStateFlaky != rhs_storage._isScreenlockStateFlaky {return false} - if _storage._supportedSoftwareFeatures != rhs_storage._supportedSoftwareFeatures {return false} - if _storage._enabledSoftwareFeatures != rhs_storage._enabledSoftwareFeatures {return false} - if _storage._enrollmentSessionID != rhs_storage._enrollmentSessionID {return false} - if _storage._oauthToken != rhs_storage._oauthToken {return false} - return true - } - if !storagesAreEqual {return false} - } - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_GcmMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".GcmMetadata" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .same(proto: "version"), - ] - - public var isInitialized: Bool { - if self._type == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self._version) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._version { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_GcmMetadata, rhs: Securegcm_GcmMetadata) -> Bool { - if lhs._type != rhs._type {return false} - if lhs._version != rhs._version {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_Tickle: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Tickle" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "expiry_time"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularFixed64Field(value: &self._expiryTime) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._expiryTime { - try visitor.visitSingularFixed64Field(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_Tickle, rhs: Securegcm_Tickle) -> Bool { - if lhs._expiryTime != rhs._expiryTime {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_LoginNotificationInfo: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".LoginNotificationInfo" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 2: .standard(proto: "creation_time"), - 3: .same(proto: "email"), - 4: .same(proto: "host"), - 5: .same(proto: "source"), - 6: .standard(proto: "event_type"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 2: try { try decoder.decodeSingularFixed64Field(value: &self._creationTime) }() - case 3: try { try decoder.decodeSingularStringField(value: &self._email) }() - case 4: try { try decoder.decodeSingularStringField(value: &self._host) }() - case 5: try { try decoder.decodeSingularStringField(value: &self._source) }() - case 6: try { try decoder.decodeSingularStringField(value: &self._eventType) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._creationTime { - try visitor.visitSingularFixed64Field(value: v, fieldNumber: 2) - } }() - try { if let v = self._email { - try visitor.visitSingularStringField(value: v, fieldNumber: 3) - } }() - try { if let v = self._host { - try visitor.visitSingularStringField(value: v, fieldNumber: 4) - } }() - try { if let v = self._source { - try visitor.visitSingularStringField(value: v, fieldNumber: 5) - } }() - try { if let v = self._eventType { - try visitor.visitSingularStringField(value: v, fieldNumber: 6) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_LoginNotificationInfo, rhs: Securegcm_LoginNotificationInfo) -> Bool { - if lhs._creationTime != rhs._creationTime {return false} - if lhs._email != rhs._email {return false} - if lhs._host != rhs._host {return false} - if lhs._source != rhs._source {return false} - if lhs._eventType != rhs._eventType {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/submissions/sapphire/ProtobufGenerated/securemessage.pb.swift b/submissions/sapphire/ProtobufGenerated/securemessage.pb.swift deleted file mode 100644 index eae8d016..00000000 --- a/submissions/sapphire/ProtobufGenerated/securemessage.pb.swift +++ /dev/null @@ -1,951 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: securemessage.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Proto definitions for SecureMessage format - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that you are building against the same version of the API -// that was used to generate this file. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -/// Supported "signature" schemes (both symmetric key and public key based) -enum Securemessage_SigScheme: SwiftProtobuf.Enum { - typealias RawValue = Int - case hmacSha256 // = 1 - case ecdsaP256Sha256 // = 2 - - /// Not recommended -- use ECDSA_P256_SHA256 instead - case rsa2048Sha256 // = 3 - - init() { - self = .hmacSha256 - } - - init?(rawValue: Int) { - switch rawValue { - case 1: self = .hmacSha256 - case 2: self = .ecdsaP256Sha256 - case 3: self = .rsa2048Sha256 - default: return nil - } - } - - var rawValue: Int { - switch self { - case .hmacSha256: return 1 - case .ecdsaP256Sha256: return 2 - case .rsa2048Sha256: return 3 - } - } - -} - -#if swift(>=4.2) - -extension Securemessage_SigScheme: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// Supported encryption schemes -enum Securemessage_EncScheme: SwiftProtobuf.Enum { - typealias RawValue = Int - - /// No encryption - case none // = 1 - case aes256Cbc // = 2 - - init() { - self = .none - } - - init?(rawValue: Int) { - switch rawValue { - case 1: self = .none - case 2: self = .aes256Cbc - default: return nil - } - } - - var rawValue: Int { - switch self { - case .none: return 1 - case .aes256Cbc: return 2 - } - } - -} - -#if swift(>=4.2) - -extension Securemessage_EncScheme: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// A list of supported public key types -enum Securemessage_PublicKeyType: SwiftProtobuf.Enum { - typealias RawValue = Int - case ecP256 // = 1 - case rsa2048 // = 2 - - /// 2048-bit MODP group 14, from RFC 3526 - case dh2048Modp // = 3 - - init() { - self = .ecP256 - } - - init?(rawValue: Int) { - switch rawValue { - case 1: self = .ecP256 - case 2: self = .rsa2048 - case 3: self = .dh2048Modp - default: return nil - } - } - - var rawValue: Int { - switch self { - case .ecP256: return 1 - case .rsa2048: return 2 - case .dh2048Modp: return 3 - } - } - -} - -#if swift(>=4.2) - -extension Securemessage_PublicKeyType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Securemessage_SecureMessage { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Must contain a HeaderAndBody message - var headerAndBody: Data { - get {return _headerAndBody ?? Data()} - set {_headerAndBody = newValue} - } - /// Returns true if `headerAndBody` has been explicitly set. - var hasHeaderAndBody: Bool {return self._headerAndBody != nil} - /// Clears the value of `headerAndBody`. Subsequent reads from it will return its default value. - mutating func clearHeaderAndBody() {self._headerAndBody = nil} - - /// Signature of header_and_body - var signature: Data { - get {return _signature ?? Data()} - set {_signature = newValue} - } - /// Returns true if `signature` has been explicitly set. - var hasSignature: Bool {return self._signature != nil} - /// Clears the value of `signature`. Subsequent reads from it will return its default value. - mutating func clearSignature() {self._signature = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _headerAndBody: Data? = nil - fileprivate var _signature: Data? = nil -} - -struct Securemessage_Header { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var signatureScheme: Securemessage_SigScheme { - get {return _signatureScheme ?? .hmacSha256} - set {_signatureScheme = newValue} - } - /// Returns true if `signatureScheme` has been explicitly set. - var hasSignatureScheme: Bool {return self._signatureScheme != nil} - /// Clears the value of `signatureScheme`. Subsequent reads from it will return its default value. - mutating func clearSignatureScheme() {self._signatureScheme = nil} - - var encryptionScheme: Securemessage_EncScheme { - get {return _encryptionScheme ?? .none} - set {_encryptionScheme = newValue} - } - /// Returns true if `encryptionScheme` has been explicitly set. - var hasEncryptionScheme: Bool {return self._encryptionScheme != nil} - /// Clears the value of `encryptionScheme`. Subsequent reads from it will return its default value. - mutating func clearEncryptionScheme() {self._encryptionScheme = nil} - - /// Identifies the verification key - var verificationKeyID: Data { - get {return _verificationKeyID ?? Data()} - set {_verificationKeyID = newValue} - } - /// Returns true if `verificationKeyID` has been explicitly set. - var hasVerificationKeyID: Bool {return self._verificationKeyID != nil} - /// Clears the value of `verificationKeyID`. Subsequent reads from it will return its default value. - mutating func clearVerificationKeyID() {self._verificationKeyID = nil} - - /// Identifies the decryption key - var decryptionKeyID: Data { - get {return _decryptionKeyID ?? Data()} - set {_decryptionKeyID = newValue} - } - /// Returns true if `decryptionKeyID` has been explicitly set. - var hasDecryptionKeyID: Bool {return self._decryptionKeyID != nil} - /// Clears the value of `decryptionKeyID`. Subsequent reads from it will return its default value. - mutating func clearDecryptionKeyID() {self._decryptionKeyID = nil} - - /// Encryption may use an IV - var iv: Data { - get {return _iv ?? Data()} - set {_iv = newValue} - } - /// Returns true if `iv` has been explicitly set. - var hasIv: Bool {return self._iv != nil} - /// Clears the value of `iv`. Subsequent reads from it will return its default value. - mutating func clearIv() {self._iv = nil} - - /// Arbitrary per-protocol public data, to be sent with the plain-text header - var publicMetadata: Data { - get {return _publicMetadata ?? Data()} - set {_publicMetadata = newValue} - } - /// Returns true if `publicMetadata` has been explicitly set. - var hasPublicMetadata: Bool {return self._publicMetadata != nil} - /// Clears the value of `publicMetadata`. Subsequent reads from it will return its default value. - mutating func clearPublicMetadata() {self._publicMetadata = nil} - - /// The length of some associated data this is not sent in this SecureMessage, - /// but which will be bound to the signature. - var associatedDataLength: UInt32 { - get {return _associatedDataLength ?? 0} - set {_associatedDataLength = newValue} - } - /// Returns true if `associatedDataLength` has been explicitly set. - var hasAssociatedDataLength: Bool {return self._associatedDataLength != nil} - /// Clears the value of `associatedDataLength`. Subsequent reads from it will return its default value. - mutating func clearAssociatedDataLength() {self._associatedDataLength = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _signatureScheme: Securemessage_SigScheme? = nil - fileprivate var _encryptionScheme: Securemessage_EncScheme? = nil - fileprivate var _verificationKeyID: Data? = nil - fileprivate var _decryptionKeyID: Data? = nil - fileprivate var _iv: Data? = nil - fileprivate var _publicMetadata: Data? = nil - fileprivate var _associatedDataLength: UInt32? = nil -} - -struct Securemessage_HeaderAndBody { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Public data about this message (to be bound in the signature) - var header: Securemessage_Header { - get {return _header ?? Securemessage_Header()} - set {_header = newValue} - } - /// Returns true if `header` has been explicitly set. - var hasHeader: Bool {return self._header != nil} - /// Clears the value of `header`. Subsequent reads from it will return its default value. - mutating func clearHeader() {self._header = nil} - - /// Payload data - var body: Data { - get {return _body ?? Data()} - set {_body = newValue} - } - /// Returns true if `body` has been explicitly set. - var hasBody: Bool {return self._body != nil} - /// Clears the value of `body`. Subsequent reads from it will return its default value. - mutating func clearBody() {self._body = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _header: Securemessage_Header? = nil - fileprivate var _body: Data? = nil -} - -/// Must be kept wire-format compatible with HeaderAndBody. Provides the -/// SecureMessage code with a consistent wire-format representation that -/// remains stable irrespective of protobuf implementation choices. This -/// low-level representation of a HeaderAndBody should not be used by -/// any code outside of the SecureMessage library implementation/tests. -struct Securemessage_HeaderAndBodyInternal { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// A raw (wire-format) byte encoding of a Header, suitable for hashing - var header: Data { - get {return _header ?? Data()} - set {_header = newValue} - } - /// Returns true if `header` has been explicitly set. - var hasHeader: Bool {return self._header != nil} - /// Clears the value of `header`. Subsequent reads from it will return its default value. - mutating func clearHeader() {self._header = nil} - - /// Payload data - var body: Data { - get {return _body ?? Data()} - set {_body = newValue} - } - /// Returns true if `body` has been explicitly set. - var hasBody: Bool {return self._body != nil} - /// Clears the value of `body`. Subsequent reads from it will return its default value. - mutating func clearBody() {self._body = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _header: Data? = nil - fileprivate var _body: Data? = nil -} - -/// A convenience proto for encoding NIST P-256 elliptic curve public keys -struct Securemessage_EcP256PublicKey { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// x and y are encoded in big-endian two's complement (slightly wasteful) - /// Client MUST verify (x,y) is a valid point on NIST P256 - var x: Data { - get {return _x ?? Data()} - set {_x = newValue} - } - /// Returns true if `x` has been explicitly set. - var hasX: Bool {return self._x != nil} - /// Clears the value of `x`. Subsequent reads from it will return its default value. - mutating func clearX() {self._x = nil} - - var y: Data { - get {return _y ?? Data()} - set {_y = newValue} - } - /// Returns true if `y` has been explicitly set. - var hasY: Bool {return self._y != nil} - /// Clears the value of `y`. Subsequent reads from it will return its default value. - mutating func clearY() {self._y = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _x: Data? = nil - fileprivate var _y: Data? = nil -} - -/// A convenience proto for encoding RSA public keys with small exponents -struct Securemessage_SimpleRsaPublicKey { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Encoded in big-endian two's complement - var n: Data { - get {return _n ?? Data()} - set {_n = newValue} - } - /// Returns true if `n` has been explicitly set. - var hasN: Bool {return self._n != nil} - /// Clears the value of `n`. Subsequent reads from it will return its default value. - mutating func clearN() {self._n = nil} - - var e: Int32 { - get {return _e ?? 65537} - set {_e = newValue} - } - /// Returns true if `e` has been explicitly set. - var hasE: Bool {return self._e != nil} - /// Clears the value of `e`. Subsequent reads from it will return its default value. - mutating func clearE() {self._e = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _n: Data? = nil - fileprivate var _e: Int32? = nil -} - -/// A convenience proto for encoding Diffie-Hellman public keys, -/// for use only when Elliptic Curve based key exchanges are not possible. -/// (Note that the group parameters must be specified separately) -struct Securemessage_DhPublicKey { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Big-endian two's complement encoded group element - var y: Data { - get {return _y ?? Data()} - set {_y = newValue} - } - /// Returns true if `y` has been explicitly set. - var hasY: Bool {return self._y != nil} - /// Clears the value of `y`. Subsequent reads from it will return its default value. - mutating func clearY() {self._y = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _y: Data? = nil -} - -struct Securemessage_GenericPublicKey { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var type: Securemessage_PublicKeyType { - get {return _type ?? .ecP256} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - var ecP256PublicKey: Securemessage_EcP256PublicKey { - get {return _ecP256PublicKey ?? Securemessage_EcP256PublicKey()} - set {_ecP256PublicKey = newValue} - } - /// Returns true if `ecP256PublicKey` has been explicitly set. - var hasEcP256PublicKey: Bool {return self._ecP256PublicKey != nil} - /// Clears the value of `ecP256PublicKey`. Subsequent reads from it will return its default value. - mutating func clearEcP256PublicKey() {self._ecP256PublicKey = nil} - - var rsa2048PublicKey: Securemessage_SimpleRsaPublicKey { - get {return _rsa2048PublicKey ?? Securemessage_SimpleRsaPublicKey()} - set {_rsa2048PublicKey = newValue} - } - /// Returns true if `rsa2048PublicKey` has been explicitly set. - var hasRsa2048PublicKey: Bool {return self._rsa2048PublicKey != nil} - /// Clears the value of `rsa2048PublicKey`. Subsequent reads from it will return its default value. - mutating func clearRsa2048PublicKey() {self._rsa2048PublicKey = nil} - - /// Use only as a last resort - var dh2048PublicKey: Securemessage_DhPublicKey { - get {return _dh2048PublicKey ?? Securemessage_DhPublicKey()} - set {_dh2048PublicKey = newValue} - } - /// Returns true if `dh2048PublicKey` has been explicitly set. - var hasDh2048PublicKey: Bool {return self._dh2048PublicKey != nil} - /// Clears the value of `dh2048PublicKey`. Subsequent reads from it will return its default value. - mutating func clearDh2048PublicKey() {self._dh2048PublicKey = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _type: Securemessage_PublicKeyType? = nil - fileprivate var _ecP256PublicKey: Securemessage_EcP256PublicKey? = nil - fileprivate var _rsa2048PublicKey: Securemessage_SimpleRsaPublicKey? = nil - fileprivate var _dh2048PublicKey: Securemessage_DhPublicKey? = nil -} - -#if swift(>=5.5) && canImport(_Concurrency) -extension Securemessage_SigScheme: @unchecked Sendable {} -extension Securemessage_EncScheme: @unchecked Sendable {} -extension Securemessage_PublicKeyType: @unchecked Sendable {} -extension Securemessage_SecureMessage: @unchecked Sendable {} -extension Securemessage_Header: @unchecked Sendable {} -extension Securemessage_HeaderAndBody: @unchecked Sendable {} -extension Securemessage_HeaderAndBodyInternal: @unchecked Sendable {} -extension Securemessage_EcP256PublicKey: @unchecked Sendable {} -extension Securemessage_SimpleRsaPublicKey: @unchecked Sendable {} -extension Securemessage_DhPublicKey: @unchecked Sendable {} -extension Securemessage_GenericPublicKey: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "securemessage" - -extension Securemessage_SigScheme: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "HMAC_SHA256"), - 2: .same(proto: "ECDSA_P256_SHA256"), - 3: .same(proto: "RSA2048_SHA256"), - ] -} - -extension Securemessage_EncScheme: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "NONE"), - 2: .same(proto: "AES_256_CBC"), - ] -} - -extension Securemessage_PublicKeyType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "EC_P256"), - 2: .same(proto: "RSA2048"), - 3: .same(proto: "DH2048_MODP"), - ] -} - -extension Securemessage_SecureMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".SecureMessage" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "header_and_body"), - 2: .same(proto: "signature"), - ] - - public var isInitialized: Bool { - if self._headerAndBody == nil {return false} - if self._signature == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._headerAndBody) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._signature) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._headerAndBody { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._signature { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_SecureMessage, rhs: Securemessage_SecureMessage) -> Bool { - if lhs._headerAndBody != rhs._headerAndBody {return false} - if lhs._signature != rhs._signature {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securemessage_Header: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Header" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "signature_scheme"), - 2: .standard(proto: "encryption_scheme"), - 3: .standard(proto: "verification_key_id"), - 4: .standard(proto: "decryption_key_id"), - 5: .same(proto: "iv"), - 6: .standard(proto: "public_metadata"), - 7: .standard(proto: "associated_data_length"), - ] - - public var isInitialized: Bool { - if self._signatureScheme == nil {return false} - if self._encryptionScheme == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._signatureScheme) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self._encryptionScheme) }() - case 3: try { try decoder.decodeSingularBytesField(value: &self._verificationKeyID) }() - case 4: try { try decoder.decodeSingularBytesField(value: &self._decryptionKeyID) }() - case 5: try { try decoder.decodeSingularBytesField(value: &self._iv) }() - case 6: try { try decoder.decodeSingularBytesField(value: &self._publicMetadata) }() - case 7: try { try decoder.decodeSingularUInt32Field(value: &self._associatedDataLength) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._signatureScheme { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._encryptionScheme { - try visitor.visitSingularEnumField(value: v, fieldNumber: 2) - } }() - try { if let v = self._verificationKeyID { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try { if let v = self._decryptionKeyID { - try visitor.visitSingularBytesField(value: v, fieldNumber: 4) - } }() - try { if let v = self._iv { - try visitor.visitSingularBytesField(value: v, fieldNumber: 5) - } }() - try { if let v = self._publicMetadata { - try visitor.visitSingularBytesField(value: v, fieldNumber: 6) - } }() - try { if let v = self._associatedDataLength { - try visitor.visitSingularUInt32Field(value: v, fieldNumber: 7) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_Header, rhs: Securemessage_Header) -> Bool { - if lhs._signatureScheme != rhs._signatureScheme {return false} - if lhs._encryptionScheme != rhs._encryptionScheme {return false} - if lhs._verificationKeyID != rhs._verificationKeyID {return false} - if lhs._decryptionKeyID != rhs._decryptionKeyID {return false} - if lhs._iv != rhs._iv {return false} - if lhs._publicMetadata != rhs._publicMetadata {return false} - if lhs._associatedDataLength != rhs._associatedDataLength {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securemessage_HeaderAndBody: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".HeaderAndBody" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "header"), - 2: .same(proto: "body"), - ] - - public var isInitialized: Bool { - if self._header == nil {return false} - if self._body == nil {return false} - if let v = self._header, !v.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularMessageField(value: &self._header) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._body) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._header { - try visitor.visitSingularMessageField(value: v, fieldNumber: 1) - } }() - try { if let v = self._body { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_HeaderAndBody, rhs: Securemessage_HeaderAndBody) -> Bool { - if lhs._header != rhs._header {return false} - if lhs._body != rhs._body {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securemessage_HeaderAndBodyInternal: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".HeaderAndBodyInternal" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "header"), - 2: .same(proto: "body"), - ] - - public var isInitialized: Bool { - if self._header == nil {return false} - if self._body == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._header) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._body) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._header { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._body { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_HeaderAndBodyInternal, rhs: Securemessage_HeaderAndBodyInternal) -> Bool { - if lhs._header != rhs._header {return false} - if lhs._body != rhs._body {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securemessage_EcP256PublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".EcP256PublicKey" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "x"), - 2: .same(proto: "y"), - ] - - public var isInitialized: Bool { - if self._x == nil {return false} - if self._y == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._x) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._y) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._x { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._y { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_EcP256PublicKey, rhs: Securemessage_EcP256PublicKey) -> Bool { - if lhs._x != rhs._x {return false} - if lhs._y != rhs._y {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securemessage_SimpleRsaPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".SimpleRsaPublicKey" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "n"), - 2: .same(proto: "e"), - ] - - public var isInitialized: Bool { - if self._n == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._n) }() - case 2: try { try decoder.decodeSingularInt32Field(value: &self._e) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._n { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._e { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_SimpleRsaPublicKey, rhs: Securemessage_SimpleRsaPublicKey) -> Bool { - if lhs._n != rhs._n {return false} - if lhs._e != rhs._e {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securemessage_DhPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".DhPublicKey" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "y"), - ] - - public var isInitialized: Bool { - if self._y == nil {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._y) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._y { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_DhPublicKey, rhs: Securemessage_DhPublicKey) -> Bool { - if lhs._y != rhs._y {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securemessage_GenericPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".GenericPublicKey" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .standard(proto: "ec_p256_public_key"), - 3: .standard(proto: "rsa2048_public_key"), - 4: .standard(proto: "dh2048_public_key"), - ] - - public var isInitialized: Bool { - if self._type == nil {return false} - if let v = self._ecP256PublicKey, !v.isInitialized {return false} - if let v = self._rsa2048PublicKey, !v.isInitialized {return false} - if let v = self._dh2048PublicKey, !v.isInitialized {return false} - return true - } - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._ecP256PublicKey) }() - case 3: try { try decoder.decodeSingularMessageField(value: &self._rsa2048PublicKey) }() - case 4: try { try decoder.decodeSingularMessageField(value: &self._dh2048PublicKey) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._ecP256PublicKey { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._rsa2048PublicKey { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() - try { if let v = self._dh2048PublicKey { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securemessage_GenericPublicKey, rhs: Securemessage_GenericPublicKey) -> Bool { - if lhs._type != rhs._type {return false} - if lhs._ecP256PublicKey != rhs._ecP256PublicKey {return false} - if lhs._rsa2048PublicKey != rhs._rsa2048PublicKey {return false} - if lhs._dh2048PublicKey != rhs._dh2048PublicKey {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/submissions/sapphire/ProtobufGenerated/ukey.pb.swift b/submissions/sapphire/ProtobufGenerated/ukey.pb.swift deleted file mode 100644 index 3cbbf2b6..00000000 --- a/submissions/sapphire/ProtobufGenerated/ukey.pb.swift +++ /dev/null @@ -1,735 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: ukey.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that you are building against the same version of the API -// that was used to generate this file. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -enum Securegcm_Ukey2HandshakeCipher: SwiftProtobuf.Enum { - typealias RawValue = Int - case reserved // = 0 - - /// NIST P-256 used for ECDH, SHA512 used for - case p256Sha512 // = 100 - - /// commitment - case curve25519Sha512 // = 200 - - init() { - self = .reserved - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .reserved - case 100: self = .p256Sha512 - case 200: self = .curve25519Sha512 - default: return nil - } - } - - var rawValue: Int { - switch self { - case .reserved: return 0 - case .p256Sha512: return 100 - case .curve25519Sha512: return 200 - } - } - -} - -#if swift(>=4.2) - -extension Securegcm_Ukey2HandshakeCipher: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Securegcm_Ukey2Message { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Identifies message type - var messageType: Securegcm_Ukey2Message.TypeEnum { - get {return _messageType ?? .unknownDoNotUse} - set {_messageType = newValue} - } - /// Returns true if `messageType` has been explicitly set. - var hasMessageType: Bool {return self._messageType != nil} - /// Clears the value of `messageType`. Subsequent reads from it will return its default value. - mutating func clearMessageType() {self._messageType = nil} - - /// Actual message, to be parsed according to - var messageData: Data { - get {return _messageData ?? Data()} - set {_messageData = newValue} - } - /// Returns true if `messageData` has been explicitly set. - var hasMessageData: Bool {return self._messageData != nil} - /// Clears the value of `messageData`. Subsequent reads from it will return its default value. - mutating func clearMessageData() {self._messageData = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum TypeEnum: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownDoNotUse // = 0 - case alert // = 1 - case clientInit // = 2 - case serverInit // = 3 - case clientFinish // = 4 - - init() { - self = .unknownDoNotUse - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownDoNotUse - case 1: self = .alert - case 2: self = .clientInit - case 3: self = .serverInit - case 4: self = .clientFinish - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownDoNotUse: return 0 - case .alert: return 1 - case .clientInit: return 2 - case .serverInit: return 3 - case .clientFinish: return 4 - } - } - - } - - init() {} - - fileprivate var _messageType: Securegcm_Ukey2Message.TypeEnum? = nil - fileprivate var _messageData: Data? = nil -} - -#if swift(>=4.2) - -extension Securegcm_Ukey2Message.TypeEnum: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Securegcm_Ukey2Alert { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var type: Securegcm_Ukey2Alert.AlertType { - get {return _type ?? .badMessage} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - var errorMessage: String { - get {return _errorMessage ?? String()} - set {_errorMessage = newValue} - } - /// Returns true if `errorMessage` has been explicitly set. - var hasErrorMessage: Bool {return self._errorMessage != nil} - /// Clears the value of `errorMessage`. Subsequent reads from it will return its default value. - mutating func clearErrorMessage() {self._errorMessage = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum AlertType: SwiftProtobuf.Enum { - typealias RawValue = Int - - /// Framing errors - case badMessage // = 1 - - /// message_type has an undefined value - case badMessageType // = 2 - - /// message_type received does not correspond to - case incorrectMessage // = 3 - - /// expected type at this stage of the protocol - case badMessageData // = 4 - - /// ClientInit and ServerInit errors - case badVersion // = 100 - - /// suitable version to speak with client. - case badRandom // = 101 - - /// length - case badHandshakeCipher // = 102 - - /// The next protocol is missing, unknown, or - case badNextProtocol // = 103 - - /// unsupported - case badPublicKey // = 104 - - /// Other errors - case internalError // = 200 - - init() { - self = .badMessage - } - - init?(rawValue: Int) { - switch rawValue { - case 1: self = .badMessage - case 2: self = .badMessageType - case 3: self = .incorrectMessage - case 4: self = .badMessageData - case 100: self = .badVersion - case 101: self = .badRandom - case 102: self = .badHandshakeCipher - case 103: self = .badNextProtocol - case 104: self = .badPublicKey - case 200: self = .internalError - default: return nil - } - } - - var rawValue: Int { - switch self { - case .badMessage: return 1 - case .badMessageType: return 2 - case .incorrectMessage: return 3 - case .badMessageData: return 4 - case .badVersion: return 100 - case .badRandom: return 101 - case .badHandshakeCipher: return 102 - case .badNextProtocol: return 103 - case .badPublicKey: return 104 - case .internalError: return 200 - } - } - - } - - init() {} - - fileprivate var _type: Securegcm_Ukey2Alert.AlertType? = nil - fileprivate var _errorMessage: String? = nil -} - -#if swift(>=4.2) - -extension Securegcm_Ukey2Alert.AlertType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -struct Securegcm_Ukey2ClientInit { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// highest supported version for rollback - var version: Int32 { - get {return _version ?? 0} - set {_version = newValue} - } - /// Returns true if `version` has been explicitly set. - var hasVersion: Bool {return self._version != nil} - /// Clears the value of `version`. Subsequent reads from it will return its default value. - mutating func clearVersion() {self._version = nil} - - /// protection - var random: Data { - get {return _random ?? Data()} - set {_random = newValue} - } - /// Returns true if `random` has been explicitly set. - var hasRandom: Bool {return self._random != nil} - /// Clears the value of `random`. Subsequent reads from it will return its default value. - mutating func clearRandom() {self._random = nil} - - var cipherCommitments: [Securegcm_Ukey2ClientInit.CipherCommitment] = [] - - /// Next protocol that the client wants to speak. - var nextProtocol: String { - get {return _nextProtocol ?? String()} - set {_nextProtocol = newValue} - } - /// Returns true if `nextProtocol` has been explicitly set. - var hasNextProtocol: Bool {return self._nextProtocol != nil} - /// Clears the value of `nextProtocol`. Subsequent reads from it will return its default value. - mutating func clearNextProtocol() {self._nextProtocol = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - /// One commitment (hash of ClientFinished containing public key) per supported - /// cipher - struct CipherCommitment { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var handshakeCipher: Securegcm_Ukey2HandshakeCipher { - get {return _handshakeCipher ?? .reserved} - set {_handshakeCipher = newValue} - } - /// Returns true if `handshakeCipher` has been explicitly set. - var hasHandshakeCipher: Bool {return self._handshakeCipher != nil} - /// Clears the value of `handshakeCipher`. Subsequent reads from it will return its default value. - mutating func clearHandshakeCipher() {self._handshakeCipher = nil} - - var commitment: Data { - get {return _commitment ?? Data()} - set {_commitment = newValue} - } - /// Returns true if `commitment` has been explicitly set. - var hasCommitment: Bool {return self._commitment != nil} - /// Clears the value of `commitment`. Subsequent reads from it will return its default value. - mutating func clearCommitment() {self._commitment = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _handshakeCipher: Securegcm_Ukey2HandshakeCipher? = nil - fileprivate var _commitment: Data? = nil - } - - init() {} - - fileprivate var _version: Int32? = nil - fileprivate var _random: Data? = nil - fileprivate var _nextProtocol: String? = nil -} - -struct Securegcm_Ukey2ServerInit { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// highest supported version for rollback - var version: Int32 { - get {return _version ?? 0} - set {_version = newValue} - } - /// Returns true if `version` has been explicitly set. - var hasVersion: Bool {return self._version != nil} - /// Clears the value of `version`. Subsequent reads from it will return its default value. - mutating func clearVersion() {self._version = nil} - - /// protection - var random: Data { - get {return _random ?? Data()} - set {_random = newValue} - } - /// Returns true if `random` has been explicitly set. - var hasRandom: Bool {return self._random != nil} - /// Clears the value of `random`. Subsequent reads from it will return its default value. - mutating func clearRandom() {self._random = nil} - - /// Selected Cipher and corresponding public key - var handshakeCipher: Securegcm_Ukey2HandshakeCipher { - get {return _handshakeCipher ?? .reserved} - set {_handshakeCipher = newValue} - } - /// Returns true if `handshakeCipher` has been explicitly set. - var hasHandshakeCipher: Bool {return self._handshakeCipher != nil} - /// Clears the value of `handshakeCipher`. Subsequent reads from it will return its default value. - mutating func clearHandshakeCipher() {self._handshakeCipher = nil} - - var publicKey: Data { - get {return _publicKey ?? Data()} - set {_publicKey = newValue} - } - /// Returns true if `publicKey` has been explicitly set. - var hasPublicKey: Bool {return self._publicKey != nil} - /// Clears the value of `publicKey`. Subsequent reads from it will return its default value. - mutating func clearPublicKey() {self._publicKey = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _version: Int32? = nil - fileprivate var _random: Data? = nil - fileprivate var _handshakeCipher: Securegcm_Ukey2HandshakeCipher? = nil - fileprivate var _publicKey: Data? = nil -} - -struct Securegcm_Ukey2ClientFinished { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// public key matching selected handshake - var publicKey: Data { - get {return _publicKey ?? Data()} - set {_publicKey = newValue} - } - /// Returns true if `publicKey` has been explicitly set. - var hasPublicKey: Bool {return self._publicKey != nil} - /// Clears the value of `publicKey`. Subsequent reads from it will return its default value. - mutating func clearPublicKey() {self._publicKey = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _publicKey: Data? = nil -} - -#if swift(>=5.5) && canImport(_Concurrency) -extension Securegcm_Ukey2HandshakeCipher: @unchecked Sendable {} -extension Securegcm_Ukey2Message: @unchecked Sendable {} -extension Securegcm_Ukey2Message.TypeEnum: @unchecked Sendable {} -extension Securegcm_Ukey2Alert: @unchecked Sendable {} -extension Securegcm_Ukey2Alert.AlertType: @unchecked Sendable {} -extension Securegcm_Ukey2ClientInit: @unchecked Sendable {} -extension Securegcm_Ukey2ClientInit.CipherCommitment: @unchecked Sendable {} -extension Securegcm_Ukey2ServerInit: @unchecked Sendable {} -extension Securegcm_Ukey2ClientFinished: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "securegcm" - -extension Securegcm_Ukey2HandshakeCipher: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "RESERVED"), - 100: .same(proto: "P256_SHA512"), - 200: .same(proto: "CURVE25519_SHA512"), - ] -} - -extension Securegcm_Ukey2Message: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Ukey2Message" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "message_type"), - 2: .standard(proto: "message_data"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._messageType) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._messageData) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._messageType { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._messageData { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_Ukey2Message, rhs: Securegcm_Ukey2Message) -> Bool { - if lhs._messageType != rhs._messageType {return false} - if lhs._messageData != rhs._messageData {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_Ukey2Message.TypeEnum: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_DO_NOT_USE"), - 1: .same(proto: "ALERT"), - 2: .same(proto: "CLIENT_INIT"), - 3: .same(proto: "SERVER_INIT"), - 4: .same(proto: "CLIENT_FINISH"), - ] -} - -extension Securegcm_Ukey2Alert: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Ukey2Alert" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .standard(proto: "error_message"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() - case 2: try { try decoder.decodeSingularStringField(value: &self._errorMessage) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._errorMessage { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_Ukey2Alert, rhs: Securegcm_Ukey2Alert) -> Bool { - if lhs._type != rhs._type {return false} - if lhs._errorMessage != rhs._errorMessage {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_Ukey2Alert.AlertType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "BAD_MESSAGE"), - 2: .same(proto: "BAD_MESSAGE_TYPE"), - 3: .same(proto: "INCORRECT_MESSAGE"), - 4: .same(proto: "BAD_MESSAGE_DATA"), - 100: .same(proto: "BAD_VERSION"), - 101: .same(proto: "BAD_RANDOM"), - 102: .same(proto: "BAD_HANDSHAKE_CIPHER"), - 103: .same(proto: "BAD_NEXT_PROTOCOL"), - 104: .same(proto: "BAD_PUBLIC_KEY"), - 200: .same(proto: "INTERNAL_ERROR"), - ] -} - -extension Securegcm_Ukey2ClientInit: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Ukey2ClientInit" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "version"), - 2: .same(proto: "random"), - 3: .standard(proto: "cipher_commitments"), - 4: .standard(proto: "next_protocol"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularInt32Field(value: &self._version) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._random) }() - case 3: try { try decoder.decodeRepeatedMessageField(value: &self.cipherCommitments) }() - case 4: try { try decoder.decodeSingularStringField(value: &self._nextProtocol) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._version { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) - } }() - try { if let v = self._random { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - if !self.cipherCommitments.isEmpty { - try visitor.visitRepeatedMessageField(value: self.cipherCommitments, fieldNumber: 3) - } - try { if let v = self._nextProtocol { - try visitor.visitSingularStringField(value: v, fieldNumber: 4) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_Ukey2ClientInit, rhs: Securegcm_Ukey2ClientInit) -> Bool { - if lhs._version != rhs._version {return false} - if lhs._random != rhs._random {return false} - if lhs.cipherCommitments != rhs.cipherCommitments {return false} - if lhs._nextProtocol != rhs._nextProtocol {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_Ukey2ClientInit.CipherCommitment: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = Securegcm_Ukey2ClientInit.protoMessageName + ".CipherCommitment" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "handshake_cipher"), - 2: .same(proto: "commitment"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._handshakeCipher) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._commitment) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._handshakeCipher { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._commitment { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_Ukey2ClientInit.CipherCommitment, rhs: Securegcm_Ukey2ClientInit.CipherCommitment) -> Bool { - if lhs._handshakeCipher != rhs._handshakeCipher {return false} - if lhs._commitment != rhs._commitment {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_Ukey2ServerInit: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Ukey2ServerInit" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "version"), - 2: .same(proto: "random"), - 3: .standard(proto: "handshake_cipher"), - 4: .standard(proto: "public_key"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularInt32Field(value: &self._version) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._random) }() - case 3: try { try decoder.decodeSingularEnumField(value: &self._handshakeCipher) }() - case 4: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._version { - try visitor.visitSingularInt32Field(value: v, fieldNumber: 1) - } }() - try { if let v = self._random { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try { if let v = self._handshakeCipher { - try visitor.visitSingularEnumField(value: v, fieldNumber: 3) - } }() - try { if let v = self._publicKey { - try visitor.visitSingularBytesField(value: v, fieldNumber: 4) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_Ukey2ServerInit, rhs: Securegcm_Ukey2ServerInit) -> Bool { - if lhs._version != rhs._version {return false} - if lhs._random != rhs._random {return false} - if lhs._handshakeCipher != rhs._handshakeCipher {return false} - if lhs._publicKey != rhs._publicKey {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Securegcm_Ukey2ClientFinished: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Ukey2ClientFinished" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "public_key"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._publicKey { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Securegcm_Ukey2ClientFinished, rhs: Securegcm_Ukey2ClientFinished) -> Bool { - if lhs._publicKey != rhs._publicKey {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} diff --git a/submissions/sapphire/ProtobufGenerated/wire_format.pb.swift b/submissions/sapphire/ProtobufGenerated/wire_format.pb.swift deleted file mode 100644 index d8c5bd04..00000000 --- a/submissions/sapphire/ProtobufGenerated/wire_format.pb.swift +++ /dev/null @@ -1,1617 +0,0 @@ -// DO NOT EDIT. -// swift-format-ignore-file -// -// Generated by the Swift generator plugin for the protocol buffer compiler. -// Source: wire_format.proto -// -// For information on using the generated types, please see the documentation: -// https://github.com/apple/swift-protobuf/ - -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Brought from: //depot/google3/location/nearby/sharing/proto/wire_format.proto -// At CL 317565061 - -import Foundation -import SwiftProtobuf - -// If the compiler emits an error on this type, it is because this file -// was generated by a version of the `protoc` Swift plug-in that is -// incompatible with the version of SwiftProtobuf to which you are linking. -// Please ensure that you are building against the same version of the API -// that was used to generate this file. -fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck { - struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {} - typealias Version = _2 -} - -/// File metadata. Does not include the actual bytes of the file. -/// NEXT_ID=6 -struct Sharing_Nearby_FileMetadata { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The human readable name of this file (eg. 'Cookbook.pdf'). - var name: String { - get {return _name ?? String()} - set {_name = newValue} - } - /// Returns true if `name` has been explicitly set. - var hasName: Bool {return self._name != nil} - /// Clears the value of `name`. Subsequent reads from it will return its default value. - mutating func clearName() {self._name = nil} - - /// The type of file (eg. 'IMAGE' from 'dog.jpg'). Specifying a type helps - /// provide a richer experience on the receiving side. - var type: Sharing_Nearby_FileMetadata.TypeEnum { - get {return _type ?? .unknown} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - /// The FILE payload id that will be sent as a follow up containing the actual - /// bytes of the file. - var payloadID: Int64 { - get {return _payloadID ?? 0} - set {_payloadID = newValue} - } - /// Returns true if `payloadID` has been explicitly set. - var hasPayloadID: Bool {return self._payloadID != nil} - /// Clears the value of `payloadID`. Subsequent reads from it will return its default value. - mutating func clearPayloadID() {self._payloadID = nil} - - /// The total size of the file. - var size: Int64 { - get {return _size ?? 0} - set {_size = newValue} - } - /// Returns true if `size` has been explicitly set. - var hasSize: Bool {return self._size != nil} - /// Clears the value of `size`. Subsequent reads from it will return its default value. - mutating func clearSize() {self._size = nil} - - /// The mimeType of file (eg. 'image/jpeg' from 'dog.jpg'). Specifying a - /// mimeType helps provide a richer experience on receiving side. - var mimeType: String { - get {return _mimeType ?? "application/octet-stream"} - set {_mimeType = newValue} - } - /// Returns true if `mimeType` has been explicitly set. - var hasMimeType: Bool {return self._mimeType != nil} - /// Clears the value of `mimeType`. Subsequent reads from it will return its default value. - mutating func clearMimeType() {self._mimeType = nil} - - /// A uuid for the attachment. Should be unique across all attachments. - var id: Int64 { - get {return _id ?? 0} - set {_id = newValue} - } - /// Returns true if `id` has been explicitly set. - var hasID: Bool {return self._id != nil} - /// Clears the value of `id`. Subsequent reads from it will return its default value. - mutating func clearID() {self._id = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum TypeEnum: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknown // = 0 - case image // = 1 - case video // = 2 - case app // = 3 - case audio // = 4 - - init() { - self = .unknown - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknown - case 1: self = .image - case 2: self = .video - case 3: self = .app - case 4: self = .audio - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknown: return 0 - case .image: return 1 - case .video: return 2 - case .app: return 3 - case .audio: return 4 - } - } - - } - - init() {} - - fileprivate var _name: String? = nil - fileprivate var _type: Sharing_Nearby_FileMetadata.TypeEnum? = nil - fileprivate var _payloadID: Int64? = nil - fileprivate var _size: Int64? = nil - fileprivate var _mimeType: String? = nil - fileprivate var _id: Int64? = nil -} - -#if swift(>=4.2) - -extension Sharing_Nearby_FileMetadata.TypeEnum: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// NEXT_ID=5 -struct Sharing_Nearby_TextMetadata { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The title of the text content. - var textTitle: String { - get {return _textTitle ?? String()} - set {_textTitle = newValue} - } - /// Returns true if `textTitle` has been explicitly set. - var hasTextTitle: Bool {return self._textTitle != nil} - /// Clears the value of `textTitle`. Subsequent reads from it will return its default value. - mutating func clearTextTitle() {self._textTitle = nil} - - /// The type of text (phone number, url, address, or plain text). - var type: Sharing_Nearby_TextMetadata.TypeEnum { - get {return _type ?? .unknown} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - /// The BYTE payload id that will be sent as a follow up containing the actual - /// bytes of the text. - var payloadID: Int64 { - get {return _payloadID ?? 0} - set {_payloadID = newValue} - } - /// Returns true if `payloadID` has been explicitly set. - var hasPayloadID: Bool {return self._payloadID != nil} - /// Clears the value of `payloadID`. Subsequent reads from it will return its default value. - mutating func clearPayloadID() {self._payloadID = nil} - - /// The size of the text content. - var size: Int64 { - get {return _size ?? 0} - set {_size = newValue} - } - /// Returns true if `size` has been explicitly set. - var hasSize: Bool {return self._size != nil} - /// Clears the value of `size`. Subsequent reads from it will return its default value. - mutating func clearSize() {self._size = nil} - - /// A uuid for the attachment. Should be unique across all attachments. - var id: Int64 { - get {return _id ?? 0} - set {_id = newValue} - } - /// Returns true if `id` has been explicitly set. - var hasID: Bool {return self._id != nil} - /// Clears the value of `id`. Subsequent reads from it will return its default value. - mutating func clearID() {self._id = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum TypeEnum: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknown // = 0 - case text // = 1 - - /// Open with browsers. - case url // = 2 - - /// Open with map apps. - case address // = 3 - - /// Dial. - case phoneNumber // = 4 - - init() { - self = .unknown - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknown - case 1: self = .text - case 2: self = .url - case 3: self = .address - case 4: self = .phoneNumber - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknown: return 0 - case .text: return 1 - case .url: return 2 - case .address: return 3 - case .phoneNumber: return 4 - } - } - - } - - init() {} - - fileprivate var _textTitle: String? = nil - fileprivate var _type: Sharing_Nearby_TextMetadata.TypeEnum? = nil - fileprivate var _payloadID: Int64? = nil - fileprivate var _size: Int64? = nil - fileprivate var _id: Int64? = nil -} - -#if swift(>=4.2) - -extension Sharing_Nearby_TextMetadata.TypeEnum: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// NEXT_ID=5 -struct Sharing_Nearby_WifiCredentialsMetadata { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The Wifi network name. This will be sent in introduction. - var ssid: String { - get {return _ssid ?? String()} - set {_ssid = newValue} - } - /// Returns true if `ssid` has been explicitly set. - var hasSsid: Bool {return self._ssid != nil} - /// Clears the value of `ssid`. Subsequent reads from it will return its default value. - mutating func clearSsid() {self._ssid = nil} - - /// The security type of network (OPEN, WPA_PSK, WEP). - var securityType: Sharing_Nearby_WifiCredentialsMetadata.SecurityType { - get {return _securityType ?? .unknownSecurityType} - set {_securityType = newValue} - } - /// Returns true if `securityType` has been explicitly set. - var hasSecurityType: Bool {return self._securityType != nil} - /// Clears the value of `securityType`. Subsequent reads from it will return its default value. - mutating func clearSecurityType() {self._securityType = nil} - - /// The BYTE payload id that will be sent as a follow up containing the - /// password. - var payloadID: Int64 { - get {return _payloadID ?? 0} - set {_payloadID = newValue} - } - /// Returns true if `payloadID` has been explicitly set. - var hasPayloadID: Bool {return self._payloadID != nil} - /// Clears the value of `payloadID`. Subsequent reads from it will return its default value. - mutating func clearPayloadID() {self._payloadID = nil} - - /// A uuid for the attachment. Should be unique across all attachments. - var id: Int64 { - get {return _id ?? 0} - set {_id = newValue} - } - /// Returns true if `id` has been explicitly set. - var hasID: Bool {return self._id != nil} - /// Clears the value of `id`. Subsequent reads from it will return its default value. - mutating func clearID() {self._id = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum SecurityType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownSecurityType // = 0 - case `open` // = 1 - case wpaPsk // = 2 - case wep // = 3 - - init() { - self = .unknownSecurityType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownSecurityType - case 1: self = .open - case 2: self = .wpaPsk - case 3: self = .wep - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownSecurityType: return 0 - case .open: return 1 - case .wpaPsk: return 2 - case .wep: return 3 - } - } - - } - - init() {} - - fileprivate var _ssid: String? = nil - fileprivate var _securityType: Sharing_Nearby_WifiCredentialsMetadata.SecurityType? = nil - fileprivate var _payloadID: Int64? = nil - fileprivate var _id: Int64? = nil -} - -#if swift(>=4.2) - -extension Sharing_Nearby_WifiCredentialsMetadata.SecurityType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// A frame used when sending messages over the wire. -/// NEXT_ID=3 -struct Sharing_Nearby_Frame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var version: Sharing_Nearby_Frame.Version { - get {return _version ?? .unknownVersion} - set {_version = newValue} - } - /// Returns true if `version` has been explicitly set. - var hasVersion: Bool {return self._version != nil} - /// Clears the value of `version`. Subsequent reads from it will return its default value. - mutating func clearVersion() {self._version = nil} - - /// Right now there's only 1 version, but if there are more, exactly one of - /// the following fields will be set. - var v1: Sharing_Nearby_V1Frame { - get {return _v1 ?? Sharing_Nearby_V1Frame()} - set {_v1 = newValue} - } - /// Returns true if `v1` has been explicitly set. - var hasV1: Bool {return self._v1 != nil} - /// Clears the value of `v1`. Subsequent reads from it will return its default value. - mutating func clearV1() {self._v1 = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum Version: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownVersion // = 0 - case v1 // = 1 - - init() { - self = .unknownVersion - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownVersion - case 1: self = .v1 - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownVersion: return 0 - case .v1: return 1 - } - } - - } - - init() {} - - fileprivate var _version: Sharing_Nearby_Frame.Version? = nil - fileprivate var _v1: Sharing_Nearby_V1Frame? = nil -} - -#if swift(>=4.2) - -extension Sharing_Nearby_Frame.Version: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// NEXT_ID=7 -struct Sharing_Nearby_V1Frame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var type: Sharing_Nearby_V1Frame.FrameType { - get {return _type ?? .unknownFrameType} - set {_type = newValue} - } - /// Returns true if `type` has been explicitly set. - var hasType: Bool {return self._type != nil} - /// Clears the value of `type`. Subsequent reads from it will return its default value. - mutating func clearType() {self._type = nil} - - /// Exactly one of the following fields will be set. - var introduction: Sharing_Nearby_IntroductionFrame { - get {return _introduction ?? Sharing_Nearby_IntroductionFrame()} - set {_introduction = newValue} - } - /// Returns true if `introduction` has been explicitly set. - var hasIntroduction: Bool {return self._introduction != nil} - /// Clears the value of `introduction`. Subsequent reads from it will return its default value. - mutating func clearIntroduction() {self._introduction = nil} - - var connectionResponse: Sharing_Nearby_ConnectionResponseFrame { - get {return _connectionResponse ?? Sharing_Nearby_ConnectionResponseFrame()} - set {_connectionResponse = newValue} - } - /// Returns true if `connectionResponse` has been explicitly set. - var hasConnectionResponse: Bool {return self._connectionResponse != nil} - /// Clears the value of `connectionResponse`. Subsequent reads from it will return its default value. - mutating func clearConnectionResponse() {self._connectionResponse = nil} - - var pairedKeyEncryption: Sharing_Nearby_PairedKeyEncryptionFrame { - get {return _pairedKeyEncryption ?? Sharing_Nearby_PairedKeyEncryptionFrame()} - set {_pairedKeyEncryption = newValue} - } - /// Returns true if `pairedKeyEncryption` has been explicitly set. - var hasPairedKeyEncryption: Bool {return self._pairedKeyEncryption != nil} - /// Clears the value of `pairedKeyEncryption`. Subsequent reads from it will return its default value. - mutating func clearPairedKeyEncryption() {self._pairedKeyEncryption = nil} - - var pairedKeyResult: Sharing_Nearby_PairedKeyResultFrame { - get {return _pairedKeyResult ?? Sharing_Nearby_PairedKeyResultFrame()} - set {_pairedKeyResult = newValue} - } - /// Returns true if `pairedKeyResult` has been explicitly set. - var hasPairedKeyResult: Bool {return self._pairedKeyResult != nil} - /// Clears the value of `pairedKeyResult`. Subsequent reads from it will return its default value. - mutating func clearPairedKeyResult() {self._pairedKeyResult = nil} - - var certificateInfo: Sharing_Nearby_CertificateInfoFrame { - get {return _certificateInfo ?? Sharing_Nearby_CertificateInfoFrame()} - set {_certificateInfo = newValue} - } - /// Returns true if `certificateInfo` has been explicitly set. - var hasCertificateInfo: Bool {return self._certificateInfo != nil} - /// Clears the value of `certificateInfo`. Subsequent reads from it will return its default value. - mutating func clearCertificateInfo() {self._certificateInfo = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum FrameType: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknownFrameType // = 0 - case introduction // = 1 - case response // = 2 - case pairedKeyEncryption // = 3 - case pairedKeyResult // = 4 - case certificateInfo // = 5 - case cancel // = 6 - - init() { - self = .unknownFrameType - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknownFrameType - case 1: self = .introduction - case 2: self = .response - case 3: self = .pairedKeyEncryption - case 4: self = .pairedKeyResult - case 5: self = .certificateInfo - case 6: self = .cancel - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknownFrameType: return 0 - case .introduction: return 1 - case .response: return 2 - case .pairedKeyEncryption: return 3 - case .pairedKeyResult: return 4 - case .certificateInfo: return 5 - case .cancel: return 6 - } - } - - } - - init() {} - - fileprivate var _type: Sharing_Nearby_V1Frame.FrameType? = nil - fileprivate var _introduction: Sharing_Nearby_IntroductionFrame? = nil - fileprivate var _connectionResponse: Sharing_Nearby_ConnectionResponseFrame? = nil - fileprivate var _pairedKeyEncryption: Sharing_Nearby_PairedKeyEncryptionFrame? = nil - fileprivate var _pairedKeyResult: Sharing_Nearby_PairedKeyResultFrame? = nil - fileprivate var _certificateInfo: Sharing_Nearby_CertificateInfoFrame? = nil -} - -#if swift(>=4.2) - -extension Sharing_Nearby_V1Frame.FrameType: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// An introduction packet sent by the sending side. Contains a list of files -/// they'd like to share. -/// NEXT_ID=4 -struct Sharing_Nearby_IntroductionFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - var fileMetadata: [Sharing_Nearby_FileMetadata] = [] - - var textMetadata: [Sharing_Nearby_TextMetadata] = [] - - /// The required app package to open the content. May be null. - var requiredPackage: String { - get {return _requiredPackage ?? String()} - set {_requiredPackage = newValue} - } - /// Returns true if `requiredPackage` has been explicitly set. - var hasRequiredPackage: Bool {return self._requiredPackage != nil} - /// Clears the value of `requiredPackage`. Subsequent reads from it will return its default value. - mutating func clearRequiredPackage() {self._requiredPackage = nil} - - var wifiCredentialsMetadata: [Sharing_Nearby_WifiCredentialsMetadata] = [] - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _requiredPackage: String? = nil -} - -/// A response packet sent by the receiving side. Accepts or rejects the list of -/// files. -/// NEXT_ID=2 -struct Sharing_Nearby_ConnectionResponseFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The receiving side's response. - var status: Sharing_Nearby_ConnectionResponseFrame.Status { - get {return _status ?? .unknown} - set {_status = newValue} - } - /// Returns true if `status` has been explicitly set. - var hasStatus: Bool {return self._status != nil} - /// Clears the value of `status`. Subsequent reads from it will return its default value. - mutating func clearStatus() {self._status = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum Status: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknown // = 0 - case accept // = 1 - case reject // = 2 - case notEnoughSpace // = 3 - case unsupportedAttachmentType // = 4 - case timedOut // = 5 - - init() { - self = .unknown - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknown - case 1: self = .accept - case 2: self = .reject - case 3: self = .notEnoughSpace - case 4: self = .unsupportedAttachmentType - case 5: self = .timedOut - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknown: return 0 - case .accept: return 1 - case .reject: return 2 - case .notEnoughSpace: return 3 - case .unsupportedAttachmentType: return 4 - case .timedOut: return 5 - } - } - - } - - init() {} - - fileprivate var _status: Sharing_Nearby_ConnectionResponseFrame.Status? = nil -} - -#if swift(>=4.2) - -extension Sharing_Nearby_ConnectionResponseFrame.Status: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// A paired key encryption packet sent between devices, contains signed data. -/// NEXT_ID=3 -struct Sharing_Nearby_PairedKeyEncryptionFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The encrypted data in byte array format. - var signedData: Data { - get {return _signedData ?? Data()} - set {_signedData = newValue} - } - /// Returns true if `signedData` has been explicitly set. - var hasSignedData: Bool {return self._signedData != nil} - /// Clears the value of `signedData`. Subsequent reads from it will return its default value. - mutating func clearSignedData() {self._signedData = nil} - - /// The hash of a certificate id. - var secretIDHash: Data { - get {return _secretIDHash ?? Data()} - set {_secretIDHash = newValue} - } - /// Returns true if `secretIDHash` has been explicitly set. - var hasSecretIDHash: Bool {return self._secretIDHash != nil} - /// Clears the value of `secretIDHash`. Subsequent reads from it will return its default value. - mutating func clearSecretIDHash() {self._secretIDHash = nil} - - /// An optional encrypted data in byte array format. - var optionalSignedData: Data { - get {return _optionalSignedData ?? Data()} - set {_optionalSignedData = newValue} - } - /// Returns true if `optionalSignedData` has been explicitly set. - var hasOptionalSignedData: Bool {return self._optionalSignedData != nil} - /// Clears the value of `optionalSignedData`. Subsequent reads from it will return its default value. - mutating func clearOptionalSignedData() {self._optionalSignedData = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _signedData: Data? = nil - fileprivate var _secretIDHash: Data? = nil - fileprivate var _optionalSignedData: Data? = nil -} - -/// A paired key verification result packet sent between devices. -/// NEXT_ID=2 -struct Sharing_Nearby_PairedKeyResultFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The verification result. - var status: Sharing_Nearby_PairedKeyResultFrame.Status { - get {return _status ?? .unknown} - set {_status = newValue} - } - /// Returns true if `status` has been explicitly set. - var hasStatus: Bool {return self._status != nil} - /// Clears the value of `status`. Subsequent reads from it will return its default value. - mutating func clearStatus() {self._status = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - enum Status: SwiftProtobuf.Enum { - typealias RawValue = Int - case unknown // = 0 - case success // = 1 - case fail // = 2 - case unable // = 3 - - init() { - self = .unknown - } - - init?(rawValue: Int) { - switch rawValue { - case 0: self = .unknown - case 1: self = .success - case 2: self = .fail - case 3: self = .unable - default: return nil - } - } - - var rawValue: Int { - switch self { - case .unknown: return 0 - case .success: return 1 - case .fail: return 2 - case .unable: return 3 - } - } - - } - - init() {} - - fileprivate var _status: Sharing_Nearby_PairedKeyResultFrame.Status? = nil -} - -#if swift(>=4.2) - -extension Sharing_Nearby_PairedKeyResultFrame.Status: CaseIterable { - // Support synthesized by the compiler. -} - -#endif // swift(>=4.2) - -/// A package containing certificate info to be shared to remote device offline. -/// NEXT_ID=2 -struct Sharing_Nearby_CertificateInfoFrame { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The public certificates to be shared with remote devices. - var publicCertificate: [Sharing_Nearby_PublicCertificate] = [] - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} -} - -/// A public certificate from the local device. -/// NEXT_ID=8 -struct Sharing_Nearby_PublicCertificate { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// The unique id of the public certificate. - var secretID: Data { - get {return _secretID ?? Data()} - set {_secretID = newValue} - } - /// Returns true if `secretID` has been explicitly set. - var hasSecretID: Bool {return self._secretID != nil} - /// Clears the value of `secretID`. Subsequent reads from it will return its default value. - mutating func clearSecretID() {self._secretID = nil} - - /// A bytes representation of a Secret Key owned by contact, to decrypt the - /// metadata_key stored within the advertisement. - var authenticityKey: Data { - get {return _authenticityKey ?? Data()} - set {_authenticityKey = newValue} - } - /// Returns true if `authenticityKey` has been explicitly set. - var hasAuthenticityKey: Bool {return self._authenticityKey != nil} - /// Clears the value of `authenticityKey`. Subsequent reads from it will return its default value. - mutating func clearAuthenticityKey() {self._authenticityKey = nil} - - /// A bytes representation a public key of X509Certificate, owned by contact, - /// to decrypt encrypted UKEY2 (from Nearby Connections API) as a hand shake in - /// contact verification phase. - var publicKey: Data { - get {return _publicKey ?? Data()} - set {_publicKey = newValue} - } - /// Returns true if `publicKey` has been explicitly set. - var hasPublicKey: Bool {return self._publicKey != nil} - /// Clears the value of `publicKey`. Subsequent reads from it will return its default value. - mutating func clearPublicKey() {self._publicKey = nil} - - /// The time in millis from epoch when this certificate becomes effective. - var startTime: Int64 { - get {return _startTime ?? 0} - set {_startTime = newValue} - } - /// Returns true if `startTime` has been explicitly set. - var hasStartTime: Bool {return self._startTime != nil} - /// Clears the value of `startTime`. Subsequent reads from it will return its default value. - mutating func clearStartTime() {self._startTime = nil} - - /// The time in millis from epoch when this certificate expires. - var endTime: Int64 { - get {return _endTime ?? 0} - set {_endTime = newValue} - } - /// Returns true if `endTime` has been explicitly set. - var hasEndTime: Bool {return self._endTime != nil} - /// Clears the value of `endTime`. Subsequent reads from it will return its default value. - mutating func clearEndTime() {self._endTime = nil} - - /// The encrypted metadata in bytes, contains personal information of the - /// device/user who created this certificate. Needs to be decrypted into bytes, - /// and converted back to EncryptedMetadata object to access fields. - var encryptedMetadataBytes: Data { - get {return _encryptedMetadataBytes ?? Data()} - set {_encryptedMetadataBytes = newValue} - } - /// Returns true if `encryptedMetadataBytes` has been explicitly set. - var hasEncryptedMetadataBytes: Bool {return self._encryptedMetadataBytes != nil} - /// Clears the value of `encryptedMetadataBytes`. Subsequent reads from it will return its default value. - mutating func clearEncryptedMetadataBytes() {self._encryptedMetadataBytes = nil} - - /// The tag for verifying metadata_encryption_key. - var metadataEncryptionKeyTag: Data { - get {return _metadataEncryptionKeyTag ?? Data()} - set {_metadataEncryptionKeyTag = newValue} - } - /// Returns true if `metadataEncryptionKeyTag` has been explicitly set. - var hasMetadataEncryptionKeyTag: Bool {return self._metadataEncryptionKeyTag != nil} - /// Clears the value of `metadataEncryptionKeyTag`. Subsequent reads from it will return its default value. - mutating func clearMetadataEncryptionKeyTag() {self._metadataEncryptionKeyTag = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _secretID: Data? = nil - fileprivate var _authenticityKey: Data? = nil - fileprivate var _publicKey: Data? = nil - fileprivate var _startTime: Int64? = nil - fileprivate var _endTime: Int64? = nil - fileprivate var _encryptedMetadataBytes: Data? = nil - fileprivate var _metadataEncryptionKeyTag: Data? = nil -} - -/// NEXT_ID=3 -struct Sharing_Nearby_WifiCredentials { - // SwiftProtobuf.Message conformance is added in an extension below. See the - // `Message` and `Message+*Additions` files in the SwiftProtobuf library for - // methods supported on all messages. - - /// Wi-Fi password. - var password: String { - get {return _password ?? String()} - set {_password = newValue} - } - /// Returns true if `password` has been explicitly set. - var hasPassword: Bool {return self._password != nil} - /// Clears the value of `password`. Subsequent reads from it will return its default value. - mutating func clearPassword() {self._password = nil} - - /// True if the network is a hidden network that is not broadcasting its SSID. - /// Default is false. - var hiddenSsid: Bool { - get {return _hiddenSsid ?? false} - set {_hiddenSsid = newValue} - } - /// Returns true if `hiddenSsid` has been explicitly set. - var hasHiddenSsid: Bool {return self._hiddenSsid != nil} - /// Clears the value of `hiddenSsid`. Subsequent reads from it will return its default value. - mutating func clearHiddenSsid() {self._hiddenSsid = nil} - - var unknownFields = SwiftProtobuf.UnknownStorage() - - init() {} - - fileprivate var _password: String? = nil - fileprivate var _hiddenSsid: Bool? = nil -} - -#if swift(>=5.5) && canImport(_Concurrency) -extension Sharing_Nearby_FileMetadata: @unchecked Sendable {} -extension Sharing_Nearby_FileMetadata.TypeEnum: @unchecked Sendable {} -extension Sharing_Nearby_TextMetadata: @unchecked Sendable {} -extension Sharing_Nearby_TextMetadata.TypeEnum: @unchecked Sendable {} -extension Sharing_Nearby_WifiCredentialsMetadata: @unchecked Sendable {} -extension Sharing_Nearby_WifiCredentialsMetadata.SecurityType: @unchecked Sendable {} -extension Sharing_Nearby_Frame: @unchecked Sendable {} -extension Sharing_Nearby_Frame.Version: @unchecked Sendable {} -extension Sharing_Nearby_V1Frame: @unchecked Sendable {} -extension Sharing_Nearby_V1Frame.FrameType: @unchecked Sendable {} -extension Sharing_Nearby_IntroductionFrame: @unchecked Sendable {} -extension Sharing_Nearby_ConnectionResponseFrame: @unchecked Sendable {} -extension Sharing_Nearby_ConnectionResponseFrame.Status: @unchecked Sendable {} -extension Sharing_Nearby_PairedKeyEncryptionFrame: @unchecked Sendable {} -extension Sharing_Nearby_PairedKeyResultFrame: @unchecked Sendable {} -extension Sharing_Nearby_PairedKeyResultFrame.Status: @unchecked Sendable {} -extension Sharing_Nearby_CertificateInfoFrame: @unchecked Sendable {} -extension Sharing_Nearby_PublicCertificate: @unchecked Sendable {} -extension Sharing_Nearby_WifiCredentials: @unchecked Sendable {} -#endif // swift(>=5.5) && canImport(_Concurrency) - -// MARK: - Code below here is support for the SwiftProtobuf runtime. - -fileprivate let _protobuf_package = "sharing.nearby" - -extension Sharing_Nearby_FileMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".FileMetadata" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "name"), - 2: .same(proto: "type"), - 3: .standard(proto: "payload_id"), - 4: .same(proto: "size"), - 5: .standard(proto: "mime_type"), - 6: .same(proto: "id"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._name) }() - case 2: try { try decoder.decodeSingularEnumField(value: &self._type) }() - case 3: try { try decoder.decodeSingularInt64Field(value: &self._payloadID) }() - case 4: try { try decoder.decodeSingularInt64Field(value: &self._size) }() - case 5: try { try decoder.decodeSingularStringField(value: &self._mimeType) }() - case 6: try { try decoder.decodeSingularInt64Field(value: &self._id) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._name { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 2) - } }() - try { if let v = self._payloadID { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 3) - } }() - try { if let v = self._size { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) - } }() - try { if let v = self._mimeType { - try visitor.visitSingularStringField(value: v, fieldNumber: 5) - } }() - try { if let v = self._id { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 6) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_FileMetadata, rhs: Sharing_Nearby_FileMetadata) -> Bool { - if lhs._name != rhs._name {return false} - if lhs._type != rhs._type {return false} - if lhs._payloadID != rhs._payloadID {return false} - if lhs._size != rhs._size {return false} - if lhs._mimeType != rhs._mimeType {return false} - if lhs._id != rhs._id {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_FileMetadata.TypeEnum: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "IMAGE"), - 2: .same(proto: "VIDEO"), - 3: .same(proto: "APP"), - 4: .same(proto: "AUDIO"), - ] -} - -extension Sharing_Nearby_TextMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".TextMetadata" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 2: .standard(proto: "text_title"), - 3: .same(proto: "type"), - 4: .standard(proto: "payload_id"), - 5: .same(proto: "size"), - 6: .same(proto: "id"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 2: try { try decoder.decodeSingularStringField(value: &self._textTitle) }() - case 3: try { try decoder.decodeSingularEnumField(value: &self._type) }() - case 4: try { try decoder.decodeSingularInt64Field(value: &self._payloadID) }() - case 5: try { try decoder.decodeSingularInt64Field(value: &self._size) }() - case 6: try { try decoder.decodeSingularInt64Field(value: &self._id) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._textTitle { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 3) - } }() - try { if let v = self._payloadID { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) - } }() - try { if let v = self._size { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 5) - } }() - try { if let v = self._id { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 6) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_TextMetadata, rhs: Sharing_Nearby_TextMetadata) -> Bool { - if lhs._textTitle != rhs._textTitle {return false} - if lhs._type != rhs._type {return false} - if lhs._payloadID != rhs._payloadID {return false} - if lhs._size != rhs._size {return false} - if lhs._id != rhs._id {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_TextMetadata.TypeEnum: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "TEXT"), - 2: .same(proto: "URL"), - 3: .same(proto: "ADDRESS"), - 4: .same(proto: "PHONE_NUMBER"), - ] -} - -extension Sharing_Nearby_WifiCredentialsMetadata: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".WifiCredentialsMetadata" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 2: .same(proto: "ssid"), - 3: .standard(proto: "security_type"), - 4: .standard(proto: "payload_id"), - 5: .same(proto: "id"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 2: try { try decoder.decodeSingularStringField(value: &self._ssid) }() - case 3: try { try decoder.decodeSingularEnumField(value: &self._securityType) }() - case 4: try { try decoder.decodeSingularInt64Field(value: &self._payloadID) }() - case 5: try { try decoder.decodeSingularInt64Field(value: &self._id) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._ssid { - try visitor.visitSingularStringField(value: v, fieldNumber: 2) - } }() - try { if let v = self._securityType { - try visitor.visitSingularEnumField(value: v, fieldNumber: 3) - } }() - try { if let v = self._payloadID { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) - } }() - try { if let v = self._id { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 5) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_WifiCredentialsMetadata, rhs: Sharing_Nearby_WifiCredentialsMetadata) -> Bool { - if lhs._ssid != rhs._ssid {return false} - if lhs._securityType != rhs._securityType {return false} - if lhs._payloadID != rhs._payloadID {return false} - if lhs._id != rhs._id {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_WifiCredentialsMetadata.SecurityType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_SECURITY_TYPE"), - 1: .same(proto: "OPEN"), - 2: .same(proto: "WPA_PSK"), - 3: .same(proto: "WEP"), - ] -} - -extension Sharing_Nearby_Frame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".Frame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "version"), - 2: .same(proto: "v1"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._version) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._v1) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._version { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._v1 { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_Frame, rhs: Sharing_Nearby_Frame) -> Bool { - if lhs._version != rhs._version {return false} - if lhs._v1 != rhs._v1 {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_Frame.Version: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_VERSION"), - 1: .same(proto: "V1"), - ] -} - -extension Sharing_Nearby_V1Frame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".V1Frame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "type"), - 2: .same(proto: "introduction"), - 3: .standard(proto: "connection_response"), - 4: .standard(proto: "paired_key_encryption"), - 5: .standard(proto: "paired_key_result"), - 6: .standard(proto: "certificate_info"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }() - case 2: try { try decoder.decodeSingularMessageField(value: &self._introduction) }() - case 3: try { try decoder.decodeSingularMessageField(value: &self._connectionResponse) }() - case 4: try { try decoder.decodeSingularMessageField(value: &self._pairedKeyEncryption) }() - case 5: try { try decoder.decodeSingularMessageField(value: &self._pairedKeyResult) }() - case 6: try { try decoder.decodeSingularMessageField(value: &self._certificateInfo) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._type { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try { if let v = self._introduction { - try visitor.visitSingularMessageField(value: v, fieldNumber: 2) - } }() - try { if let v = self._connectionResponse { - try visitor.visitSingularMessageField(value: v, fieldNumber: 3) - } }() - try { if let v = self._pairedKeyEncryption { - try visitor.visitSingularMessageField(value: v, fieldNumber: 4) - } }() - try { if let v = self._pairedKeyResult { - try visitor.visitSingularMessageField(value: v, fieldNumber: 5) - } }() - try { if let v = self._certificateInfo { - try visitor.visitSingularMessageField(value: v, fieldNumber: 6) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_V1Frame, rhs: Sharing_Nearby_V1Frame) -> Bool { - if lhs._type != rhs._type {return false} - if lhs._introduction != rhs._introduction {return false} - if lhs._connectionResponse != rhs._connectionResponse {return false} - if lhs._pairedKeyEncryption != rhs._pairedKeyEncryption {return false} - if lhs._pairedKeyResult != rhs._pairedKeyResult {return false} - if lhs._certificateInfo != rhs._certificateInfo {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_V1Frame.FrameType: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN_FRAME_TYPE"), - 1: .same(proto: "INTRODUCTION"), - 2: .same(proto: "RESPONSE"), - 3: .same(proto: "PAIRED_KEY_ENCRYPTION"), - 4: .same(proto: "PAIRED_KEY_RESULT"), - 5: .same(proto: "CERTIFICATE_INFO"), - 6: .same(proto: "CANCEL"), - ] -} - -extension Sharing_Nearby_IntroductionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".IntroductionFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "file_metadata"), - 2: .standard(proto: "text_metadata"), - 3: .standard(proto: "required_package"), - 4: .standard(proto: "wifi_credentials_metadata"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeRepeatedMessageField(value: &self.fileMetadata) }() - case 2: try { try decoder.decodeRepeatedMessageField(value: &self.textMetadata) }() - case 3: try { try decoder.decodeSingularStringField(value: &self._requiredPackage) }() - case 4: try { try decoder.decodeRepeatedMessageField(value: &self.wifiCredentialsMetadata) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - if !self.fileMetadata.isEmpty { - try visitor.visitRepeatedMessageField(value: self.fileMetadata, fieldNumber: 1) - } - if !self.textMetadata.isEmpty { - try visitor.visitRepeatedMessageField(value: self.textMetadata, fieldNumber: 2) - } - try { if let v = self._requiredPackage { - try visitor.visitSingularStringField(value: v, fieldNumber: 3) - } }() - if !self.wifiCredentialsMetadata.isEmpty { - try visitor.visitRepeatedMessageField(value: self.wifiCredentialsMetadata, fieldNumber: 4) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_IntroductionFrame, rhs: Sharing_Nearby_IntroductionFrame) -> Bool { - if lhs.fileMetadata != rhs.fileMetadata {return false} - if lhs.textMetadata != rhs.textMetadata {return false} - if lhs._requiredPackage != rhs._requiredPackage {return false} - if lhs.wifiCredentialsMetadata != rhs.wifiCredentialsMetadata {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_ConnectionResponseFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".ConnectionResponseFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "status"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._status) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._status { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_ConnectionResponseFrame, rhs: Sharing_Nearby_ConnectionResponseFrame) -> Bool { - if lhs._status != rhs._status {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_ConnectionResponseFrame.Status: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "ACCEPT"), - 2: .same(proto: "REJECT"), - 3: .same(proto: "NOT_ENOUGH_SPACE"), - 4: .same(proto: "UNSUPPORTED_ATTACHMENT_TYPE"), - 5: .same(proto: "TIMED_OUT"), - ] -} - -extension Sharing_Nearby_PairedKeyEncryptionFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".PairedKeyEncryptionFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "signed_data"), - 2: .standard(proto: "secret_id_hash"), - 3: .standard(proto: "optional_signed_data"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._signedData) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._secretIDHash) }() - case 3: try { try decoder.decodeSingularBytesField(value: &self._optionalSignedData) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._signedData { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._secretIDHash { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try { if let v = self._optionalSignedData { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_PairedKeyEncryptionFrame, rhs: Sharing_Nearby_PairedKeyEncryptionFrame) -> Bool { - if lhs._signedData != rhs._signedData {return false} - if lhs._secretIDHash != rhs._secretIDHash {return false} - if lhs._optionalSignedData != rhs._optionalSignedData {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_PairedKeyResultFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".PairedKeyResultFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "status"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularEnumField(value: &self._status) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._status { - try visitor.visitSingularEnumField(value: v, fieldNumber: 1) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_PairedKeyResultFrame, rhs: Sharing_Nearby_PairedKeyResultFrame) -> Bool { - if lhs._status != rhs._status {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_PairedKeyResultFrame.Status: SwiftProtobuf._ProtoNameProviding { - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 0: .same(proto: "UNKNOWN"), - 1: .same(proto: "SUCCESS"), - 2: .same(proto: "FAIL"), - 3: .same(proto: "UNABLE"), - ] -} - -extension Sharing_Nearby_CertificateInfoFrame: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".CertificateInfoFrame" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "public_certificate"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeRepeatedMessageField(value: &self.publicCertificate) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - if !self.publicCertificate.isEmpty { - try visitor.visitRepeatedMessageField(value: self.publicCertificate, fieldNumber: 1) - } - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_CertificateInfoFrame, rhs: Sharing_Nearby_CertificateInfoFrame) -> Bool { - if lhs.publicCertificate != rhs.publicCertificate {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_PublicCertificate: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".PublicCertificate" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .standard(proto: "secret_id"), - 2: .standard(proto: "authenticity_key"), - 3: .standard(proto: "public_key"), - 4: .standard(proto: "start_time"), - 5: .standard(proto: "end_time"), - 6: .standard(proto: "encrypted_metadata_bytes"), - 7: .standard(proto: "metadata_encryption_key_tag"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularBytesField(value: &self._secretID) }() - case 2: try { try decoder.decodeSingularBytesField(value: &self._authenticityKey) }() - case 3: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }() - case 4: try { try decoder.decodeSingularInt64Field(value: &self._startTime) }() - case 5: try { try decoder.decodeSingularInt64Field(value: &self._endTime) }() - case 6: try { try decoder.decodeSingularBytesField(value: &self._encryptedMetadataBytes) }() - case 7: try { try decoder.decodeSingularBytesField(value: &self._metadataEncryptionKeyTag) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._secretID { - try visitor.visitSingularBytesField(value: v, fieldNumber: 1) - } }() - try { if let v = self._authenticityKey { - try visitor.visitSingularBytesField(value: v, fieldNumber: 2) - } }() - try { if let v = self._publicKey { - try visitor.visitSingularBytesField(value: v, fieldNumber: 3) - } }() - try { if let v = self._startTime { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 4) - } }() - try { if let v = self._endTime { - try visitor.visitSingularInt64Field(value: v, fieldNumber: 5) - } }() - try { if let v = self._encryptedMetadataBytes { - try visitor.visitSingularBytesField(value: v, fieldNumber: 6) - } }() - try { if let v = self._metadataEncryptionKeyTag { - try visitor.visitSingularBytesField(value: v, fieldNumber: 7) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_PublicCertificate, rhs: Sharing_Nearby_PublicCertificate) -> Bool { - if lhs._secretID != rhs._secretID {return false} - if lhs._authenticityKey != rhs._authenticityKey {return false} - if lhs._publicKey != rhs._publicKey {return false} - if lhs._startTime != rhs._startTime {return false} - if lhs._endTime != rhs._endTime {return false} - if lhs._encryptedMetadataBytes != rhs._encryptedMetadataBytes {return false} - if lhs._metadataEncryptionKeyTag != rhs._metadataEncryptionKeyTag {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} - -extension Sharing_Nearby_WifiCredentials: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding { - static let protoMessageName: String = _protobuf_package + ".WifiCredentials" - static let _protobuf_nameMap: SwiftProtobuf._NameMap = [ - 1: .same(proto: "password"), - 2: .standard(proto: "hidden_ssid"), - ] - - mutating func decodeMessage(decoder: inout D) throws { - while let fieldNumber = try decoder.nextFieldNumber() { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every case branch when no optimizations are - // enabled. https://github.com/apple/swift-protobuf/issues/1034 - switch fieldNumber { - case 1: try { try decoder.decodeSingularStringField(value: &self._password) }() - case 2: try { try decoder.decodeSingularBoolField(value: &self._hiddenSsid) }() - default: break - } - } - } - - func traverse(visitor: inout V) throws { - // The use of inline closures is to circumvent an issue where the compiler - // allocates stack space for every if/case branch local when no optimizations - // are enabled. https://github.com/apple/swift-protobuf/issues/1034 and - // https://github.com/apple/swift-protobuf/issues/1182 - try { if let v = self._password { - try visitor.visitSingularStringField(value: v, fieldNumber: 1) - } }() - try { if let v = self._hiddenSsid { - try visitor.visitSingularBoolField(value: v, fieldNumber: 2) - } }() - try unknownFields.traverse(visitor: &visitor) - } - - static func ==(lhs: Sharing_Nearby_WifiCredentials, rhs: Sharing_Nearby_WifiCredentials) -> Bool { - if lhs._password != rhs._password {return false} - if lhs._hiddenSsid != rhs._hiddenSsid {return false} - if lhs.unknownFields != rhs.unknownFields {return false} - return true - } -} From 937ce0488e52ae9817dd8d7dbbf0806114238c91 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:47:16 -0400 Subject: [PATCH 13/16] Delete submissions/sapphire/ProtobufSource directory --- .../device_to_device_messages.proto | 81 ---- .../ProtobufSource/offline_wire_formats.proto | 403 ------------------ .../sapphire/ProtobufSource/securegcm.proto | 308 ------------- .../ProtobufSource/securemessage.proto | 126 ------ .../sapphire/ProtobufSource/ukey.proto | 105 ----- .../sapphire/ProtobufSource/wire_format.proto | 236 ---------- 6 files changed, 1259 deletions(-) delete mode 100644 submissions/sapphire/ProtobufSource/device_to_device_messages.proto delete mode 100644 submissions/sapphire/ProtobufSource/offline_wire_formats.proto delete mode 100644 submissions/sapphire/ProtobufSource/securegcm.proto delete mode 100644 submissions/sapphire/ProtobufSource/securemessage.proto delete mode 100644 submissions/sapphire/ProtobufSource/ukey.proto delete mode 100644 submissions/sapphire/ProtobufSource/wire_format.proto diff --git a/submissions/sapphire/ProtobufSource/device_to_device_messages.proto b/submissions/sapphire/ProtobufSource/device_to_device_messages.proto deleted file mode 100644 index 5600373e..00000000 --- a/submissions/sapphire/ProtobufSource/device_to_device_messages.proto +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto2"; - -package securegcm; - -import "securemessage.proto"; - -option optimize_for = LITE_RUNTIME; -option java_package = "com.google.security.cryptauth.lib.securegcm"; -option java_outer_classname = "DeviceToDeviceMessagesProto"; -option objc_class_prefix = "SGCM"; - -// Used by protocols between devices -message DeviceToDeviceMessage { - // the payload of the message - optional bytes message = 1; - - // the sequence number of the message - must be increasing. - optional int32 sequence_number = 2; -} - -// sent as the first message from initiator to responder -// in an unauthenticated Diffie-Hellman Key Exchange -message InitiatorHello { - // The session public key to send to the responder - optional securemessage.GenericPublicKey public_dh_key = 1; - - // The protocol version - optional int32 protocol_version = 2 [default = 0]; -} - -// sent inside the header of the first message from the responder to the -// initiator in an unauthenticated Diffie-Hellman Key Exchange -message ResponderHello { - // The session public key to send to the initiator - optional securemessage.GenericPublicKey public_dh_key = 1; - - // The protocol version - optional int32 protocol_version = 2 [default = 0]; -} - -// Type of curve -enum Curve { ED_25519 = 1; } - -// A convenience proto for encoding curve points in affine representation -message EcPoint { - required Curve curve = 1; - - // x and y are encoded in big-endian two's complement - // client MUST verify (x,y) is a valid point on the specified curve - required bytes x = 2; - required bytes y = 3; -} - -message SpakeHandshakeMessage { - // Each flow in the protocol bumps this counter - optional int32 flow_number = 1; - - // Some (but not all) SPAKE flows send a point on an elliptic curve - optional EcPoint ec_point = 2; - - // Some (but not all) SPAKE flows send a hash value - optional bytes hash_value = 3; - - // The last flow of a SPAKE protocol can send an optional payload, - // since the key exchange is already complete on the sender's side. - optional bytes payload = 4; -} diff --git a/submissions/sapphire/ProtobufSource/offline_wire_formats.proto b/submissions/sapphire/ProtobufSource/offline_wire_formats.proto deleted file mode 100644 index c1120040..00000000 --- a/submissions/sapphire/ProtobufSource/offline_wire_formats.proto +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto2"; - -package location.nearby.connections; - -option optimize_for = LITE_RUNTIME; -option java_outer_classname = "OfflineWireFormatsProto"; -option java_package = "com.google.location.nearby.connections.proto"; -option objc_class_prefix = "GNCP"; - -message OfflineFrame { - enum Version { - UNKNOWN_VERSION = 0; - V1 = 1; - } - optional Version version = 1; - - // Right now there's only 1 version, but if there are more, exactly one of - // the following fields will be set. - optional V1Frame v1 = 2; -} - -message V1Frame { - enum FrameType { - UNKNOWN_FRAME_TYPE = 0; - CONNECTION_REQUEST = 1; - CONNECTION_RESPONSE = 2; - PAYLOAD_TRANSFER = 3; - BANDWIDTH_UPGRADE_NEGOTIATION = 4; - KEEP_ALIVE = 5; - DISCONNECTION = 6; - PAIRED_KEY_ENCRYPTION = 7; - } - optional FrameType type = 1; - - // Exactly one of the following fields will be set. - optional ConnectionRequestFrame connection_request = 2; - optional ConnectionResponseFrame connection_response = 3; - optional PayloadTransferFrame payload_transfer = 4; - optional BandwidthUpgradeNegotiationFrame bandwidth_upgrade_negotiation = 5; - optional KeepAliveFrame keep_alive = 6; - optional DisconnectionFrame disconnection = 7; - optional PairedKeyEncryptionFrame paired_key_encryption = 8; -} - -message ConnectionRequestFrame { - // Should always match cs/symbol:location.nearby.proto.connections.Medium - // LINT.IfChange - enum Medium { - UNKNOWN_MEDIUM = 0; - MDNS = 1 [deprecated = true]; - BLUETOOTH = 2; - WIFI_HOTSPOT = 3; - BLE = 4; - WIFI_LAN = 5; - WIFI_AWARE = 6; - NFC = 7; - WIFI_DIRECT = 8; - WEB_RTC = 9; - BLE_L2CAP = 10; - USB = 11; - } - // LINT.ThenChange(//depot/google3/third_party/nearby/proto/connections_enums.proto) - - optional string endpoint_id = 1; - optional string endpoint_name = 2; - optional bytes handshake_data = 3; - // A random number generated for each outgoing connection that is presently - // used to act as a tiebreaker when 2 devices connect to each other - // simultaneously; this can also be used for other initialization-scoped - // things in the future. - optional int32 nonce = 4; - // The mediums this device supports upgrading to. This list should be filtered - // by both the strategy and this device's individual limitations. - repeated Medium mediums = 5; - optional bytes endpoint_info = 6; - optional MediumMetadata medium_metadata = 7; - optional int32 keep_alive_interval_millis = 8; - optional int32 keep_alive_timeout_millis = 9; - // The type of {@link Device} object. - optional int32 device_type = 10 [default = 0]; - // The bytes of serialized {@link Device} object. - optional bytes device_info = 11; -} - -message ConnectionResponseFrame { - // This doesn't need to send back endpoint_id and endpoint_name (like - // the ConnectionRequestFrame does) because those have already been - // transmitted out-of-band, at the time this endpoint was discovered. - - // One of: - // - // - ConnectionsStatusCodes.STATUS_OK - // - ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED. - optional int32 status = 1 [deprecated = true]; - optional bytes handshake_data = 2; - - // Used to replace the status integer parameter with a meaningful enum item. - // Map ConnectionsStatusCodes.STATUS_OK to ACCEPT and - // ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED to REJECT. - // Flag: connection_replace_status_with_response_connectionResponseFrame - enum ResponseStatus { - UNKNOWN_RESPONSE_STATUS = 0; - ACCEPT = 1; - REJECT = 2; - } - optional ResponseStatus response = 3; - optional OsInfo os_info = 4; - // A bitmask value to indicate which medium supports Multiplex transmission - // feature. Each supporting medium could utilize one bit starting from the - // least significant bit in this field. eq. BT utilizes the LSB bit which 0x01 - // means bt supports multiplex while 0x00 means not. Refer to ClientProxy.java - // for the bit usages. - optional int32 multiplex_socket_bitmask = 5; - optional int32 nearby_connections_version = 6; -} - -message PayloadTransferFrame { - enum PacketType { - UNKNOWN_PACKET_TYPE = 0; - DATA = 1; - CONTROL = 2; - } - - message PayloadHeader { - enum PayloadType { - UNKNOWN_PAYLOAD_TYPE = 0; - BYTES = 1; - FILE = 2; - STREAM = 3; - } - optional int64 id = 1; - optional PayloadType type = 2; - optional int64 total_size = 3; - optional bool is_sensitive = 4; - optional string file_name = 5; - optional string parent_folder = 6; - } - - // Accompanies DATA packets. - message PayloadChunk { - enum Flags { - LAST_CHUNK = 0x1; - } - optional int32 flags = 1; - optional int64 offset = 2; - optional bytes body = 3; - } - - // Accompanies CONTROL packets. - message ControlMessage { - enum EventType { - UNKNOWN_EVENT_TYPE = 0; - PAYLOAD_ERROR = 1; - PAYLOAD_CANCELED = 2; - PAYLOAD_RECEIVED_ACK = 3; - } - - optional EventType event = 1; - optional int64 offset = 2; - } - - optional PacketType packet_type = 1; - optional PayloadHeader payload_header = 2; - - // Exactly one of the following fields will be set, depending on the type. - optional PayloadChunk payload_chunk = 3; - optional ControlMessage control_message = 4; -} - -message BandwidthUpgradeNegotiationFrame { - enum EventType { - UNKNOWN_EVENT_TYPE = 0; - UPGRADE_PATH_AVAILABLE = 1; - LAST_WRITE_TO_PRIOR_CHANNEL = 2; - SAFE_TO_CLOSE_PRIOR_CHANNEL = 3; - CLIENT_INTRODUCTION = 4; - UPGRADE_FAILURE = 5; - CLIENT_INTRODUCTION_ACK = 6; - } - - // Accompanies UPGRADE_PATH_AVAILABLE and UPGRADE_FAILURE events. - message UpgradePathInfo { - // Should always match cs/symbol:location.nearby.proto.connections.Medium - enum Medium { - UNKNOWN_MEDIUM = 0; - MDNS = 1 [deprecated = true]; - BLUETOOTH = 2; - WIFI_HOTSPOT = 3; - BLE = 4; - WIFI_LAN = 5; - WIFI_AWARE = 6; - NFC = 7; - WIFI_DIRECT = 8; - WEB_RTC = 9; - // 10 is reserved. - USB = 11; - } - - // Accompanies Medium.WIFI_HOTSPOT. - message WifiHotspotCredentials { - optional string ssid = 1; - optional string password = 2; - optional int32 port = 3; - optional string gateway = 4 [default = "0.0.0.0"]; - // This field can be a band or frequency - optional int32 frequency = 5 [default = -1]; - } - - // Accompanies Medium.WIFI_LAN. - message WifiLanSocket { - optional bytes ip_address = 1; - optional int32 wifi_port = 2; - } - - // Accompanies Medium.BLUETOOTH. - message BluetoothCredentials { - optional string service_name = 1; - optional string mac_address = 2; - } - - // Accompanies Medium.WIFI_AWARE. - message WifiAwareCredentials { - optional string service_id = 1; - optional bytes service_info = 2; - optional string password = 3; - } - - // Accompanies Medium.WIFI_DIRECT. - message WifiDirectCredentials { - optional string ssid = 1; - optional string password = 2; - optional int32 port = 3; - optional int32 frequency = 4; - optional string gateway = 5 [default = "0.0.0.0"]; - } - - // Accompanies Medium.WEB_RTC - message WebRtcCredentials { - optional string peer_id = 1; - optional LocationHint location_hint = 2; - } - - optional Medium medium = 1; - - // Exactly one of the following fields will be set. - optional WifiHotspotCredentials wifi_hotspot_credentials = 2; - optional WifiLanSocket wifi_lan_socket = 3; - optional BluetoothCredentials bluetooth_credentials = 4; - optional WifiAwareCredentials wifi_aware_credentials = 5; - optional WifiDirectCredentials wifi_direct_credentials = 6; - optional WebRtcCredentials web_rtc_credentials = 8; - - // Disable Encryption for this upgrade medium to improve throughput. - optional bool supports_disabling_encryption = 7; - - // An ack will be sent after the CLIENT_INTRODUCTION frame. - optional bool supports_client_introduction_ack = 9; - } - - // Accompanies CLIENT_INTRODUCTION events. - message ClientIntroduction { - optional string endpoint_id = 1; - optional bool supports_disabling_encryption = 2; - } - - // Accompanies CLIENT_INTRODUCTION_ACK events. - message ClientIntroductionAck {} - - optional EventType event_type = 1; - - // Exactly one of the following fields will be set. - optional UpgradePathInfo upgrade_path_info = 2; - optional ClientIntroduction client_introduction = 3; - optional ClientIntroductionAck client_introduction_ack = 4; -} - -message KeepAliveFrame { - // And ack will be sent after receiving KEEP_ALIVE frame. - optional bool ack = 1; -} - -// Informs the remote side to immediately severe the socket connection. -// Used in bandwidth upgrades to get around a race condition, but may be used -// in other situations to trigger a faster disconnection event than waiting for -// socket closed on the remote side. -message DisconnectionFrame { - // Apply safe-to-disconnect protocol if true. - optional bool request_safe_to_disconnect = 1; - - // Ack of receiving Disconnection frame will be sent to the sender - // frame. - optional bool ack_safe_to_disconnect = 2; -} - -// A paired key encryption packet sent between devices, contains signed data. -message PairedKeyEncryptionFrame { - // The encrypted data (raw authentication token for the established - // connection) in byte array format. - optional bytes signed_data = 1; -} - -message MediumMetadata { - // True if local device supports 5GHz. - optional bool supports_5_ghz = 1; - // WiFi LAN BSSID, in the form of a six-byte MAC address: XX:XX:XX:XX:XX:XX - optional string bssid = 2; - // IP address, in network byte order: the highest order byte of the address is - // in byte[0]. - optional bytes ip_address = 3; - // True if local device supports 6GHz. - optional bool supports_6_ghz = 4; - // True if local device has mobile radio. - optional bool mobile_radio = 5; - // The frequency of the WiFi LAN AP(in MHz). Or -1 is not associated with an - // AP over WiFi, -2 represents the active network uses an Ethernet transport. - optional int32 ap_frequency = 6 [default = -1]; - // Available channels on the local device. - optional AvailableChannels available_channels = 7; - // Usable WiFi Direct client channels on the local device. - optional WifiDirectCliUsableChannels wifi_direct_cli_usable_channels = 8; - // Usable WiFi LAN channels on the local device. - optional WifiLanUsableChannels wifi_lan_usable_channels = 9; - // Usable WiFi Aware channels on the local device. - optional WifiAwareUsableChannels wifi_aware_usable_channels = 10; - // Usable WiFi Hotspot STA channels on the local device. - optional WifiHotspotStaUsableChannels wifi_hotspot_sta_usable_channels = 11; -} - -// Available channels on the local device. -message AvailableChannels { - repeated int32 channels = 1 [packed = true]; -} - -// Usable WiFi Direct client channels on the local device. -message WifiDirectCliUsableChannels { - repeated int32 channels = 1 [packed = true]; -} - -// Usable WiFi LAN channels on the local device. -message WifiLanUsableChannels { - repeated int32 channels = 1 [packed = true]; -} - -// Usable WiFi Aware channels on the local device. -message WifiAwareUsableChannels { - repeated int32 channels = 1 [packed = true]; -} - -// Usable WiFi Hotspot STA channels on the local device. -message WifiHotspotStaUsableChannels { - repeated int32 channels = 1 [packed = true]; -} - -// LocationHint is used to specify a location as well as format. -message LocationHint { - // Location is the location, provided in the format specified by format. - optional string location = 1; - - // the format of location. - optional LocationStandard.Format format = 2; -} - -message LocationStandard { - enum Format { - UNKNOWN = 0; - // E164 country codes: - // https://en.wikipedia.org/wiki/List_of_country_calling_codes - // e.g. +1 for USA - E164_CALLING = 1; - - // ISO 3166-1 alpha-2 country codes: - // https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 - ISO_3166_1_ALPHA_2 = 2; - } -} - -// Device capability for OS information. -message OsInfo { - enum OsType { - UNKNOWN_OS_TYPE = 0; - ANDROID = 1; - CHROME_OS = 2; - WINDOWS = 3; - APPLE = 4; - LINUX = 100; // g3 test environment - } - - optional OsType type = 1; -} diff --git a/submissions/sapphire/ProtobufSource/securegcm.proto b/submissions/sapphire/ProtobufSource/securegcm.proto deleted file mode 100644 index 0325f06e..00000000 --- a/submissions/sapphire/ProtobufSource/securegcm.proto +++ /dev/null @@ -1,308 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto2"; - -package securegcm; - -option optimize_for = LITE_RUNTIME; -option java_package = "com.google.security.cryptauth.lib.securegcm"; -option java_outer_classname = "SecureGcmProto"; -option objc_class_prefix = "SGCM"; - -// Message used only during enrollment -// Field numbers should be kept in sync with DeviceInfo in: -// java/com/google/security/cryptauth/backend/services/common/common.proto -message GcmDeviceInfo { - // This field's name does not match the one in DeviceInfo for legacy reasons. - // Consider using long_device_id and device_type instead when enrolling - // non-android devices. - optional fixed64 android_device_id = 1; - - // Used for device_address of DeviceInfo field 2, but for GCM capable devices. - optional bytes gcm_registration_id = 102; - - // Used for device_address of DeviceInfo field 2, but for iOS devices. - optional bytes apn_registration_id = 202; - - // Does the user have notifications enabled for the given device address. - optional bool notification_enabled = 203 [default = true]; - - // Used for device_address of DeviceInfo field 2, a Bluetooth Mac address for - // the device (e.g., to be used with EasyUnlock) - optional string bluetooth_mac_address = 302; - - // SHA-256 hash of the device master key (from the key exchange). - // Differs from DeviceInfo field 3, which contains the actual master key. - optional bytes device_master_key_hash = 103; - - // A SecureMessage.EcP256PublicKey - required bytes user_public_key = 4; - - // device's model name - // (e.g., an android.os.Build.MODEL or UIDevice.model) - optional string device_model = 7; - - // device's locale - optional string locale = 8; - - // The handle for user_public_key (and implicitly, a master key) - optional bytes key_handle = 9; - - // The initial counter value for the device, sent by the device - optional int64 counter = 12 [default = 0]; - - // The Operating System version on the device - // (e.g., an android.os.Build.DISPLAY or UIDevice.systemVersion) - optional string device_os_version = 13; - - // The Operating System version number on the device - // (e.g., an android.os.Build.VERSION.SDK_INT) - optional int64 device_os_version_code = 14; - - // The Operating System release on the device - // (e.g., an android.os.Build.VERSION.RELEASE) - optional string device_os_release = 15; - - // The Operating System codename on the device - // (e.g., an android.os.Build.VERSION.CODENAME or UIDevice.systemName) - optional string device_os_codename = 16; - - // The software version running on the device - // (e.g., Authenticator app version string) - optional string device_software_version = 17; - - // The software version number running on the device - // (e.g., Authenticator app version code) - optional int64 device_software_version_code = 18; - - // Software package information if applicable - // (e.g., com.google.android.apps.authenticator2) - optional string device_software_package = 19; - - // Size of the display in thousandths of an inch (e.g., 7000 mils = 7 in) - optional int32 device_display_diagonal_mils = 22; - - // For Authzen capable devices, their Authzen protocol version - optional int32 device_authzen_version = 24; - - // Not all devices have device identifiers that fit in 64 bits. - optional bytes long_device_id = 29; - - // The device manufacturer name - // (e.g., android.os.Build.MANUFACTURER) - optional string device_manufacturer = 31; - - // Used to indicate which type of device this is. - optional DeviceType device_type = 32 [default = ANDROID]; - - // Fields corresponding to screenlock type/features and hardware features - // should be numbered in the 400 range. - - // Is this device using a secure screenlock (e.g., pattern or pin unlock) - optional bool using_secure_screenlock = 400 [default = false]; - - // Is auto-unlocking the screenlock (e.g., when at "home") supported? - optional bool auto_unlock_screenlock_supported = 401 [default = false]; - - // Is auto-unlocking the screenlock (e.g., when at "home") enabled? - optional bool auto_unlock_screenlock_enabled = 402 [default = false]; - - // Does the device have a Bluetooth (classic) radio? - optional bool bluetooth_radio_supported = 403 [default = false]; - - // Is the Bluetooth (classic) radio on? - optional bool bluetooth_radio_enabled = 404 [default = false]; - - // Does the device hardware support a mobile data connection? - optional bool mobile_data_supported = 405 [default = false]; - - // Does the device support tethering? - optional bool tethering_supported = 406 [default = false]; - - // Does the device have a BLE radio? - optional bool ble_radio_supported = 407 [default = false]; - - // Is the device a "Pixel Experience" Android device? - optional bool pixel_experience = 408 [default = false]; - - // Is the device running in the ARC++ container on a chromebook? - optional bool arc_plus_plus = 409 [default = false]; - - // Is the value set in |using_secure_screenlock| reliable? On some Android - // devices, the platform API to get the screenlock state is not trustworthy. - // See b/32212161. - optional bool is_screenlock_state_flaky = 410 [default = false]; - - // A list of multi-device software features supported by the device. - repeated SoftwareFeature supported_software_features = 411; - - // A list of multi-device software features currently enabled (active) on the - // device. - repeated SoftwareFeature enabled_software_features = 412; - - // The enrollment session id this is sent with - optional bytes enrollment_session_id = 1000; - - // A copy of the user's OAuth token - optional string oauth_token = 1001; -} - -// This enum is used by iOS devices as values for device_display_diagonal_mils -// in GcmDeviceInfo. There is no good way to calculate it on those devices. -enum AppleDeviceDiagonalMils { - // This is the mils diagonal on an iPhone 5. - APPLE_PHONE = 4000; - // This is the mils diagonal on an iPad mini. - APPLE_PAD = 7900; -} - -// This should be kept in sync with DeviceType in: -// java/com/google/security/cryptauth/backend/services/common/common_enums.proto -enum DeviceType { - UNKNOWN = 0; - ANDROID = 1; - CHROME = 2; - IOS = 3; - BROWSER = 4; - OSX = 5; -} - -// MultiDevice features which may be supported and enabled on a device. See -enum SoftwareFeature { - UNKNOWN_FEATURE = 0; - BETTER_TOGETHER_HOST = 1; - BETTER_TOGETHER_CLIENT = 2; - EASY_UNLOCK_HOST = 3; - EASY_UNLOCK_CLIENT = 4; - MAGIC_TETHER_HOST = 5; - MAGIC_TETHER_CLIENT = 6; - SMS_CONNECT_HOST = 7; - SMS_CONNECT_CLIENT = 8; -} - -// A list of "reasons" that can be provided for calling server-side APIs. -// This is particularly important for calls that can be triggered by different -// kinds of events. Please try to keep reasons as generic as possible, so that -// codes can be re-used by various callers in a sensible fashion. -enum InvocationReason { - REASON_UNKNOWN = 0; - // First run of the software package invoking this call - REASON_INITIALIZATION = 1; - // Ordinary periodic actions (e.g. monthly master key rotation) - REASON_PERIODIC = 2; - // Slow-cycle periodic action (e.g. yearly keypair rotation???) - REASON_SLOW_PERIODIC = 3; - // Fast-cycle periodic action (e.g. daily sync for Smart Lock users) - REASON_FAST_PERIODIC = 4; - // Expired state (e.g. expired credentials, or cached entries) was detected - REASON_EXPIRATION = 5; - // An unexpected protocol failure occurred (so attempting to repair state) - REASON_FAILURE_RECOVERY = 6; - // A new account has been added to the device - REASON_NEW_ACCOUNT = 7; - // An existing account on the device has been changed - REASON_CHANGED_ACCOUNT = 8; - // The user toggled the state of a feature (e.g. Smart Lock enabled via BT) - REASON_FEATURE_TOGGLED = 9; - // A "push" from the server caused this action (e.g. a sync tickle) - REASON_SERVER_INITIATED = 10; - // A local address change triggered this (e.g. GCM registration id changed) - REASON_ADDRESS_CHANGE = 11; - // A software update has triggered this - REASON_SOFTWARE_UPDATE = 12; - // A manual action by the user triggered this (e.g. commands sent via adb) - REASON_MANUAL = 13; - // A custom key has been invalidated on the device (e.g. screen lock is - // disabled). - REASON_CUSTOM_KEY_INVALIDATION = 14; - // Periodic action triggered by auth_proximity - REASON_PROXIMITY_PERIODIC = 15; -} - -enum Type { - ENROLLMENT = 0; - TICKLE = 1; - TX_REQUEST = 2; - TX_REPLY = 3; - TX_SYNC_REQUEST = 4; - TX_SYNC_RESPONSE = 5; - TX_PING = 6; - DEVICE_INFO_UPDATE = 7; - TX_CANCEL_REQUEST = 8; - - // DEPRECATED (can be re-used after Aug 2015) - PROXIMITYAUTH_PAIRING = 10; - - // The kind of identity assertion generated by a "GCM V1" device (i.e., - // an Android phone that has registered with us a public and a symmetric - // key) - GCMV1_IDENTITY_ASSERTION = 11; - - // Device-to-device communications are protected by an unauthenticated - // Diffie-Hellman exchange. The InitiatorHello message is simply the - // initiator's public DH key, and is not encoded as a SecureMessage, so - // it doesn't have a tag. - // The ResponderHello message (which is sent by the responder - // to the initiator), on the other hand, carries a payload that is protected - // by the derived shared key. It also contains the responder's - // public DH key. ResponderHelloAndPayload messages have the - // DEVICE_TO_DEVICE_RESPONDER_HELLO tag. - DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD = 12; - - // Device-to-device communications are protected by an unauthenticated - // Diffie-Hellman exchange. Once the initiator and responder - // agree on a shared key (through Diffie-Hellman), they will use messages - // tagged with DEVICE_TO_DEVICE_MESSAGE to exchange data. - DEVICE_TO_DEVICE_MESSAGE = 13; - - // Notification to let a device know it should contact a nearby device. - DEVICE_PROXIMITY_CALLBACK = 14; - - // Device-to-device communications are protected by an unauthenticated - // Diffie-Hellman exchange. During device-to-device authentication, the first - // message from initiator (the challenge) is signed and put into the payload - // of the message sent back to the initiator. - UNLOCK_KEY_SIGNED_CHALLENGE = 15; - - // Specialty (corp only) features - LOGIN_NOTIFICATION = 101; -} - -message GcmMetadata { - required Type type = 1; - optional int32 version = 2 [default = 0]; -} - -message Tickle { - // Time after which this tickle should expire - optional fixed64 expiry_time = 1; -} - -message LoginNotificationInfo { - // Time at which the server received the login notification request. - optional fixed64 creation_time = 2; - - // Must correspond to user_id in LoginNotificationRequest, if set. - optional string email = 3; - - // Host where the user's credentials were used to login, if meaningful. - optional string host = 4; - - // Location from where the user's credentials were used, if meaningful. - optional string source = 5; - - // Type of login, e.g. ssh, gnome-screensaver, or web. - optional string event_type = 6; -} diff --git a/submissions/sapphire/ProtobufSource/securemessage.proto b/submissions/sapphire/ProtobufSource/securemessage.proto deleted file mode 100644 index 5118d357..00000000 --- a/submissions/sapphire/ProtobufSource/securemessage.proto +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Proto definitions for SecureMessage format - -syntax = "proto2"; - -package securemessage; - -option optimize_for = LITE_RUNTIME; -option java_package = "com.google.security.cryptauth.lib.securemessage"; -option java_outer_classname = "SecureMessageProto"; -option objc_class_prefix = "SMSG"; - -message SecureMessage { - // Must contain a HeaderAndBody message - required bytes header_and_body = 1; - // Signature of header_and_body - required bytes signature = 2; -} - -// Supported "signature" schemes (both symmetric key and public key based) -enum SigScheme { - HMAC_SHA256 = 1; - ECDSA_P256_SHA256 = 2; - // Not recommended -- use ECDSA_P256_SHA256 instead - RSA2048_SHA256 = 3; -} - -// Supported encryption schemes -enum EncScheme { - // No encryption - NONE = 1; - AES_256_CBC = 2; -} - -message Header { - required SigScheme signature_scheme = 1; - required EncScheme encryption_scheme = 2; - // Identifies the verification key - optional bytes verification_key_id = 3; - // Identifies the decryption key - optional bytes decryption_key_id = 4; - // Encryption may use an IV - optional bytes iv = 5; - // Arbitrary per-protocol public data, to be sent with the plain-text header - optional bytes public_metadata = 6; - // The length of some associated data this is not sent in this SecureMessage, - // but which will be bound to the signature. - optional uint32 associated_data_length = 7 [default = 0]; -} - -message HeaderAndBody { - // Public data about this message (to be bound in the signature) - required Header header = 1; - // Payload data - required bytes body = 2; -} - -// Must be kept wire-format compatible with HeaderAndBody. Provides the -// SecureMessage code with a consistent wire-format representation that -// remains stable irrespective of protobuf implementation choices. This -// low-level representation of a HeaderAndBody should not be used by -// any code outside of the SecureMessage library implementation/tests. -message HeaderAndBodyInternal { - // A raw (wire-format) byte encoding of a Header, suitable for hashing - required bytes header = 1; - // Payload data - required bytes body = 2; -} - -// ------- -// The remainder of the messages defined here are provided only for -// convenience. They are not needed for SecureMessage proper, but are -// commonly useful wherever SecureMessage might be applied. -// ------- - -// A list of supported public key types -enum PublicKeyType { - EC_P256 = 1; - RSA2048 = 2; - // 2048-bit MODP group 14, from RFC 3526 - DH2048_MODP = 3; -} - -// A convenience proto for encoding NIST P-256 elliptic curve public keys -message EcP256PublicKey { - // x and y are encoded in big-endian two's complement (slightly wasteful) - // Client MUST verify (x,y) is a valid point on NIST P256 - required bytes x = 1; - required bytes y = 2; -} - -// A convenience proto for encoding RSA public keys with small exponents -message SimpleRsaPublicKey { - // Encoded in big-endian two's complement - required bytes n = 1; - optional int32 e = 2 [default = 65537]; -} - -// A convenience proto for encoding Diffie-Hellman public keys, -// for use only when Elliptic Curve based key exchanges are not possible. -// (Note that the group parameters must be specified separately) -message DhPublicKey { - // Big-endian two's complement encoded group element - required bytes y = 1; -} - -message GenericPublicKey { - required PublicKeyType type = 1; - optional EcP256PublicKey ec_p256_public_key = 2; - optional SimpleRsaPublicKey rsa2048_public_key = 3; - // Use only as a last resort - optional DhPublicKey dh2048_public_key = 4; -} diff --git a/submissions/sapphire/ProtobufSource/ukey.proto b/submissions/sapphire/ProtobufSource/ukey.proto deleted file mode 100644 index 327d8d3d..00000000 --- a/submissions/sapphire/ProtobufSource/ukey.proto +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -syntax = "proto2"; - -package securegcm; - -option optimize_for = LITE_RUNTIME; -option java_package = "com.google.security.cryptauth.lib.securegcm"; -option java_outer_classname = "UkeyProto"; - -message Ukey2Message { - enum Type { - UNKNOWN_DO_NOT_USE = 0; - ALERT = 1; - CLIENT_INIT = 2; - SERVER_INIT = 3; - CLIENT_FINISH = 4; - } - - optional Type message_type = 1; // Identifies message type - optional bytes message_data = 2; // Actual message, to be parsed according to - // message_type -} - -message Ukey2Alert { - enum AlertType { - // Framing errors - BAD_MESSAGE = 1; // The message could not be deserialized - BAD_MESSAGE_TYPE = 2; // message_type has an undefined value - INCORRECT_MESSAGE = 3; // message_type received does not correspond to - // expected type at this stage of the protocol - BAD_MESSAGE_DATA = 4; // Could not deserialize message_data as per - // value inmessage_type - - // ClientInit and ServerInit errors - BAD_VERSION = 100; // version is invalid; server cannot find - // suitable version to speak with client. - BAD_RANDOM = 101; // Random data is missing or of incorrect - // length - BAD_HANDSHAKE_CIPHER = 102; // No suitable handshake ciphers were found - BAD_NEXT_PROTOCOL = 103; // The next protocol is missing, unknown, or - // unsupported - BAD_PUBLIC_KEY = 104; // The public key could not be parsed - - // Other errors - INTERNAL_ERROR = 200; // An internal error has occurred. error_message - // may contain additional details for logging - // and debugging. - } - - optional AlertType type = 1; - optional string error_message = 2; -} - -enum Ukey2HandshakeCipher { - RESERVED = 0; - P256_SHA512 = 100; // NIST P-256 used for ECDH, SHA512 used for - // commitment - CURVE25519_SHA512 = 200; // Curve 25519 used for ECDH, SHA512 used for - // commitment -} - -message Ukey2ClientInit { - optional int32 version = 1; // highest supported version for rollback - // protection - optional bytes random = 2; // random bytes for replay/reuse protection - - // One commitment (hash of ClientFinished containing public key) per supported - // cipher - message CipherCommitment { - optional Ukey2HandshakeCipher handshake_cipher = 1; - optional bytes commitment = 2; - } - repeated CipherCommitment cipher_commitments = 3; - - // Next protocol that the client wants to speak. - optional string next_protocol = 4; -} - -message Ukey2ServerInit { - optional int32 version = 1; // highest supported version for rollback - // protection - optional bytes random = 2; // random bytes for replay/reuse protection - - // Selected Cipher and corresponding public key - optional Ukey2HandshakeCipher handshake_cipher = 3; - optional bytes public_key = 4; -} - -message Ukey2ClientFinished { - optional bytes public_key = 1; // public key matching selected handshake - // cipher -} diff --git a/submissions/sapphire/ProtobufSource/wire_format.proto b/submissions/sapphire/ProtobufSource/wire_format.proto deleted file mode 100644 index 6853e22d..00000000 --- a/submissions/sapphire/ProtobufSource/wire_format.proto +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2020 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Brought from: //depot/google3/location/nearby/sharing/proto/wire_format.proto -// At CL 317565061 - -syntax = "proto2"; - -package sharing.nearby; - -// Required in Chrome. -option optimize_for = LITE_RUNTIME; - -// File metadata. Does not include the actual bytes of the file. -// NEXT_ID=6 -message FileMetadata { - enum Type { - UNKNOWN = 0; - IMAGE = 1; - VIDEO = 2; - APP = 3; - AUDIO = 4; - } - - // The human readable name of this file (eg. 'Cookbook.pdf'). - optional string name = 1; - - // The type of file (eg. 'IMAGE' from 'dog.jpg'). Specifying a type helps - // provide a richer experience on the receiving side. - optional Type type = 2 [default = UNKNOWN]; - - // The FILE payload id that will be sent as a follow up containing the actual - // bytes of the file. - optional int64 payload_id = 3; - - // The total size of the file. - optional int64 size = 4; - - // The mimeType of file (eg. 'image/jpeg' from 'dog.jpg'). Specifying a - // mimeType helps provide a richer experience on receiving side. - optional string mime_type = 5 [default = "application/octet-stream"]; - - // A uuid for the attachment. Should be unique across all attachments. - optional int64 id = 6; -} - -// NEXT_ID=5 -message TextMetadata { - enum Type { - UNKNOWN = 0; - TEXT = 1; - // Open with browsers. - URL = 2; - // Open with map apps. - ADDRESS = 3; - // Dial. - PHONE_NUMBER = 4; - } - - // The title of the text content. - optional string text_title = 2; - - // The type of text (phone number, url, address, or plain text). - optional Type type = 3 [default = UNKNOWN]; - - // The BYTE payload id that will be sent as a follow up containing the actual - // bytes of the text. - optional int64 payload_id = 4; - - // The size of the text content. - optional int64 size = 5; - - // A uuid for the attachment. Should be unique across all attachments. - optional int64 id = 6; -} - -// NEXT_ID=5 -message WifiCredentialsMetadata { - enum SecurityType { - UNKNOWN_SECURITY_TYPE = 0; - OPEN = 1; - WPA_PSK = 2; - WEP = 3; - } - - // The Wifi network name. This will be sent in introduction. - optional string ssid = 2; - - // The security type of network (OPEN, WPA_PSK, WEP). - optional SecurityType security_type = 3 [default = UNKNOWN_SECURITY_TYPE]; - - // The BYTE payload id that will be sent as a follow up containing the - // password. - optional int64 payload_id = 4; - - // A uuid for the attachment. Should be unique across all attachments. - optional int64 id = 5; -} - -// A frame used when sending messages over the wire. -// NEXT_ID=3 -message Frame { - enum Version { - UNKNOWN_VERSION = 0; - V1 = 1; - } - optional Version version = 1; - - // Right now there's only 1 version, but if there are more, exactly one of - // the following fields will be set. - optional V1Frame v1 = 2; -} - -// NEXT_ID=7 -message V1Frame { - enum FrameType { - UNKNOWN_FRAME_TYPE = 0; - INTRODUCTION = 1; - RESPONSE = 2; - PAIRED_KEY_ENCRYPTION = 3; - PAIRED_KEY_RESULT = 4; - CERTIFICATE_INFO = 5; - CANCEL = 6; - } - - optional FrameType type = 1; - - // Exactly one of the following fields will be set. - optional IntroductionFrame introduction = 2; - optional ConnectionResponseFrame connection_response = 3; - optional PairedKeyEncryptionFrame paired_key_encryption = 4; - optional PairedKeyResultFrame paired_key_result = 5; - optional CertificateInfoFrame certificate_info = 6; -} - -// An introduction packet sent by the sending side. Contains a list of files -// they'd like to share. -// NEXT_ID=4 -message IntroductionFrame { - repeated FileMetadata file_metadata = 1; - repeated TextMetadata text_metadata = 2; - // The required app package to open the content. May be null. - optional string required_package = 3; - repeated WifiCredentialsMetadata wifi_credentials_metadata = 4; -} - -// A response packet sent by the receiving side. Accepts or rejects the list of -// files. -// NEXT_ID=2 -message ConnectionResponseFrame { - enum Status { - UNKNOWN = 0; - ACCEPT = 1; - REJECT = 2; - NOT_ENOUGH_SPACE = 3; - UNSUPPORTED_ATTACHMENT_TYPE = 4; - TIMED_OUT = 5; - } - - // The receiving side's response. - optional Status status = 1; -} - -// A paired key encryption packet sent between devices, contains signed data. -// NEXT_ID=3 -message PairedKeyEncryptionFrame { - // The encrypted data in byte array format. - optional bytes signed_data = 1; - - // The hash of a certificate id. - optional bytes secret_id_hash = 2; - - // An optional encrypted data in byte array format. - optional bytes optional_signed_data = 3; -} - -// A paired key verification result packet sent between devices. -// NEXT_ID=2 -message PairedKeyResultFrame { - enum Status { - UNKNOWN = 0; - SUCCESS = 1; - FAIL = 2; - UNABLE = 3; - } - - // The verification result. - optional Status status = 1; -} - -// A package containing certificate info to be shared to remote device offline. -// NEXT_ID=2 -message CertificateInfoFrame { - // The public certificates to be shared with remote devices. - repeated PublicCertificate public_certificate = 1; -} - -// A public certificate from the local device. -// NEXT_ID=8 -message PublicCertificate { - // The unique id of the public certificate. - optional bytes secret_id = 1; - - // A bytes representation of a Secret Key owned by contact, to decrypt the - // metadata_key stored within the advertisement. - optional bytes authenticity_key = 2; - - // A bytes representation a public key of X509Certificate, owned by contact, - // to decrypt encrypted UKEY2 (from Nearby Connections API) as a hand shake in - // contact verification phase. - optional bytes public_key = 3; - - // The time in millis from epoch when this certificate becomes effective. - optional int64 start_time = 4; - - // The time in millis from epoch when this certificate expires. - optional int64 end_time = 5; - - // The encrypted metadata in bytes, contains personal information of the - // device/user who created this certificate. Needs to be decrypted into bytes, - // and converted back to EncryptedMetadata object to access fields. - optional bytes encrypted_metadata_bytes = 6; - - // The tag for verifying metadata_encryption_key. - optional bytes metadata_encryption_key_tag = 7; -} - -// NEXT_ID=3 -message WifiCredentials { - // Wi-Fi password. - optional string password = 1; - // True if the network is a hidden network that is not broadcasting its SSID. - // Default is false. - optional bool hidden_ssid = 2 [default = false]; -} \ No newline at end of file From e942d5522197dae272b3737b2d1ddfca1af3a2cf Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:47:22 -0400 Subject: [PATCH 14/16] Delete submissions/sapphire/Sapphire.xcodeproj directory --- .../Sapphire.xcodeproj/project.pbxproj | 986 ------------------ .../contents.xcworkspacedata | 7 - .../xcshareddata/swiftpm/Package.resolved | 60 -- .../IDEFindNavigatorScopes.plist | 5 - .../UserInterfaceState.xcuserstate | Bin 684944 -> 0 bytes .../xcshareddata/xcschemes/Sapphire.xcscheme | 102 -- .../xcdebugger/Breakpoints_v2.xcbkptlist | 6 - .../xcschemes/xcschememanagement.plist | 42 - 8 files changed, 1208 deletions(-) delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.pbxproj delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/UserInterfaceState.xcuserstate delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/xcshareddata/xcschemes/Sapphire.xcscheme delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist delete mode 100644 submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.pbxproj b/submissions/sapphire/Sapphire.xcodeproj/project.pbxproj deleted file mode 100644 index fc9fd989..00000000 --- a/submissions/sapphire/Sapphire.xcodeproj/project.pbxproj +++ /dev/null @@ -1,986 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 77; - objects = { - -/* Begin PBXBuildFile section */ - DA5256792E162B9F00D8F42E /* NearDropDisplayState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5256782E162B9F00D8F42E /* NearDropDisplayState.swift */; }; - DA52567B2E162FA900D8F42E /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA52567A2E162FA900D8F42E /* ShareViewController.swift */; }; - DA52567D2E162FBE00D8F42E /* DeviceListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA52567C2E162FBE00D8F42E /* DeviceListCell.swift */; }; - DA7C49632E15ACA60049937A /* MediaRemoteAdapter in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49622E15ACA60049937A /* MediaRemoteAdapter */; }; - DA7C49642E15ACAA0049937A /* MediaRemoteAdapter in Embed Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49622E15ACA60049937A /* MediaRemoteAdapter */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - DA7C49982E15D33A0049937A /* OutboundNearbyConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498D2E15D33A0049937A /* OutboundNearbyConnection.swift */; }; - DA7C49992E15D33A0049937A /* wire_format.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49942E15D33A0049937A /* wire_format.pb.swift */; }; - DA7C499A2E15D33A0049937A /* securemessage.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49922E15D33A0049937A /* securemessage.pb.swift */; }; - DA7C499B2E15D33A0049937A /* InboundNearbyConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49892E15D33A0049937A /* InboundNearbyConnection.swift */; }; - DA7C499C2E15D33A0049937A /* NearbyConnectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498B2E15D33A0049937A /* NearbyConnectionManager.swift */; }; - DA7C499D2E15D33A0049937A /* Data+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49962E15D33A0049937A /* Data+Extensions.swift */; }; - DA7C499E2E15D33A0049937A /* device_to_device_messages.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498F2E15D33A0049937A /* device_to_device_messages.pb.swift */; }; - DA7C499F2E15D33A0049937A /* ukey.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49932E15D33A0049937A /* ukey.pb.swift */; }; - DA7C49A12E15D33A0049937A /* NearbyConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C498A2E15D33A0049937A /* NearbyConnection.swift */; }; - DA7C49A22E15D33A0049937A /* offline_wire_formats.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49902E15D33A0049937A /* offline_wire_formats.pb.swift */; }; - DA7C49A32E15D33A0049937A /* securegcm.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA7C49912E15D33A0049937A /* securegcm.pb.swift */; }; - DA7C49A52E15D34D0049937A /* SwiftECC in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49A42E15D34D0049937A /* SwiftECC */; }; - DA7C49A82E15D3660049937A /* SwiftProtobuf in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49A72E15D3660049937A /* SwiftProtobuf */; }; - DA7C49AA2E15D3660049937A /* SwiftProtobufPluginLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49A92E15D3660049937A /* SwiftProtobufPluginLibrary */; }; - DA7C49AC2E15D3660049937A /* protoc-gen-swift in Frameworks */ = {isa = PBXBuildFile; productRef = DA7C49AB2E15D3660049937A /* protoc-gen-swift */; }; - DA7C49AD2E15D3800049937A /* libNearbyShare.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49802E15CCA50049937A /* libNearbyShare.dylib */; }; - DA9385462E17B443006C5361 /* DisplayServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA9385452E17B443006C5361 /* DisplayServices.framework */; }; - DABC6CC02E16F57B00A5CF83 /* TransferDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABC6CBC2E16F53E00A5CF83 /* TransferDirection.swift */; }; - DABC6CDD2E17457A00A5CF83 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DABC6CDB2E17457700A5CF83 /* IOKit.framework */; }; - DABC6CDF2E17458500A5CF83 /* UserNotifications.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49B92E15DB160049937A /* UserNotifications.framework */; }; - DABC6CE12E17458600A5CF83 /* UserNotificationsUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49B82E15DB160049937A /* UserNotificationsUI.framework */; }; - DABC6CE32E1749CA00A5CF83 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DABC6CD72E17455F00A5CF83 /* CoreGraphics.framework */; }; - DACBB01D2E20321D00740C9B /* libNearbyShare.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DA7C49802E15CCA50049937A /* libNearbyShare.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; - DAF7D8AB2E207BBC00AB0820 /* SwiftProtobufPluginLibrary in Frameworks */ = {isa = PBXBuildFile; productRef = DAF7D8AA2E207BBC00AB0820 /* SwiftProtobufPluginLibrary */; }; - DAF7D8AE2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = DAF7D8AD2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - DA46CF882DCBCA0100F00EC5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DA46CF6E2DCBCA0000F00EC5 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DA46CF752DCBCA0000F00EC5; - remoteInfo = DynamicNotch; - }; - DA46CF922DCBCA0100F00EC5 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DA46CF6E2DCBCA0000F00EC5 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DA46CF752DCBCA0000F00EC5; - remoteInfo = DynamicNotch; - }; - DA7C49AF2E15D3800049937A /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DA46CF6E2DCBCA0000F00EC5 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DA7C497F2E15CCA50049937A; - remoteInfo = NearbyShare; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - DAE70B782E12300B001F0890 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - DA7C49642E15ACAA0049937A /* MediaRemoteAdapter in Embed Frameworks */, - DACBB01D2E20321D00740C9B /* libNearbyShare.dylib in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; - DAF7D8AC2E207C5100AB0820 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - DAF7D8AE2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - DA46CF762DCBCA0000F00EC5 /* Sapphire.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sapphire.app; sourceTree = BUILT_PRODUCTS_DIR; }; - DA46CF872DCBCA0100F00EC5 /* SapphireTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SapphireTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - DA46CF912DCBCA0100F00EC5 /* SapphireUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SapphireUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - DA5256782E162B9F00D8F42E /* NearDropDisplayState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearDropDisplayState.swift; sourceTree = ""; }; - DA52567A2E162FA900D8F42E /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = ""; }; - DA52567C2E162FBE00D8F42E /* DeviceListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceListCell.swift; sourceTree = ""; }; - DA7C49802E15CCA50049937A /* libNearbyShare.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libNearbyShare.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; - DA7C49892E15D33A0049937A /* InboundNearbyConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InboundNearbyConnection.swift; sourceTree = ""; }; - DA7C498A2E15D33A0049937A /* NearbyConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyConnection.swift; sourceTree = ""; }; - DA7C498B2E15D33A0049937A /* NearbyConnectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NearbyConnectionManager.swift; sourceTree = ""; }; - DA7C498D2E15D33A0049937A /* OutboundNearbyConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutboundNearbyConnection.swift; sourceTree = ""; }; - DA7C498F2E15D33A0049937A /* device_to_device_messages.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = device_to_device_messages.pb.swift; sourceTree = ""; }; - DA7C49902E15D33A0049937A /* offline_wire_formats.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = offline_wire_formats.pb.swift; sourceTree = ""; }; - DA7C49912E15D33A0049937A /* securegcm.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = securegcm.pb.swift; sourceTree = ""; }; - DA7C49922E15D33A0049937A /* securemessage.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = securemessage.pb.swift; sourceTree = ""; }; - DA7C49932E15D33A0049937A /* ukey.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ukey.pb.swift; sourceTree = ""; }; - DA7C49942E15D33A0049937A /* wire_format.pb.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = wire_format.pb.swift; sourceTree = ""; }; - DA7C49962E15D33A0049937A /* Data+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+Extensions.swift"; sourceTree = ""; }; - DA7C49B82E15DB160049937A /* UserNotificationsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotificationsUI.framework; path = System/Library/Frameworks/UserNotificationsUI.framework; sourceTree = SDKROOT; }; - DA7C49B92E15DB160049937A /* UserNotifications.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserNotifications.framework; path = System/Library/Frameworks/UserNotifications.framework; sourceTree = SDKROOT; }; - DA9385432E17B2A4006C5361 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; - DA9385452E17B443006C5361 /* DisplayServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DisplayServices.framework; path = ../../../../System/Library/PrivateFrameworks/DisplayServices.framework; sourceTree = ""; }; - DABC6CBC2E16F53E00A5CF83 /* TransferDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransferDirection.swift; sourceTree = ""; }; - DABC6CCF2E173F0600A5CF83 /* BezelServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = BezelServices.framework; path = ../../../../System/Library/PrivateFrameworks/BezelServices.framework; sourceTree = ""; }; - DABC6CD72E17455F00A5CF83 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - DABC6CDB2E17457700A5CF83 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; - DABC6D012E177F6100A5CF83 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = System/Library/Frameworks/ApplicationServices.framework; sourceTree = SDKROOT; }; - DAF7D8AD2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SwiftProtobuf_SwiftProtobuf.bundle; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ - DA300BA42E1399620022B999 /* Exceptions for "Sapphire" folder in "Sapphire" target */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - App/Info.plist, - ); - target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; - }; - DA7C49BE2E15DC180049937A /* Exceptions for "ObjC" folder in "NearbyShare" target */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - "Bridging-Header.h", - NDNotificationCenterHackery.h, - NDNotificationCenterHackery.m, - PrivateAPI.h, - ); - target = DA7C497F2E15CCA50049937A /* NearbyShare */; - }; - DADB61FD2E1F774400238226 /* Exceptions for "ObjC" folder in "Sapphire" target */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - NDNotificationCenterHackery.m, - ); - target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; - }; -/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ - -/* Begin PBXFileSystemSynchronizedRootGroup section */ - DA183FC92E122AF30056667D /* Sapphire */ = { - isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - DA300BA42E1399620022B999 /* Exceptions for "Sapphire" folder in "Sapphire" target */, - ); - path = Sapphire; - sourceTree = ""; - }; - DA46CF8A2DCBCA0100F00EC5 /* SapphireNotchTests */ = { - isa = PBXFileSystemSynchronizedRootGroup; - path = SapphireNotchTests; - sourceTree = ""; - }; - DA46CF942DCBCA0100F00EC5 /* SapphireNotchUITests */ = { - isa = PBXFileSystemSynchronizedRootGroup; - path = SapphireNotchUITests; - sourceTree = ""; - }; - DA7C49B62E15D7360049937A /* ObjC */ = { - isa = PBXFileSystemSynchronizedRootGroup; - exceptions = ( - DADB61FD2E1F774400238226 /* Exceptions for "ObjC" folder in "Sapphire" target */, - DA7C49BE2E15DC180049937A /* Exceptions for "ObjC" folder in "NearbyShare" target */, - ); - path = ObjC; - sourceTree = ""; - }; -/* End PBXFileSystemSynchronizedRootGroup section */ - -/* Begin PBXFrameworksBuildPhase section */ - DA46CF732DCBCA0000F00EC5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - DABC6CE32E1749CA00A5CF83 /* CoreGraphics.framework in Frameworks */, - DABC6CE12E17458600A5CF83 /* UserNotificationsUI.framework in Frameworks */, - DA7C49632E15ACA60049937A /* MediaRemoteAdapter in Frameworks */, - DABC6CDF2E17458500A5CF83 /* UserNotifications.framework in Frameworks */, - DAF7D8AB2E207BBC00AB0820 /* SwiftProtobufPluginLibrary in Frameworks */, - DA7C49AD2E15D3800049937A /* libNearbyShare.dylib in Frameworks */, - DABC6CDD2E17457A00A5CF83 /* IOKit.framework in Frameworks */, - DA9385462E17B443006C5361 /* DisplayServices.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA46CF842DCBCA0100F00EC5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA46CF8E2DCBCA0100F00EC5 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA7C497E2E15CCA50049937A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - DA7C49AC2E15D3660049937A /* protoc-gen-swift in Frameworks */, - DA7C49AA2E15D3660049937A /* SwiftProtobufPluginLibrary in Frameworks */, - DA7C49A52E15D34D0049937A /* SwiftECC in Frameworks */, - DA7C49A82E15D3660049937A /* SwiftProtobuf in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - DA46CF6D2DCBCA0000F00EC5 = { - isa = PBXGroup; - children = ( - DAF7D8AD2E20801E00AB0820 /* SwiftProtobuf_SwiftProtobuf.bundle */, - DA183FC92E122AF30056667D /* Sapphire */, - DA46CF8A2DCBCA0100F00EC5 /* SapphireNotchTests */, - DA46CF942DCBCA0100F00EC5 /* SapphireNotchUITests */, - DA46CFCE2DCE7B9E00F00EC5 /* Frameworks */, - DA46CF772DCBCA0000F00EC5 /* Products */, - DA7C498E2E15D33A0049937A /* Nearby */, - DA7C49952E15D33A0049937A /* ProtobufGenerated */, - DA7C49972E15D33A0049937A /* Util */, - DA7C49B62E15D7360049937A /* ObjC */, - ); - sourceTree = ""; - }; - DA46CF772DCBCA0000F00EC5 /* Products */ = { - isa = PBXGroup; - children = ( - DA46CF762DCBCA0000F00EC5 /* Sapphire.app */, - DA46CF872DCBCA0100F00EC5 /* SapphireTests.xctest */, - DA46CF912DCBCA0100F00EC5 /* SapphireUITests.xctest */, - DA7C49802E15CCA50049937A /* libNearbyShare.dylib */, - ); - name = Products; - sourceTree = ""; - }; - DA46CFCE2DCE7B9E00F00EC5 /* Frameworks */ = { - isa = PBXGroup; - children = ( - DA9385452E17B443006C5361 /* DisplayServices.framework */, - DA9385432E17B2A4006C5361 /* AppKit.framework */, - DABC6D012E177F6100A5CF83 /* ApplicationServices.framework */, - DABC6CDB2E17457700A5CF83 /* IOKit.framework */, - DABC6CD72E17455F00A5CF83 /* CoreGraphics.framework */, - DABC6CCF2E173F0600A5CF83 /* BezelServices.framework */, - DA7C49B92E15DB160049937A /* UserNotifications.framework */, - DA7C49B82E15DB160049937A /* UserNotificationsUI.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - DA7C498E2E15D33A0049937A /* Nearby */ = { - isa = PBXGroup; - children = ( - DABC6CBC2E16F53E00A5CF83 /* TransferDirection.swift */, - DA7C49892E15D33A0049937A /* InboundNearbyConnection.swift */, - DA52567A2E162FA900D8F42E /* ShareViewController.swift */, - DA52567C2E162FBE00D8F42E /* DeviceListCell.swift */, - DA7C498A2E15D33A0049937A /* NearbyConnection.swift */, - DA7C498B2E15D33A0049937A /* NearbyConnectionManager.swift */, - DA5256782E162B9F00D8F42E /* NearDropDisplayState.swift */, - DA7C498D2E15D33A0049937A /* OutboundNearbyConnection.swift */, - ); - path = Nearby; - sourceTree = ""; - }; - DA7C49952E15D33A0049937A /* ProtobufGenerated */ = { - isa = PBXGroup; - children = ( - DA7C498F2E15D33A0049937A /* device_to_device_messages.pb.swift */, - DA7C49902E15D33A0049937A /* offline_wire_formats.pb.swift */, - DA7C49912E15D33A0049937A /* securegcm.pb.swift */, - DA7C49922E15D33A0049937A /* securemessage.pb.swift */, - DA7C49932E15D33A0049937A /* ukey.pb.swift */, - DA7C49942E15D33A0049937A /* wire_format.pb.swift */, - ); - path = ProtobufGenerated; - sourceTree = ""; - }; - DA7C49972E15D33A0049937A /* Util */ = { - isa = PBXGroup; - children = ( - DA7C49962E15D33A0049937A /* Data+Extensions.swift */, - ); - path = Util; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - DA7C497C2E15CCA50049937A /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - DA46CF752DCBCA0000F00EC5 /* Sapphire */ = { - isa = PBXNativeTarget; - buildConfigurationList = DA46CF9B2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "Sapphire" */; - buildPhases = ( - DA46CF722DCBCA0000F00EC5 /* Sources */, - DA46CF732DCBCA0000F00EC5 /* Frameworks */, - DA46CF742DCBCA0000F00EC5 /* Resources */, - DAE70B782E12300B001F0890 /* Embed Frameworks */, - DAF7D8AC2E207C5100AB0820 /* CopyFiles */, - ); - buildRules = ( - ); - dependencies = ( - DA7C49B02E15D3800049937A /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - DA183FC92E122AF30056667D /* Sapphire */, - DA7C49B62E15D7360049937A /* ObjC */, - ); - name = Sapphire; - packageProductDependencies = ( - DA7C49622E15ACA60049937A /* MediaRemoteAdapter */, - DAF7D8AA2E207BBC00AB0820 /* SwiftProtobufPluginLibrary */, - ); - productName = DynamicNotch; - productReference = DA46CF762DCBCA0000F00EC5 /* Sapphire.app */; - productType = "com.apple.product-type.application"; - }; - DA46CF862DCBCA0100F00EC5 /* SapphireTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = DA46CF9E2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireTests" */; - buildPhases = ( - DA46CF832DCBCA0100F00EC5 /* Sources */, - DA46CF842DCBCA0100F00EC5 /* Frameworks */, - DA46CF852DCBCA0100F00EC5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - DA46CF892DCBCA0100F00EC5 /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - DA46CF8A2DCBCA0100F00EC5 /* SapphireNotchTests */, - ); - name = SapphireTests; - packageProductDependencies = ( - ); - productName = DynamicNotchTests; - productReference = DA46CF872DCBCA0100F00EC5 /* SapphireTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - DA46CF902DCBCA0100F00EC5 /* SapphireUITests */ = { - isa = PBXNativeTarget; - buildConfigurationList = DA46CFA12DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireUITests" */; - buildPhases = ( - DA46CF8D2DCBCA0100F00EC5 /* Sources */, - DA46CF8E2DCBCA0100F00EC5 /* Frameworks */, - DA46CF8F2DCBCA0100F00EC5 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - DA46CF932DCBCA0100F00EC5 /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - DA46CF942DCBCA0100F00EC5 /* SapphireNotchUITests */, - ); - name = SapphireUITests; - packageProductDependencies = ( - ); - productName = DynamicNotchUITests; - productReference = DA46CF912DCBCA0100F00EC5 /* SapphireUITests.xctest */; - productType = "com.apple.product-type.bundle.ui-testing"; - }; - DA7C497F2E15CCA50049937A /* NearbyShare */ = { - isa = PBXNativeTarget; - buildConfigurationList = DA7C49862E15CCA50049937A /* Build configuration list for PBXNativeTarget "NearbyShare" */; - buildPhases = ( - DA7C497C2E15CCA50049937A /* Headers */, - DA7C497D2E15CCA50049937A /* Sources */, - DA7C497E2E15CCA50049937A /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = NearbyShare; - packageProductDependencies = ( - DA7C49A42E15D34D0049937A /* SwiftECC */, - DA7C49A72E15D3660049937A /* SwiftProtobuf */, - DA7C49A92E15D3660049937A /* SwiftProtobufPluginLibrary */, - DA7C49AB2E15D3660049937A /* protoc-gen-swift */, - ); - productName = NearbyShare; - productReference = DA7C49802E15CCA50049937A /* libNearbyShare.dylib */; - productType = "com.apple.product-type.library.dynamic"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - DA46CF6E2DCBCA0000F00EC5 /* Project object */ = { - isa = PBXProject; - attributes = { - BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1630; - LastUpgradeCheck = 1640; - TargetAttributes = { - DA46CF752DCBCA0000F00EC5 = { - CreatedOnToolsVersion = 16.3; - }; - DA46CF862DCBCA0100F00EC5 = { - CreatedOnToolsVersion = 16.3; - TestTargetID = DA46CF752DCBCA0000F00EC5; - }; - DA46CF902DCBCA0100F00EC5 = { - CreatedOnToolsVersion = 16.3; - TestTargetID = DA46CF752DCBCA0000F00EC5; - }; - DA7C497F2E15CCA50049937A = { - CreatedOnToolsVersion = 16.4; - }; - }; - }; - buildConfigurationList = DA46CF712DCBCA0000F00EC5 /* Build configuration list for PBXProject "Sapphire" */; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = DA46CF6D2DCBCA0000F00EC5; - minimizedProjectReferenceProxies = 1; - packageReferences = ( - DAD47CD22E13C3DB001B70C8 /* XCRemoteSwiftPackageReference "SwiftECC" */, - DA7C49612E15ACA60049937A /* XCRemoteSwiftPackageReference "mediaremote-adapter" */, - DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */, - ); - preferredProjectObjectVersion = 77; - productRefGroup = DA46CF772DCBCA0000F00EC5 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - DA46CF752DCBCA0000F00EC5 /* Sapphire */, - DA46CF862DCBCA0100F00EC5 /* SapphireTests */, - DA46CF902DCBCA0100F00EC5 /* SapphireUITests */, - DA7C497F2E15CCA50049937A /* NearbyShare */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - DA46CF742DCBCA0000F00EC5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA46CF852DCBCA0100F00EC5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA46CF8F2DCBCA0100F00EC5 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - DA46CF722DCBCA0000F00EC5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA46CF832DCBCA0100F00EC5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA46CF8D2DCBCA0100F00EC5 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DA7C497D2E15CCA50049937A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DA52567B2E162FA900D8F42E /* ShareViewController.swift in Sources */, - DA52567D2E162FBE00D8F42E /* DeviceListCell.swift in Sources */, - DA7C49982E15D33A0049937A /* OutboundNearbyConnection.swift in Sources */, - DA7C49992E15D33A0049937A /* wire_format.pb.swift in Sources */, - DA7C499A2E15D33A0049937A /* securemessage.pb.swift in Sources */, - DA7C499B2E15D33A0049937A /* InboundNearbyConnection.swift in Sources */, - DA7C499C2E15D33A0049937A /* NearbyConnectionManager.swift in Sources */, - DABC6CC02E16F57B00A5CF83 /* TransferDirection.swift in Sources */, - DA7C499D2E15D33A0049937A /* Data+Extensions.swift in Sources */, - DA7C499E2E15D33A0049937A /* device_to_device_messages.pb.swift in Sources */, - DA7C499F2E15D33A0049937A /* ukey.pb.swift in Sources */, - DA7C49A12E15D33A0049937A /* NearbyConnection.swift in Sources */, - DA5256792E162B9F00D8F42E /* NearDropDisplayState.swift in Sources */, - DA7C49A22E15D33A0049937A /* offline_wire_formats.pb.swift in Sources */, - DA7C49A32E15D33A0049937A /* securegcm.pb.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - DA46CF892DCBCA0100F00EC5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; - targetProxy = DA46CF882DCBCA0100F00EC5 /* PBXContainerItemProxy */; - }; - DA46CF932DCBCA0100F00EC5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DA46CF752DCBCA0000F00EC5 /* Sapphire */; - targetProxy = DA46CF922DCBCA0100F00EC5 /* PBXContainerItemProxy */; - }; - DA7C49B02E15D3800049937A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DA7C497F2E15CCA50049937A /* NearbyShare */; - targetProxy = DA7C49AF2E15D3800049937A /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - DA46CF992DCBCA0100F00EC5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 14.6; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - DA46CF9A2DCBCA0100F00EC5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEAD_CODE_STRIPPING = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 14.6; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = macosx; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - DA46CF9C2DCBCA0100F00EC5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = Sapphire/Sapphire.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = KVQFWJ7C7S; - ENABLE_HARDENED_RUNTIME = YES; - ENABLE_INCOMING_NETWORK_CONNECTIONS = YES; - ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; - FRAMEWORK_SEARCH_PATHS = ""; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = Sapphire/App/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = Sapphire; - INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; - INFOPLIST_KEY_LSUIElement = YES; - INFOPLIST_KEY_NSAppleEventsUsageDescription = "Needed for HUD and music implmentation"; - INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Used to show new connections and battery low notifications"; - INFOPLIST_KEY_NSFocusStatusUsageDescription = "Needed to provide live focus updates"; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; - INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Needed for nearby share functionality"; - INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "Needed to provide live weather updates"; - INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Needed to provide live weather updates"; - INFOPLIST_KEY_NSMainStoryboardFile = Main; - INFOPLIST_KEY_NSMicrophoneUsageDescription = "Used for Gemini Live"; - INFOPLIST_KEY_NSPrincipalClass = NSApplication; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MARKETING_VERSION = 1.0; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = com.shariq.sapphire; - PRODUCT_NAME = "$(TARGET_NAME)"; - REGISTER_APP_GROUPS = YES; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "ObjC/Bridging-Header.h"; - SWIFT_VERSION = 5.0; - SYSTEM_FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); - }; - name = Debug; - }; - DA46CF9D2DCBCA0100F00EC5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CODE_SIGN_ENTITLEMENTS = Sapphire/Sapphire.entitlements; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = KVQFWJ7C7S; - ENABLE_HARDENED_RUNTIME = YES; - ENABLE_INCOMING_NETWORK_CONNECTIONS = YES; - ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; - FRAMEWORK_SEARCH_PATHS = ""; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_FILE = Sapphire/App/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = Sapphire; - INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; - INFOPLIST_KEY_LSUIElement = YES; - INFOPLIST_KEY_NSAppleEventsUsageDescription = "Needed for HUD and music implmentation"; - INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Used to show new connections and battery low notifications"; - INFOPLIST_KEY_NSFocusStatusUsageDescription = "Needed to provide live focus updates"; - INFOPLIST_KEY_NSHumanReadableCopyright = ""; - INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Needed for nearby share functionality"; - INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "Needed to provide live weather updates"; - INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "Needed to provide live weather updates"; - INFOPLIST_KEY_NSMainStoryboardFile = Main; - INFOPLIST_KEY_NSMicrophoneUsageDescription = "Used for Gemini Live"; - INFOPLIST_KEY_NSPrincipalClass = NSApplication; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MARKETING_VERSION = 1.0; - OTHER_LDFLAGS = ""; - PRODUCT_BUNDLE_IDENTIFIER = com.shariq.sapphire; - PRODUCT_NAME = "$(TARGET_NAME)"; - REGISTER_APP_GROUPS = YES; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OBJC_BRIDGING_HEADER = "ObjC/Bridging-Header.h"; - SWIFT_VERSION = 5.0; - SYSTEM_FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", - ); - }; - name = Release; - }; - DA46CF9F2DCBCA0100F00EC5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - GENERATE_INFOPLIST_FILE = YES; - MACOSX_DEPLOYMENT_TARGET = 15.4; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sapphire.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Sapphire"; - }; - name = Debug; - }; - DA46CFA02DCBCA0100F00EC5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - GENERATE_INFOPLIST_FILE = YES; - MACOSX_DEPLOYMENT_TARGET = 15.4; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sapphire.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Sapphire"; - }; - name = Release; - }; - DA46CFA22DCBCA0100F00EC5 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = DynamicNotch; - }; - name = Debug; - }; - DA46CFA32DCBCA0100F00EC5 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = YES; - GENERATE_INFOPLIST_FILE = YES; - MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = shariq.DynamicNotchUITests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_EMIT_LOC_STRINGS = NO; - SWIFT_VERSION = 5.0; - TEST_TARGET_NAME = DynamicNotch; - }; - name = Release; - }; - DA7C49872E15CCA50049937A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = KVQFWJ7C7S; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = ""; - EXECUTABLE_PREFIX = lib; - LD_DYLIB_INSTALL_NAME = "@rpath/libNearbyShare.dylib"; - MACOSX_DEPLOYMENT_TARGET = 14.6; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - DA7C49882E15CCA50049937A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = KVQFWJ7C7S; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = ""; - EXECUTABLE_PREFIX = lib; - LD_DYLIB_INSTALL_NAME = "@rpath/libNearbyShare.dylib"; - MACOSX_DEPLOYMENT_TARGET = 14.6; - PRODUCT_NAME = "$(TARGET_NAME)"; - SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - DA46CF712DCBCA0000F00EC5 /* Build configuration list for PBXProject "Sapphire" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DA46CF992DCBCA0100F00EC5 /* Debug */, - DA46CF9A2DCBCA0100F00EC5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - DA46CF9B2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "Sapphire" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DA46CF9C2DCBCA0100F00EC5 /* Debug */, - DA46CF9D2DCBCA0100F00EC5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - DA46CF9E2DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DA46CF9F2DCBCA0100F00EC5 /* Debug */, - DA46CFA02DCBCA0100F00EC5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - DA46CFA12DCBCA0100F00EC5 /* Build configuration list for PBXNativeTarget "SapphireUITests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DA46CFA22DCBCA0100F00EC5 /* Debug */, - DA46CFA32DCBCA0100F00EC5 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - DA7C49862E15CCA50049937A /* Build configuration list for PBXNativeTarget "NearbyShare" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DA7C49872E15CCA50049937A /* Debug */, - DA7C49882E15CCA50049937A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCRemoteSwiftPackageReference section */ - DA7C49612E15ACA60049937A /* XCRemoteSwiftPackageReference "mediaremote-adapter" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/ejbills/mediaremote-adapter.git"; - requirement = { - branch = master; - kind = branch; - }; - }; - DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/swift-protobuf.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.30.0; - }; - }; - DAD47CD22E13C3DB001B70C8 /* XCRemoteSwiftPackageReference "SwiftECC" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/leif-ibsen/SwiftECC.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 5.5.0; - }; - }; -/* End XCRemoteSwiftPackageReference section */ - -/* Begin XCSwiftPackageProductDependency section */ - DA7C49622E15ACA60049937A /* MediaRemoteAdapter */ = { - isa = XCSwiftPackageProductDependency; - package = DA7C49612E15ACA60049937A /* XCRemoteSwiftPackageReference "mediaremote-adapter" */; - productName = MediaRemoteAdapter; - }; - DA7C49A42E15D34D0049937A /* SwiftECC */ = { - isa = XCSwiftPackageProductDependency; - package = DAD47CD22E13C3DB001B70C8 /* XCRemoteSwiftPackageReference "SwiftECC" */; - productName = SwiftECC; - }; - DA7C49A72E15D3660049937A /* SwiftProtobuf */ = { - isa = XCSwiftPackageProductDependency; - package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; - productName = SwiftProtobuf; - }; - DA7C49A92E15D3660049937A /* SwiftProtobufPluginLibrary */ = { - isa = XCSwiftPackageProductDependency; - package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; - productName = SwiftProtobufPluginLibrary; - }; - DA7C49AB2E15D3660049937A /* protoc-gen-swift */ = { - isa = XCSwiftPackageProductDependency; - package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; - productName = "protoc-gen-swift"; - }; - DAF7D8AA2E207BBC00AB0820 /* SwiftProtobufPluginLibrary */ = { - isa = XCSwiftPackageProductDependency; - package = DA7C49A62E15D3660049937A /* XCRemoteSwiftPackageReference "swift-protobuf" */; - productName = SwiftProtobufPluginLibrary; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = DA46CF6E2DCBCA0000F00EC5 /* Project object */; -} diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a6..00000000 --- a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index e09f56e8..00000000 --- a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,60 +0,0 @@ -{ - "originHash" : "bbf74e37c041f8e77021c1d7c946dd6a4df5cfc4c317708e65974eb0e4b73cda", - "pins" : [ - { - "identity" : "asn1", - "kind" : "remoteSourceControl", - "location" : "https://github.com/leif-ibsen/ASN1", - "state" : { - "revision" : "e38d1b8b43d8b53ffadde9836f34289176bb7a0c", - "version" : "2.7.0" - } - }, - { - "identity" : "bigint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/leif-ibsen/BigInt", - "state" : { - "revision" : "afb70a0038bfbba845271b60fa9a58d5840f8017", - "version" : "1.21.0" - } - }, - { - "identity" : "digest", - "kind" : "remoteSourceControl", - "location" : "https://github.com/leif-ibsen/Digest", - "state" : { - "revision" : "95ba89b494aaff5f3cd2933c03b9a890323dbf2c", - "version" : "1.13.0" - } - }, - { - "identity" : "mediaremote-adapter", - "kind" : "remoteSourceControl", - "location" : "https://github.com/ejbills/mediaremote-adapter.git", - "state" : { - "branch" : "master", - "revision" : "3529aa25023082a2ceadebcd2c9c4a9430ee96b9" - } - }, - { - "identity" : "swift-protobuf", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-protobuf.git", - "state" : { - "revision" : "102a647b573f60f73afdce5613a51d71349fe507", - "version" : "1.30.0" - } - }, - { - "identity" : "swiftecc", - "kind" : "remoteSourceControl", - "location" : "https://github.com/leif-ibsen/SwiftECC.git", - "state" : { - "revision" : "85c529c9c56b649a8d8edcef60aab3925ab0f69f", - "version" : "5.5.0" - } - } - ], - "version" : 3 -} diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist deleted file mode 100644 index 5dd5da85..00000000 --- a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/IDEFindNavigatorScopes.plist +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/UserInterfaceState.xcuserstate b/submissions/sapphire/Sapphire.xcodeproj/project.xcworkspace/xcuserdata/Shariq.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index d6f66518101597fcc0834002559f61a60fab28ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 684944 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 z

KTL)GOfPq<>AK1Y>Iv<|0ED?cG9n_hH1>(_ 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%0AQ;eg3qA>XJSnUF-}POWx#8~MS0N6&VX_N zP-3P7F2EnF4SHZ;Om+C2wfh4iV;eC4tn`z>UMiu$0AgV^qbH`i;Q?6QcEhXZ;T1&Q z6}Fbp<)ydbr%H)8u_c$?colSuZ%P+*C%UZdi9-820go~_(&O!JdpaY1j0{9>w+G-f z<++B^hbbbCgq#pbs)Dm*S%L`E=BT!=K*H{>KM7GM3%W$*bx%6xmTf13>6&S#W?QL??J2!_$Jzdc8<|KQAipIS3%l)fd%nwIm4u>q+~O zMVn*6Eoj>#?}{#V?jQg`1Oyr#AZ&WGFo=X=2k_ajSPu1jw(P+KB{M7WT=KN!Wn5>O z<)>D7fpeOFVu>Sb_3kQNn77R?EtTCORfn5y(aajNv2p7z&;>sIL$}t(dy|v4-|iEr zrrcdF1hF4)G`9VGJ1;4Z zLw?I=^_BKgTh&#SS~l8?=9SvC`Y^V|eVmZN@!VCj=Eh-m)w9KqQ+H`f5H_8_f)yX` z6-=Ks>SqN`i=i7`_0U0o>g7;9$wT0H*QNZz**;AsH=AWb1<*#YmQEcYxOn5WujiqW@r%D?6b1b;#~^F{jrKL@^&$i1roy4ld$y z-xvL)Ejy%rZiZ#@o*L^`Ur%9Em=7tz0XBZhmg-O7G2GXtSiucX2gm$G!0(zVCBcy{Fs zrgi7KcpHK2hzxs24oKhX_St5_6 zt)ci_XRNrl!%&GPH^UP21bY(kJPl3UX5&!#G^{&N(CyjPES%Z{2&+KHcGYz_^2}&s z;&>0J`t($xA$6+K(7UT+D7__z*Wj+d1f8qE-^8`egBAJfC~J3Z9cC=Q^m`lR(p466 zI--OS2R^#w%t+;d3{0($d@NQ|JExF^Ko2SOBetGgOUy`A3U=; zJf>-YcB9zQvOTlMywTQ1I6VNAPUW4cKDbjizb&YxePH|7>J$ln^bY!&ZE|&69Sdv& z#_DzZX~0oj_O=EPdBVbq3zLds(Rgl)d!c-5PxDv&Ee{K|c`DA85LU7si95_*W8G?G zCWV}p%Kky9>s$;nIB^`nyE{4GNCSf-MGSefU{YU8442}mL)-?8nw&UKS+V;R0HlyB z-MhkCIV;0?dd5&Z0s7mHb~a#zc^;DKq$j06?s4S;cQGVs47*-rOZkSH=iyWU;AFA# ztR^r_7-x=>E@YIHW(pJWYNfmNwm}sZ)K1H?gtbw{k-MQ*zRmBUiY3);Xew@XZ+1{g z^z=N@2Rc{JQv(Aow%3mI)z;_jRQAY&r-}10VXyBq_?^;%V)3T(SWum2(ae(2kyb52 z#$%ml0eMO=f6I~ppLS3J|3}x>06M0688%FTasU$KZ_h4_M>+D-*xk8#tbokwGMhm*?;Zp{2e5GGG@C-E zAr&B?2ye6M-tKU!MZl`Ww$ksG*onw4G@JQQq-sSd-KPQt*+{{)uj(nuOPU+Ib%w7I zxEBDMSGRKlE9`_{S6V_}`@jO!T>Zk2<{5U27Ib(%tBl~>4lcpEtpOk*ZPxF|GYAU6 zx{~-6^&m3xUL>Czwr3a4K{Js@pPwi7a&RK6NlOC73+ZbYmC@)R0_1?t!K>TD}(U)V8k!0NOi@oACuk$N1%MnDnV zNO4IBz<~tZOG#0g!HFO0@$%9YRFN9aWi|Hk%rZ%17ViT2M?et(;bR=dA)@J%S0V^c ziIgMJ+O;6*P-OQqCKK!hB*pi8Q&wIaBqi@k4~_bw4A)O{eB%6k7a(XhZ$^N=c2z(E z`Ozo05(|zz6|k25x~CU#szpGyf@<}IqniZ4m}gc6 zT~XK06g$ViinNn{z2bJ}-+-kl|4r@NiD+r60x@quyX!Ayoy?~s9WcZWh46q7ZzhbL zjg#(?Cuz95mr;23#hrT3Ryt+SF+ZbI^PYMg1RO4lu1q5h-k#D}YDyl01Ax=&`v<9f zo#z|xT3qB+#4EwAZo#VUq(xHlp2wyOc6G2x;Gr=NsV_>;w433)7<(+zzgM7CKIN5^ zSL4B%v7h>%_9P%ckUc*E$cquxp%+&q-up*iT%)Zk?x%xYoD_tD&irc}0#Y<(M+}Zh zfh`s;BEEoV?z}0B9ky8=ir|YeqTzRl^-qxJ{A%%bKd5|w0#IqhZD$U=Bp1>S3I%)0#9=y;O7WSmq00mYMjHv2yWmb!sc+N$uy)EC z2U&j;(x{WfmR^jHDFQ2dQrE7`2Ax5VE4&ck6X5ycAz0}dEb2mER`Ru$=~p{V=yXs% zP(E+F&~5VGZu3F7CfCgK&X-{vI@ih~;AnDohtqoiHI3ZhoR6LqP;#dgNPuFz{1iG%-yGw$$2F*qf5HxW-*IQni5gI26X7)A`gPkR8A0l6;Yt^u< z%F}_o5D4&gUc@KMKX?ptFo{otHGe4T%fJzI1|U**sH5yn{k1Ew zDRiv(+b~-E>TNp|bWjr#yf`7)>2`(cLu}6mo~$r~rLbG`n4)hMkD8xAc*tM#)d8D5 z8(pO?&X;JmeC4+p0Rj@PgDjSVRjoJCl#d7}4AW3+W3|`C06=x9ogL`%Htqya*H9GR zKmsUrRE3j7o6{=g97xJub!W&jDJMCdz2!Z^ncf8mFSBV8TZ*pkq1;wdNX5v7Rv?1| z74i8#%K7GAxplOy@{_QVrC-UCTOr=Y3m~YL9(_un9_xxuUPPif*?aYmXBw}B%2r7W zeuX5(AZ8Pwy{ubJTTL>a+WQ$S1D1~+3{FcDO!sVw)A8P7mevWaJ=mL-5nuC+${j>9 zNEX#mQ|?Bf_P%q5#wt4zXtFT^MP9fY*9PLe00Tij=9|-_9w(OM(%bj47WTB=Gq6O+ z*}mcQZvzqmsU-sgvx=m+Cbcf){7NlQPNkZ_vAYzORy~c43V8?Zv3UX@MQ+VDtDe*} z4)I6_GXo{_TykG>w`Xy^i;W*-iBf)_uC&;uLxUOd{)CmMdzhD`IiKApZ=t8Hbad1f zFbhzKjtf&GUF41VQh`J~Cgp2gsmo7-A_s{cZ!htveM}_p z;}7=*6nI634+{0B2@EiqjwqF5ugEnc`fDj^2#Jr;!vRnCfDaF62Y{f8TmtyKKei=o z_fu%G%vSSL(TpdsdP1)3kdBRDJI@o!!~6IE5|}FbAtLSj{1Qic`S6e(JTf;w&NCp< zV_pM69AeIEfDs;vx&K?I!a5<5-|{42E7y8opSd2ck6rcRISt$7Yk;P1)4OSqvj016xB=NF9@XzrR!HZ}71@JV2LrZ-G)e0ENY;K9eq` zGyg=8n8fr5F(u^Y*-|8iWN%?-sCkOc<+_K6-F45Bg|whdwWfLYY-%%4vf_E%(zgow zKkW1~d$re9mCov4IS(tRmznGY6tY+4wSY!zdLJQoXBt=bU+!yt~f*!94@jm>R(GF$BL=>dK#7|9%ttou?ShQ`DFqm^nd|h0{iKsvYg^ zOm;^t95x|W)TSQN(SQN0ljRXkM;UF;v$3+Ct{eu1Kl^~6DG<2&4#sAl+td_?e*WD& zG6no|N$fT8XWs%8SUD|gOx<|#&r~mzT=Kp?)vX9{VtsI%pF9mv?a`Jget-^71>%Vp zgOzlycQ1+jX~UTSKa1|am+-+Zi5)wc6eEzXQU6&BP`W^?t; zL6OKpUW_^;1*~%#(-BQAgqP9N;UtWG7Q~r@GWS6pKA%Dn!#pk-ix8q9Sf+K3aom$x z+q1fE7x2vJi~5IF$fBo-kmmWYFSa@UhFT|JXcnL=v?c}hdaS)t567FeH_IPsY|X7? z9Gg~3i=5w`pt{!8KdIOt+rB<_h0SIP0Wdz94AAx~Eyl)V7J6|N%(fUk-O9HK_ zoe)l&io`t8gqZf~^?H2}MsS?s}2 z*=Z;(yUOWgU{7=b0}zKKd=3#)2$1WOtUl7cs~mX%3sW9^r1c3BUaQ)t239=}SoEX5 zh+FL`$Emen1%0B2=U-8q@0(jEkf(oF`MZc^w;3^Mfo^WmrjU zA-B8IYwn#+%IGBBygo&I`3D5N+VfNw-|G@dY1Sswo|K>KrNL$zor7$+Xo`?qIbAsO zHlQPR(@avJ&S3Tms8Dn7y9&(!4v_~4L^W%lgY2wH~~viVB?i0 zCC?ln<)1iR01;T(tl6w*AR=|WofFL+@$`CT# z>y_G2celkq^ucQdfFx3Q@d*@f_0O>0b;O7&N8$m{H@|hFFx)weV9En;^-QH|0>nj0 zDsNLQTIwF^oY1(gslIt%CbX3LY>&P@aJNDoa_#-!mHdAMc5&UVpzPwWTvwE4>&|Nl ze%`_UYEKzpyj*{->?!5K>*|NrNIvRk!K=YKZ8-BH-~a-)5a_G^;>wB{(JYicUFgG0 z79frfv*PPm){KSunrREL-_m>fj_-;--;TpcmIu(pWUemrK*EEe(QqdO8djUiazEU| znY4kPH`z@tJGh)F?#80xNZGJsYSz24c<=yaj;fbW%xvKxq4k8tAqjY&)w2nP@9r%fk9IB3@2T{K$X z?*^{ru#<|(lOcMn5z+Vzxmy>opf^#dFU&Fs)o~e>I7$j)`?HD;1D$(BR1Sb2vE(x(c=X4JKUmUOSo@xwyhsxoXLcLrYEd0Hx=U`t)|%2b z=cUziJ8JCofZ`ZoXtWwQkbw08tp}TwPABmh0e|TRK_9?ykOj_bp(%^=Q%%tNx&}-* zttSR%#7p8CtMeF&SS9J3dpG{g&+=Z3ZLS87Bf3QoV z-$}V=J>`qxeFBS#!V)lMg=IHi^R?DlkeJt|oQ_miwT_uC0U1CmZ!xo-vy{v zc9O*vW#aN@H$G6^7uWi~9`8kI7ML2IQPD<&j}#|mAwck2&3M@mXs98CCM7h7WMD82 zE!_h^pS<8{(&R@x(u}g_^|FQn1Zrj-5(moe$;^7Vr=dEGr>C#;dO`j0GQ}0H{Ym}S zsz%^}aeDc{3oimjDM>|H!xPM@a#D)t{w5{YXqQF=!1&_UY<|z$!K?la05fV-aB-1K zJfMx)+o1fwExrv{Erx}p^e!OzaElM6fVv#VdI3nmy?t(pnOXXfl)?c) z)3*R!xK{;X1}PQ|LYb?x75DquytmBlQatf&T8^_%;^W6nim2?UXYaOWz_Jx){XQ|D zYhmy%yCYdSeVSOntoEblt!3MV=kuJsD08*ugbBQ~T-O#VMDmk+OT7=HOxslI|8MW= zT_ih>c=h05=TLAu9OxDYHd3fRz+eYSHGFv`MSHUAMDPX{;ckzh6|ySsm1xPz2W+awLjRB+u^Sf+c)rfE9xR zGg#}%pwRQR_GaA8#xNbsjLg_Y3Kt}h%r&~aDYcREo|PSA4!hMtSKlg_v8eo5JzJl% z@HJ&P9&~5<5nz|jBA#4MI9u&@jY_|qC7~>f{XE^8TqRxFOh0Ivc`fFe#1>kmxOpu%dK_aJcUy}l%+9b@*sYJ@6N2_v@s^?&+!`Ad<#GXQ|sgztEDOwr;J33 zs}hh&D^w5jFzO79O1ca2%H#Cpb*u& z1VdwK=u@oFpt||~{_ApNp_|ouW^A(x1Rb{ zBBLm9{bhJVa>2Vjx_R9vRYA7n#`6#Ectk$v0ft?L-N%z!C~#&BqJ0;F_VAW%OHAlF|j$?W*J9e#G)MK}_FDV!y&j zGM=G&Dni$Ct5mdR$L&)geSSPucbw<-N;<6b%I(!-*-OH!_0hM?u2S{6iYiA^R}GB7 zl8R@**>GBr`;~bvs?DV_=qp-1!9`scHNl29RrE@YRpzy6S9_gxOce+yHTR?`HImy+KoH1N4gMwx7 zB-j#@l3Mjun3>uIBv2-Hs{m?&bM&k89GA{oG--!KN%D0v<(f9Z(ze~`cm~>5TMmJz z8SPprg+Mx{(GIa11GR5YdLBh-Sn6<|nC)O37!xYZJnMr-*oY#T>&w@ol}9r!rr)Fw z^elBf@X^&)$yciF+a7%Hi~l(Hzz`U-uu zT`1M6^6Ju+!9J?J^YDQtn@p6P+i~{&Zft<6K&oI6y1{l&jCGy%8piR;VxD!mopBVe zE%Sfyep%YXDJf|XXL?WmPz`)hTDul0PR-+k|2zv=w zrY>Z)?25OcciHlgDa6+e_l;X$TTe}!QEJI+zthiHAEVdnw$({5MC$nguU@m3jW#z` zdR;mxRln&&YD>e#idb8H%`MDx)}WX&!oR65m{H=5M@3L>%fe5zWe=c{U9rT~IupTQ zt?QFgQ&yTXU#ctET6>QcelcJebENjsIM0rY z4eQUu71FjquaoAlYVm9N#v>E@hpj7Y3p^ed>#zQU{J>bZg{>+8WwjF zLRU#(UtC}0ReKtePoj&AyIbP`x*N9Y!~Nu9ZvqarjTLGvK*0#RKGlW`dPUAqKVq8`2=a!cB z5v9?NE}7INd38YY+HNdYO#4F#{@yhd7+k8;B5ft2_Qd2Cu>BZ-6it8e>Nz|4fW)12n zqD>iKYjjs^KYBL_mK<2vcos>57+bx5yNXBM}Dodf|LR#W?P_t}6U-?RAG zo|G{L&n}+)uAC$^7i}jfj5fQ`yoLdtAXs&`Yq!iNb)5cOID`W&*4<6IENZh(J9X|% z{{=FYplXG*wAe5!%7NBwOI^|H&kF|%iI@=On*DCY+IJwt8 z8U%p}f@5E+jNCS{69qujQ35PN-SehmKoFidhOPLlof6=o9nim?$4>SHbaAD6yt%_ zt@2r;MR(2$5sn#z9!G$O)+C-J3}?JpGV{hX27$a;8o+H7`vcclOHkW#dIHM?Tit(2zdU`uh6$>+q%WmYv;P{Z%WTt{k0UW zgDd`JBK{o++#)s}kwcTYR_jkKiP@6OycyunSda|M8K-Q?lZ3bWc9!9+A30Wuy2T84J) zbA^goxeEz+Ic}_>v9~0$740f_-%^dnLL6ptJ);hz*f_yhIqVm`HIKG#dS|U{d#mWJ zTbR|b?FoN@$JbpH?$3;)oevP=qOYxiYTCx2>gvH%4{;B|Pqb$RK-4OMM)2)5SoUVZ zt<`rsG*8nJSm0Hjy-wL)AI1B0`l$5s(|*2}iTiwI01U4(kD*72E_@RYb78b@pmWUtnoPD=-2oK}(mE zD>_!79w`R8loGJk4APaSh01_hCbj9(!NNOBBr2m7-m&I(tn<5fS8* zDeKW9%GKoYpS9jdJDKwMU0w@TS_>=l25lFhdHGS-f|Y<;Q?$y%AEv8_z8QmBE3@wS zX;e{F7?5w38+1m8#6diO9;`(~?OIaOZo07=)_bs8wwZKikBu4`y@^__Xa!Q7{i0*l zxO^q96Wla00#(lnf*m8a4f8?{EnSvFhPJfWxf)~KQq%z$vI6DJJLDHDXh4UJqbM&0 z=0BM_cI!C0{#?e4$-A~53*mR;#r3WaiRVfIc;Jcc{gRCR6<^7d272aMGiT$@Nikg? zEtC~xPmv%!-GC9&nNrKJojP46^4#EFzm5y)x~P`vA?|{oR?#(rV}-C+78MAzTQI*F zcHf#ypO%)f^|ziNQCHxJs5z?pya@Ri4!#9g2jb2(8O6<0niyR-Q`TC<#-jFw2J>*y zt@S`FW83q*1f;8Hi7*X36(y*NpI}V7j&h%kZ~;A6p5+4fx!892(@S%g;51WL7y-NsY|o>E zEqu3ZhdJyPM*1JC>jjyNMQhsNszZ8m>X6NI#+FPwT*sqd9l-Lufp#)#pDSE&ZV$)b zh`N^sG}`rVl%B&+4b?B8&?8=G1)#9zLU5^Kghe#Hv%f`G*lsn*Fpsqcc3+5TwhlAC zXUW!4CMb{%oz!lVY+Gs`h?;#o&Vy|i+fz!EssgcPIj*DngnFYGTW{kT#)5eNkKk5bCX@X904~A03XKKp?O$oS&aR;Ohw_enN39I1qT*akf}2KIJdy z0X&<}=ivne0xvNZi^X4m{PD**e^2;IVR)|4l@{-WOqkKw!5>DgEo@9>3r>CcH4Nv=avGTRxmzS4MXS3PcMD%cLqy++jUE<+vHhX)O z@Dr{1y8t=ov(wYlw@N8rY))Gs5ZDz`N?)Fyp1zfHUh8GQYyU9F<>lqm)6>&GL|`xw zcs`MHesFqv`ulY(KVxMKz{BzJ@t>yC=>sAa-8!G^!{&uXD~Hou8k7l5^hLYy7vW01&Uf`sy3g>GYlHbox75DubWw zq@zIK<-{{u3jJp}=g)`tc5WRzQvirNckaA$baeD9B6{=Qy?bw#Qr;k<*NEt+M09uO z1Ox)lFD_{LD!#Ln(&Nj^%WvlM`J?%K{?&DE=iLX2Bfsa{vGU07*qoM6N<$ Eg3hy0`v3p{ diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x.png deleted file mode 100644 index 37b36f1579225e5619147545a7d808bb4dd71cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32336 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

KTL)GOfPq<>AK1Y>Iv<|0ED?cG9n_hH1>(_ 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%0AQ;eg3qA>XJSnUF-}POWx#8~MS0N6&VX_N zP-3P7F2EnF4SHZ;Om+C2wfh4iV;eC4tn`z>UMiu$0AgV^qbH`i;Q?6QcEhXZ;T1&Q z6}Fbp<)ydbr%H)8u_c$?colSuZ%P+*C%UZdi9-820go~_(&O!JdpaY1j0{9>w+G-f z<++B^hbbbCgq#pbs)Dm*S%L`E=BT!=K*H{>KM7GM3%W$*bx%6xmTf13>6&S#W?QL??J2!_$Jzdc8<|KQAipIS3%l)fd%nwIm4u>q+~O zMVn*6Eoj>#?}{#V?jQg`1Oyr#AZ&WGFo=X=2k_ajSPu1jw(P+KB{M7WT=KN!Wn5>O z<)>D7fpeOFVu>Sb_3kQNn77R?EtTCORfn5y(aajNv2p7z&;>sIL$}t(dy|v4-|iEr zrrcdF1hF4)G`9VGJ1;4Z zLw?I=^_BKgTh&#SS~l8?=9SvC`Y^V|eVmZN@!VCj=Eh-m)w9KqQ+H`f5H_8_f)yX` z6-=Ks>SqN`i=i7`_0U0o>g7;9$wT0H*QNZz**;AsH=AWb1<*#YmQEcYxOn5WujiqW@r%D?6b1b;#~^F{jrKL@^&$i1roy4ld$y z-xvL)Ejy%rZiZ#@o*L^`Ur%9Em=7tz0XBZhmg-O7G2GXtSiucX2gm$G!0(zVCBcy{Fs zrgi7KcpHK2hzxs24oKhX_St5_6 zt)ci_XRNrl!%&GPH^UP21bY(kJPl3UX5&!#G^{&N(CyjPES%Z{2&+KHcGYz_^2}&s z;&>0J`t($xA$6+K(7UT+D7__z*Wj+d1f8qE-^8`egBAJfC~J3Z9cC=Q^m`lR(p466 zI--OS2R^#w%t+;d3{0($d@NQ|JExF^Ko2SOBetGgOUy`A3U=; zJf>-YcB9zQvOTlMywTQ1I6VNAPUW4cKDbjizb&YxePH|7>J$ln^bY!&ZE|&69Sdv& z#_DzZX~0oj_O=EPdBVbq3zLds(Rgl)d!c-5PxDv&Ee{K|c`DA85LU7si95_*W8G?G zCWV}p%Kky9>s$;nIB^`nyE{4GNCSf-MGSefU{YU8442}mL)-?8nw&UKS+V;R0HlyB z-MhkCIV;0?dd5&Z0s7mHb~a#zc^;DKq$j06?s4S;cQGVs47*-rOZkSH=iyWU;AFA# ztR^r_7-x=>E@YIHW(pJWYNfmNwm}sZ)K1H?gtbw{k-MQ*zRmBUiY3);Xew@XZ+1{g z^z=N@2Rc{JQv(Aow%3mI)z;_jRQAY&r-}10VXyBq_?^;%V)3T(SWum2(ae(2kyb52 z#$%ml0eMO=f6I~ppLS3J|3}x>06M0688%FTasU$KZ_h4_M>+D-*xk8#tbokwGMhm*?;Zp{2e5GGG@C-E zAr&B?2ye6M-tKU!MZl`Ww$ksG*onw4G@JQQq-sSd-KPQt*+{{)uj(nuOPU+Ib%w7I zxEBDMSGRKlE9`_{S6V_}`@jO!T>Zk2<{5U27Ib(%tBl~>4lcpEtpOk*ZPxF|GYAU6 zx{~-6^&m3xUL>Czwr3a4K{Js@pPwi7a&RK6NlOC73+ZbYmC@)R0_1?t!K>TD}(U)V8k!0NOi@oACuk$N1%MnDnV zNO4IBz<~tZOG#0g!HFO0@$%9YRFN9aWi|Hk%rZ%17ViT2M?et(;bR=dA)@J%S0V^c ziIgMJ+O;6*P-OQqCKK!hB*pi8Q&wIaBqi@k4~_bw4A)O{eB%6k7a(XhZ$^N=c2z(E z`Ozo05(|zz6|k25x~CU#szpGyf@<}IqniZ4m}gc6 zT~XK06g$ViinNn{z2bJ}-+-kl|4r@NiD+r60x@quyX!Ayoy?~s9WcZWh46q7ZzhbL zjg#(?Cuz95mr;23#hrT3Ryt+SF+ZbI^PYMg1RO4lu1q5h-k#D}YDyl01Ax=&`v<9f zo#z|xT3qB+#4EwAZo#VUq(xHlp2wyOc6G2x;Gr=NsV_>;w433)7<(+zzgM7CKIN5^ zSL4B%v7h>%_9P%ckUc*E$cquxp%+&q-up*iT%)Zk?x%xYoD_tD&irc}0#Y<(M+}Zh zfh`s;BEEoV?z}0B9ky8=ir|YeqTzRl^-qxJ{A%%bKd5|w0#IqhZD$U=Bp1>S3I%)0#9=y;O7WSmq00mYMjHv2yWmb!sc+N$uy)EC z2U&j;(x{WfmR^jHDFQ2dQrE7`2Ax5VE4&ck6X5ycAz0}dEb2mER`Ru$=~p{V=yXs% zP(E+F&~5VGZu3F7CfCgK&X-{vI@ih~;AnDohtqoiHI3ZhoR6LqP;#dgNPuFz{1iG%-yGw$$2F*qf5HxW-*IQni5gI26X7)A`gPkR8A0l6;Yt^u< z%F}_o5D4&gUc@KMKX?ptFo{otHGe4T%fJzI1|U**sH5yn{k1Ew zDRiv(+b~-E>TNp|bWjr#yf`7)>2`(cLu}6mo~$r~rLbG`n4)hMkD8xAc*tM#)d8D5 z8(pO?&X;JmeC4+p0Rj@PgDjSVRjoJCl#d7}4AW3+W3|`C06=x9ogL`%Htqya*H9GR zKmsUrRE3j7o6{=g97xJub!W&jDJMCdz2!Z^ncf8mFSBV8TZ*pkq1;wdNX5v7Rv?1| z74i8#%K7GAxplOy@{_QVrC-UCTOr=Y3m~YL9(_un9_xxuUPPif*?aYmXBw}B%2r7W zeuX5(AZ8Pwy{ubJTTL>a+WQ$S1D1~+3{FcDO!sVw)A8P7mevWaJ=mL-5nuC+${j>9 zNEX#mQ|?Bf_P%q5#wt4zXtFT^MP9fY*9PLe00Tij=9|-_9w(OM(%bj47WTB=Gq6O+ z*}mcQZvzqmsU-sgvx=m+Cbcf){7NlQPNkZ_vAYzORy~c43V8?Zv3UX@MQ+VDtDe*} z4)I6_GXo{_TykG>w`Xy^i;W*-iBf)_uC&;uLxUOd{)CmMdzhD`IiKApZ=t8Hbad1f zFbhzKjtf&GUF41VQh`J~Cgp2gsmo7-A_s{cZ!htveM}_p z;}7=*6nI634+{0B2@EiqjwqF5ugEnc`fDj^2#Jr;!vRnCfDaF62Y{f8TmtyKKei=o z_fu%G%vSSL(TpdsdP1)3kdBRDJI@o!!~6IE5|}FbAtLSj{1Qic`S6e(JTf;w&NCp< zV_pM69AeIEfDs;vx&K?I!a5<5-|{42E7y8opSd2ck6rcRISt$7Yk;P1)4OSqvj016xB=NF9@XzrR!HZ}71@JV2LrZ-G)e0ENY;K9eq` zGyg=8n8fr5F(u^Y*-|8iWN%?-sCkOc<+_K6-F45Bg|whdwWfLYY-%%4vf_E%(zgow zKkW1~d$re9mCov4IS(tRmznGY6tY+4wSY!zdLJQoXBt=bU+!yt~f*!94@jm>R(GF$BL=>dK#7|9%ttou?ShQ`DFqm^nd|h0{iKsvYg^ zOm;^t95x|W)TSQN(SQN0ljRXkM;UF;v$3+Ct{eu1Kl^~6DG<2&4#sAl+td_?e*WD& zG6no|N$fT8XWs%8SUD|gOx<|#&r~mzT=Kp?)vX9{VtsI%pF9mv?a`Jget-^71>%Vp zgOzlycQ1+jX~UTSKa1|am+-+Zi5)wc6eEzXQU6&BP`W^?t; zL6OKpUW_^;1*~%#(-BQAgqP9N;UtWG7Q~r@GWS6pKA%Dn!#pk-ix8q9Sf+K3aom$x z+q1fE7x2vJi~5IF$fBo-kmmWYFSa@UhFT|JXcnL=v?c}hdaS)t567FeH_IPsY|X7? z9Gg~3i=5w`pt{!8KdIOt+rB<_h0SIP0Wdz94AAx~Eyl)V7J6|N%(fUk-O9HK_ zoe)l&io`t8gqZf~^?H2}MsS?s}2 z*=Z;(yUOWgU{7=b0}zKKd=3#)2$1WOtUl7cs~mX%3sW9^r1c3BUaQ)t239=}SoEX5 zh+FL`$Emen1%0B2=U-8q@0(jEkf(oF`MZc^w;3^Mfo^WmrjU zA-B8IYwn#+%IGBBygo&I`3D5N+VfNw-|G@dY1Sswo|K>KrNL$zor7$+Xo`?qIbAsO zHlQPR(@avJ&S3Tms8Dn7y9&(!4v_~4L^W%lgY2wH~~viVB?i0 zCC?ln<)1iR01;T(tl6w*AR=|WofFL+@$`CT# z>y_G2celkq^ucQdfFx3Q@d*@f_0O>0b;O7&N8$m{H@|hFFx)weV9En;^-QH|0>nj0 zDsNLQTIwF^oY1(gslIt%CbX3LY>&P@aJNDoa_#-!mHdAMc5&UVpzPwWTvwE4>&|Nl ze%`_UYEKzpyj*{->?!5K>*|NrNIvRk!K=YKZ8-BH-~a-)5a_G^;>wB{(JYicUFgG0 z79frfv*PPm){KSunrREL-_m>fj_-;--;TpcmIu(pWUemrK*EEe(QqdO8djUiazEU| znY4kPH`z@tJGh)F?#80xNZGJsYSz24c<=yaj;fbW%xvKxq4k8tAqjY&)w2nP@9r%fk9IB3@2T{K$X z?*^{ru#<|(lOcMn5z+Vzxmy>opf^#dFU&Fs)o~e>I7$j)`?HD;1D$(BR1Sb2vE(x(c=X4JKUmUOSo@xwyhsxoXLcLrYEd0Hx=U`t)|%2b z=cUziJ8JCofZ`ZoXtWwQkbw08tp}TwPABmh0e|TRK_9?ykOj_bp(%^=Q%%tNx&}-* zttSR%#7p8CtMeF&SS9J3dpG{g&+=Z3ZLS87Bf3QoV z-$}V=J>`qxeFBS#!V)lMg=IHi^R?DlkeJt|oQ_miwT_uC0U1CmZ!xo-vy{v zc9O*vW#aN@H$G6^7uWi~9`8kI7ML2IQPD<&j}#|mAwck2&3M@mXs98CCM7h7WMD82 zE!_h^pS<8{(&R@x(u}g_^|FQn1Zrj-5(moe$;^7Vr=dEGr>C#;dO`j0GQ}0H{Ym}S zsz%^}aeDc{3oimjDM>|H!xPM@a#D)t{w5{YXqQF=!1&_UY<|z$!K?la05fV-aB-1K zJfMx)+o1fwExrv{Erx}p^e!OzaElM6fVv#VdI3nmy?t(pnOXXfl)?c) z)3*R!xK{;X1}PQ|LYb?x75DquytmBlQatf&T8^_%;^W6nim2?UXYaOWz_Jx){XQ|D zYhmy%yCYdSeVSOntoEblt!3MV=kuJsD08*ugbBQ~T-O#VMDmk+OT7=HOxslI|8MW= zT_ih>c=h05=TLAu9OxDYHd3fRz+eYSHGFv`MSHUAMDPX{;ckzh6|ySsm1xPz2W+awLjRB+u^Sf+c)rfE9xR zGg#}%pwRQR_GaA8#xNbsjLg_Y3Kt}h%r&~aDYcREo|PSA4!hMtSKlg_v8eo5JzJl% z@HJ&P9&~5<5nz|jBA#4MI9u&@jY_|qC7~>f{XE^8TqRxFOh0Ivc`fFe#1>kmxOpu%dK_aJcUy}l%+9b@*sYJ@6N2_v@s^?&+!`Ad<#GXQ|sgztEDOwr;J33 zs}hh&D^w5jFzO79O1ca2%H#Cpb*u& z1VdwK=u@oFpt||~{_ApNp_|ouW^A(x1Rb{ zBBLm9{bhJVa>2Vjx_R9vRYA7n#`6#Ectk$v0ft?L-N%z!C~#&BqJ0;F_VAW%OHAlF|j$?W*J9e#G)MK}_FDV!y&j zGM=G&Dni$Ct5mdR$L&)geSSPucbw<-N;<6b%I(!-*-OH!_0hM?u2S{6iYiA^R}GB7 zl8R@**>GBr`;~bvs?DV_=qp-1!9`scHNl29RrE@YRpzy6S9_gxOce+yHTR?`HImy+KoH1N4gMwx7 zB-j#@l3Mjun3>uIBv2-Hs{m?&bM&k89GA{oG--!KN%D0v<(f9Z(ze~`cm~>5TMmJz z8SPprg+Mx{(GIa11GR5YdLBh-Sn6<|nC)O37!xYZJnMr-*oY#T>&w@ol}9r!rr)Fw z^elBf@X^&)$yciF+a7%Hi~l(Hzz`U-uu zT`1M6^6Ju+!9J?J^YDQtn@p6P+i~{&Zft<6K&oI6y1{l&jCGy%8piR;VxD!mopBVe zE%Sfyep%YXDJf|XXL?WmPz`)hTDul0PR-+k|2zv=w zrY>Z)?25OcciHlgDa6+e_l;X$TTe}!QEJI+zthiHAEVdnw$({5MC$nguU@m3jW#z` zdR;mxRln&&YD>e#idb8H%`MDx)}WX&!oR65m{H=5M@3L>%fe5zWe=c{U9rT~IupTQ zt?QFgQ&yTXU#ctET6>QcelcJebENjsIM0rY z4eQUu71FjquaoAlYVm9N#v>E@hpj7Y3p^ed>#zQU{J>bZg{>+8WwjF zLRU#(UtC}0ReKtePoj&AyIbP`x*N9Y!~Nu9ZvqarjTLGvK*0#RKGlW`dPUAqKVq8`2=a!cB z5v9?NE}7INd38YY+HNdYO#4F#{@yhd7+k8;B5ft2_Qd2Cu>BZ-6it8e>Nz|4fW)12n zqD>iKYjjs^KYBL_mK<2vcos>57+bx5yNXBM}Dodf|LR#W?P_t}6U-?RAG zo|G{L&n}+)uAC$^7i}jfj5fQ`yoLdtAXs&`Yq!iNb)5cOID`W&*4<6IENZh(J9X|% z{{=FYplXG*wAe5!%7NBwOI^|H&kF|%iI@=On*DCY+IJwt8 z8U%p}f@5E+jNCS{69qujQ35PN-SehmKoFidhOPLlof6=o9nim?$4>SHbaAD6yt%_ zt@2r;MR(2$5sn#z9!G$O)+C-J3}?JpGV{hX27$a;8o+H7`vcclOHkW#dIHM?Tit(2zdU`uh6$>+q%WmYv;P{Z%WTt{k0UW zgDd`JBK{o++#)s}kwcTYR_jkKiP@6OycyunSda|M8K-Q?lZ3bWc9!9+A30Wuy2T84J) zbA^goxeEz+Ic}_>v9~0$740f_-%^dnLL6ptJ);hz*f_yhIqVm`HIKG#dS|U{d#mWJ zTbR|b?FoN@$JbpH?$3;)oevP=qOYxiYTCx2>gvH%4{;B|Pqb$RK-4OMM)2)5SoUVZ zt<`rsG*8nJSm0Hjy-wL)AI1B0`l$5s(|*2}iTiwI01U4(kD*72E_@RYb78b@pmWUtnoPD=-2oK}(mE zD>_!79w`R8loGJk4APaSh01_hCbj9(!NNOBBr2m7-m&I(tn<5fS8* zDeKW9%GKoYpS9jdJDKwMU0w@TS_>=l25lFhdHGS-f|Y<;Q?$y%AEv8_z8QmBE3@wS zX;e{F7?5w38+1m8#6diO9;`(~?OIaOZo07=)_bs8wwZKikBu4`y@^__Xa!Q7{i0*l zxO^q96Wla00#(lnf*m8a4f8?{EnSvFhPJfWxf)~KQq%z$vI6DJJLDHDXh4UJqbM&0 z=0BM_cI!C0{#?e4$-A~53*mR;#r3WaiRVfIc;Jcc{gRCR6<^7d272aMGiT$@Nikg? zEtC~xPmv%!-GC9&nNrKJojP46^4#EFzm5y)x~P`vA?|{oR?#(rV}-C+78MAzTQI*F zcHf#ypO%)f^|ziNQCHxJs5z?pya@Ri4!#9g2jb2(8O6<0niyR-Q`TC<#-jFw2J>*y zt@S`FW83q*1f;8Hi7*X36(y*NpI}V7j&h%kZ~;A6p5+4fx!892(@S%g;51WL7y-NsY|o>E zEqu3ZhdJyPM*1JC>jjyNMQhsNszZ8m>X6NI#+FPwT*sqd9l-Lufp#)#pDSE&ZV$)b zh`N^sG}`rVl%B&+4b?B8&?8=G1)#9zLU5^Kghe#Hv%f`G*lsn*Fpsqcc3+5TwhlAC zXUW!4CMb{%oz!lVY+Gs`h?;#o&Vy|i+fz!EssgcPIj*DngnFYGTW{kT#)5eNkKk5bCX@X904~A03XKKp?O$oS&aR;Ohw_enN39I1qT*akf}2KIJdy z0X&<}=ivne0xvNZi^X4m{PD**e^2;IVR)|4l@{-WOqkKw!5>DgEo@9>3r>CcH4Nv=avGTRxmzS4MXS3PcMD%cLqy++jUE<+vHhX)O z@Dr{1y8t=ov(wYlw@N8rY))Gs5ZDz`N?)Fyp1zfHUh8GQYyU9F<>lqm)6>&GL|`xw zcs`MHesFqv`ulY(KVxMKz{BzJ@t>yC=>sAa-8!G^!{&uXD~Hou8k7l5^hLYy7vW01&Uf`sy3g>GYlHbox75DubWw zq@zIK<-{{u3jJp}=g)`tc5WRzQvirNckaA$baeD9B6{=Qy?bw#Qr;k<*NEt+M09uO z1Ox)lFD_{LD!#Ln(&Nj^%WvlM`J?%K{?&DE=iLX2Bfsa{vGU07*qoM6N<$ Eg3hy0`v3p{ diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 2.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 2.png deleted file mode 100644 index 9927569cdabb60b41169ea0f2dd7b028e20d9072..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8675 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 ty5V>{zP7)=|MtCm_gT~*Ny1V|a`n$SD z+?}Rr4)^!>zZnb$AE@eWULnlvWHOmNJ~=u0GNm+<7~|pL;o*}I!rfPCcoU_R-$$d- z{cvz_@cqut&ik*^IDo3|g%A$p=;-KARo#Ex1OUwJRNs_w09CymUo=3LkC%k6y|&^4 z0g-A`1Vm(w#8tU?uj4rG)JA<@NC`5%2>bG7q6y{LODaFYKxzvWOlUNa;?mVc_M4@Yhu2GsG#85pVmy!_rk#+|& z$i+#;nI>ae<3VS&_*SOo+e&^8fPaLXO^95a)Js_<{@#+ zSA64wzaXg8-L_HLZIqi`V7Jq`C#oi{LcomW&Y!CR)f>4OxyamJ^}1tgEbU$X2ppj;E=L&9-JUvwbWZ?O#>oTY*B>c(=osPHsj#tkgjWJ zyN0%HXnHNS5pyG#Ov;H=GPxvD&dhRRmJ`Q+oN=RR+1(w?Pm~}%y{sQYsu2HrHsQUu zj`;4=PY8`7EzklTy}s0bSHCao7dJlp{0E-={0p(|E`(4w-6sxDkDu|?haVC2!q3-6 z2+Fr#f6UXpR(;RE+atJkNz$F>*0%?tu$;fm3sIHfKr|UomGI zj3~OirmuoUzRzx?V$95#79+dQ32aG3?qE~`xYY|qolvaS2iL3zY<}?+cd{ATd`{q! zdSDR(fDG7tf+EXeg{ t#}Ccy002ovPDHLkV1hm?2J-*_ diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 5.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 5.png deleted file mode 100644 index 2401c28c584d89d3f08bc53759462cd6fbbda551..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1075 zcmV-31kC%1P)T~*Ny1V|a`n$SD z+?}Rr4)^!>zZnb$AE@eWULnlvWHOmNJ~=u0GNm+<7~|pL;o*}I!rfPCcoU_R-$$d- z{cvz_@cqut&ik*^IDo3|g%A$p=;-KARo#Ex1OUwJRNs_w09CymUo=3LkC%k6y|&^4 z0g-A`1Vm(w#8tU?uj4rG)JA<@NC`5%2>bG7q6y{LODaFYKxzvWOlUNa;?mVc_M4@Yhu2GsG#85pVmy!_rk#+|& z$i+#;nI>ae<3VS&_*SOo+e&^8fPaLXO^95a)Js_<{@#+ zSA64wzaXg8-L_HLZIqi`V7Jq`C#oi{LcomW&Y!CR)f>4OxyamJ^}1tgEbU$X2ppj;E=L&9-JUvwbWZ?O#>oTY*B>c(=osPHsj#tkgjWJ zyN0%HXnHNS5pyG#Ov;H=GPxvD&dhRRmJ`Q+oN=RR+1(w?Pm~}%y{sQYsu2HrHsQUu zj`;4=PY8`7EzklTy}s0bSHCao7dJlp{0E-={0p(|E`(4w-6sxDkDu|?haVC2!q3-6 z2+Fr#f6UXpR(;RE+atJkNz$F>*0%?tu$;fm3sIHfKr|UomGI zj3~OirmuoUzRzx?V$95#79+dQ32aG3?qE~`xYY|qolvaS2iL3zY<}?+cd{ATd`{q! zdSDR(fDG7tf+EXeg{ t#}Ccy002ovPDHLkV1hm?2J-*_ diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 6.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 6.png deleted file mode 100644 index 1cf328f4cc397518b295147db4300b8ca7dd08c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 473 zcmV;~0Ve*5P)DlD%$IK@f$%+1>j`>bCFu8(FW{ zKh8Bjg}DDU1B4K+1AqX|fp>y)AR@>KLouTi$i>KIhA^A!%5l*++S(DkAkPS9pxGE> zVLugOD&#T)yb~@O$Lg}; zmR(Em0Scr+NrN756~Jqt@-6pqq&$r=oAHn`y-n<*5}rpeOU)QG^Prh*_BSBrLN1AY zQbhRYBiS5fF(c3C2zZ1%7SEAW)$Q4?S*p7AF~+Z5*S&SlU7l<1`~Kz+^LfjRsTYkY P00000NkvXXu0mjf51`g1 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 82fd87ac..00000000 --- a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "filename" : "Artboard 6.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "16x16" - }, - { - "filename" : "Artboard 5.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "16x16" - }, - { - "filename" : "Artboard 4.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "32x32" - }, - { - "filename" : "Artboard 3.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "32x32" - }, - { - "filename" : "Artboard 2.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "128x128" - }, - { - "filename" : "Artboard 1@0.5x 1.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "128x128" - }, - { - "filename" : "Artboard 1@0.5x.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "256x256" - }, - { - "filename" : "Artboard 1.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "256x256" - }, - { - "filename" : "Frame 33.png", - "idiom" : "mac", - "scale" : "1x", - "size" : "512x512" - }, - { - "filename" : "Frame 32.png", - "idiom" : "mac", - "scale" : "2x", - "size" : "512x512" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 32.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 32.png deleted file mode 100644 index 8b9d3e0360dc3a72064bd0c8f90925bf988d0e61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181896 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
~|C-#l(OR6W(~Mr+R;_U#>h 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
9++=)CcVw?!*;*lT%?iNMZ<7K$2_9 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Ú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 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 33.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 33.png deleted file mode 100644 index 8b9d3e0360dc3a72064bd0c8f90925bf988d0e61..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 181896 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
~|C-#l(OR6W(~Mr+R;_U#>h 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
9++=)CcVw?!*;*lT%?iNMZ<7K$2_9 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Ú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
6OJiXCW0YIOJR7xlPUZ2JD^Q#QPe!^hx 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 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json b/submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json deleted file mode 100644 index 2aa0709e..00000000 --- a/submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - }, - "properties" : { - "compression-type" : "lossless" - } -} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json b/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json deleted file mode 100644 index dd24b520..00000000 --- a/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "Google-Gemini-Logo.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Google-Gemini-Logo.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Google-Gemini-Logo.png deleted file mode 100644 index 2eb2d323e1d76767d19a566d0a84b19a595bb0ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16697 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/submissions/sapphire/Sapphire/App/Info.plist b/submissions/sapphire/Sapphire/App/Info.plist deleted file mode 100644 index 213b84d2..00000000 --- a/submissions/sapphire/Sapphire/App/Info.plist +++ /dev/null @@ -1,25 +0,0 @@ - - - - - CFBundleURLTypes - - - CFBundleTypeRole - Editor - CFBundleURLName - com.shariq.sapphire - CFBundleURLSchemes - - sapphire - - - - NSCalendarsFullAccessUsageDescription - Needed to show events in calendar - NSHighResolutionCapable - - NSScreenCaptureUsageDescription - Needed for gemini live activity - - diff --git a/submissions/sapphire/Sapphire/App/OnboardingView.swift b/submissions/sapphire/Sapphire/App/OnboardingView.swift deleted file mode 100644 index db9c5097..00000000 --- a/submissions/sapphire/Sapphire/App/OnboardingView.swift +++ /dev/null @@ -1,233 +0,0 @@ -// -// OnboardingView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-09. -// - -import SwiftUI - -struct OnboardingView: View { - enum OnboardingStep { - case welcome, permissions - } - - @State private var currentStep: OnboardingStep = .welcome - var onComplete: () -> Void - - var body: some View { - ZStack { - LinearGradient( - gradient: Gradient(colors: [Color.indigo.opacity(0.3), Color.black]), - startPoint: .top, - endPoint: .bottom - ) - .ignoresSafeArea() - - CustomWindowControls() - .padding(.horizontal, 16) - .padding(.top, 16) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) - .zIndex(2) - - switch currentStep { - case .welcome: - WelcomeStepView(onGetStarted: { - withAnimation(.spring(response: 0.5, dampingFraction: 0.8)) { - currentStep = .permissions - } - }) - .transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .leading).combined(with: .opacity))) - case .permissions: - PermissionsStepView(onComplete: onComplete) - .transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .trailing).combined(with: .opacity))) - } - } - .background(.ultraThinMaterial) - .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous)) - } -} - - - -private struct WelcomeStepView: View { - var onGetStarted: () -> Void - - @State private var isHoveringGetStarted = false - - private var buttonGradient: LinearGradient { - LinearGradient( - gradient: Gradient(colors: [ - Color(red: 249/255, green: 165/255, blue: 154/255), - Color(red: 255/255, green: 197/255, blue: 158/255), - Color(red: 255/255, green: 247/255, blue: 174/255) - ]), - startPoint: .leading, - endPoint: .trailing - ) - } - - var body: some View { - VStack(spacing: 20) { - Spacer() - - Image(nsImage: NSApp.applicationIconImage) - .resizable() - .frame(width: 80, height: 80) - .clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous)) - - Text("Welcome to Sapphire") - .font(.largeTitle.weight(.bold)) - .multilineTextAlignment(.center) - - Text("A new way to experience your Mac's notch.\nLet's get started by setting up a few permissions.") - .font(.title3) - .multilineTextAlignment(.center) - .foregroundColor(.secondary) - .padding(.horizontal) - - Spacer() - - Button(action: onGetStarted) { - HStack { - Text("Get Started") - if isHoveringGetStarted { - Image(systemName: "arrow.right") - .transition(.opacity.animation(.easeInOut(duration: 0.2))) - } - } - .font(.headline) - .fontWeight(.semibold) - .foregroundColor(.black.opacity(0.8)) - .padding(.horizontal, 40) - .padding(.vertical, 12) - .background(buttonGradient) - .clipShape(Capsule()) - } - .buttonStyle(.plain) - .shadow(color: .black.opacity(0.3), radius: 10, y: 5) - .padding(.bottom, 50) - .onHover { hovering in - withAnimation(.easeInOut(duration: 0.2)) { - isHoveringGetStarted = hovering - } - } - } - } -} - - - -private struct PermissionsStepView: View { - @StateObject private var permissionsManager = PermissionsManager() - var onComplete: () -> Void - - - private var doneButtonGradient: LinearGradient { - LinearGradient( - gradient: Gradient(colors: [ - Color(red: 154/255, green: 249/255, blue: 165/255), - Color(red: 174/255, green: 255/255, blue: 247/255) - ]), - startPoint: .leading, - endPoint: .trailing - ) - } - - var body: some View { - VStack(spacing: 0) { - Text("Required Permissions") - .font(.largeTitle.weight(.bold)) - .padding(.top, 40).padding(.bottom, 10) - - Text("Sapphire needs a few permissions to provide live information and control your system. Your data is never collected or sent anywhere.") - .font(.body).multilineTextAlignment(.center).foregroundColor(.secondary) - .padding(.horizontal, 50).padding(.bottom, 30) - - ScrollView { - VStack(spacing: 15) { - ForEach(permissionsManager.allPermissions) { permission in - PermissionRowView(permission: permission, manager: permissionsManager) - } - }.padding(.horizontal, 50) - } - - Spacer() - - Button(action: onComplete) { - Text("Done") - .font(.headline).fontWeight(.semibold) - .foregroundColor(.black.opacity(0.8)) - .padding(.horizontal, 60).padding(.vertical, 12) - .background(doneButtonGradient) - .clipShape(Capsule()) - } - .buttonStyle(.plain) - .disabled(!permissionsManager.areAllPermissionsGranted) - .padding(.bottom, 50) - .animation(.easeInOut, value: permissionsManager.areAllPermissionsGranted) - } - .onAppear { - permissionsManager.checkAllPermissions() - } - } -} - - - -private struct PermissionRowView: View { - let permission: PermissionItem - @ObservedObject var manager: PermissionsManager - - var body: some View { - HStack(spacing: 15) { - Image(systemName: permission.iconName).font(.title2).frame(width: 40, height: 40) - .background(permission.iconColor.opacity(0.2)).clipShape(Circle()).foregroundColor(permission.iconColor) - VStack(alignment: .leading, spacing: 2) { - Text(permission.title).font(.headline) - Text(permission.description).font(.subheadline).foregroundColor(.secondary) - } - Spacer() - let status = manager.status(for: permission.type) - switch status { - case .granted: Image(systemName: "checkmark.circle.fill").font(.title2).foregroundColor(.green) - case .denied: Image(systemName: "xmark.circle.fill").font(.title2).foregroundColor(.red) - case .notRequested: Button("Request") { manager.requestPermission(permission.type) }.buttonStyle(.bordered).tint(.accentColor) - } - } - .padding().background(.black.opacity(0.15)) - .clipShape(RoundedRectangle(cornerRadius: 20)) - .overlay(RoundedRectangle(cornerRadius: 20).stroke(Color.white.opacity(0.1), lineWidth: 1)) - } -} - - - -private struct CustomWindowControls: View { - @Environment(\.window) private var window: NSWindow? - @State private var isHovering = false - - var body: some View { - HStack(spacing: 8) { - Button(action: { window?.close() }) { - Image(systemName: "xmark").font(.system(size: 9, weight: .bold, design: .rounded)) - } - .buttonStyle(TrafficLightButtonStyle(color: .red, isHovering: isHovering)) - - Button(action: { window?.miniaturize(nil) }) { - Image(systemName: "minus").font(.system(size: 9, weight: .bold, design: .rounded)) - } - .buttonStyle(TrafficLightButtonStyle(color: .yellow, isHovering: isHovering)) - - Button(action: { window?.zoom(nil) }) { - Image(systemName: "plus").font(.system(size: 9, weight: .bold, design: .rounded)) - } - .buttonStyle(TrafficLightButtonStyle(color: .green, isHovering: isHovering)) - } - .onHover { hovering in - withAnimation(.easeInOut(duration: 0.1)) { - isHovering = hovering - } - } - } -} diff --git a/submissions/sapphire/Sapphire/App/PermissionsManager.swift b/submissions/sapphire/Sapphire/App/PermissionsManager.swift deleted file mode 100644 index 8ddec97b..00000000 --- a/submissions/sapphire/Sapphire/App/PermissionsManager.swift +++ /dev/null @@ -1,185 +0,0 @@ -// -// PermissionsManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI -import Combine -import CoreLocation -import EventKit -import AVFoundation -import UserNotifications -import ScreenCaptureKit -import CoreBluetooth -import Intents - -enum PermissionType: Identifiable { - case accessibility, notifications, location, calendar, bluetooth, focusStatus - var id: Self { self } -} - -enum PermissionStatus { case granted, denied, notRequested } - -struct PermissionItem: Identifiable { - let id = UUID() - let type: PermissionType, title: String, description: String, iconName: String - let iconColor: Color -} - -@MainActor -class PermissionsManager: NSObject, ObservableObject, CLLocationManagerDelegate, CBCentralManagerDelegate { - - @Published var accessibilityStatus: PermissionStatus = .notRequested - @Published var notificationsStatus: PermissionStatus = .notRequested - @Published var locationStatus: PermissionStatus = .notRequested - @Published var calendarStatus: PermissionStatus = .notRequested - @Published var bluetoothStatus: PermissionStatus = .notRequested - @Published var focusStatusStatus: PermissionStatus = .notRequested - - private var locationManager: CLLocationManager? - private var bluetoothManager: CBCentralManager? - - let allPermissions: [PermissionItem] = [ - .init(type: .accessibility, title: "Accessibility", description: "Needed to detect media key presses for music and volume control.", iconName: "figure.wave.circle.fill", iconColor: .purple), - .init(type: .notifications, title: "Notifications", description: "Needed to show custom alerts for messages and system events.", iconName: "bell.badge.fill", iconColor: .red), - .init(type: .location, title: "Location", description: "Needed to provide live weather updates for your current location.", iconName: "location.fill", iconColor: .blue), - .init(type: .calendar, title: "Calendar", description: "Needed to show your upcoming events.", iconName: "calendar", iconColor: .red), - .init(type: .bluetooth, title: "Bluetooth", description: "Needed to detect connected devices and their battery levels.", iconName: "ipad.landscape.and.iphone", iconColor: .blue), - .init(type: .focusStatus, title: "Focus Status", description: "Needed to show when a Focus mode is active.", iconName: "moon.fill", iconColor: .indigo) - ] - - var areAllPermissionsGranted: Bool { - accessibilityStatus == .granted && - notificationsStatus == .granted && - locationStatus == .granted && - calendarStatus == .granted && - bluetoothStatus == .granted && - focusStatusStatus == .granted - } - - override init() { - super.init() - self.locationManager = CLLocationManager() - self.locationManager?.delegate = self - self.bluetoothManager = CBCentralManager(delegate: self, queue: nil) - } - - func checkAllPermissions() { - - switch CBManager.authorization { - case .allowedAlways: - bluetoothStatus = .granted - case .denied, .restricted: - bluetoothStatus = .denied - case .notDetermined: - bluetoothStatus = .notRequested - @unknown default: - bluetoothStatus = .notRequested - } - } - - func status(for type: PermissionType) -> PermissionStatus { - switch type { - case .accessibility: return accessibilityStatus - case .notifications: return notificationsStatus - case .location: return locationStatus - case .calendar: return calendarStatus - case .bluetooth: return bluetoothStatus - case .focusStatus: return focusStatusStatus - } - } - - func requestPermission(_ type: PermissionType) { - switch type { - case .accessibility: - self.accessibilityStatus = .granted - - case .notifications: - UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, _ in - DispatchQueue.main.async { self.notificationsStatus = granted ? .granted : .denied } - } - - case .location: - locationManager?.requestWhenInUseAuthorization() - - case .calendar: - EKEventStore().requestFullAccessToEvents { granted, _ in - DispatchQueue.main.async { self.calendarStatus = granted ? .granted : .denied } - } - - case .bluetooth: - - - if bluetoothManager?.state == .poweredOn { - - bluetoothManager?.scanForPeripherals(withServices: nil, options: nil) - } else { - - DispatchQueue.main.async { - self.bluetoothStatus = .denied - } - } - - case .focusStatus: - INFocusStatusCenter.default.requestAuthorization { status in - DispatchQueue.main.async { - switch status { - case .authorized: self.focusStatusStatus = .granted - case .denied: self.focusStatusStatus = .denied - case .notDetermined: self.focusStatusStatus = .notRequested - @unknown default: self.focusStatusStatus = .notRequested - } - } - } - } - } - - func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - updateLocationStatus(for: manager.authorizationStatus) - } - - private func updateLocationStatus(for status: CLAuthorizationStatus) { - switch status { - case .authorized, .authorizedAlways, .authorizedWhenInUse: - locationStatus = .granted - case .denied, .restricted: - locationStatus = .denied - case .notDetermined: - locationStatus = .notRequested - @unknown default: - locationStatus = .notRequested - } - } - - - func centralManagerDidUpdateState(_ central: CBCentralManager) { - switch central.state { - case .poweredOn: - - DispatchQueue.main.async { - self.bluetoothStatus = .granted - } - case .poweredOff: - - DispatchQueue.main.async { - self.bluetoothStatus = .denied - } - case .unauthorized: - - DispatchQueue.main.async { - self.bluetoothStatus = .denied - } - case .unknown, .resetting: - - DispatchQueue.main.async { - self.bluetoothStatus = .notRequested - } - @unknown default: - DispatchQueue.main.async { - self.bluetoothStatus = .notRequested - } - } - } -} diff --git a/submissions/sapphire/Sapphire/App/ViewController.swift b/submissions/sapphire/Sapphire/App/ViewController.swift deleted file mode 100644 index 25ef7691..00000000 --- a/submissions/sapphire/Sapphire/App/ViewController.swift +++ /dev/null @@ -1,25 +0,0 @@ -// -// ViewController.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-05-07. -// - -import Cocoa - -class ViewController: NSViewController { - - override func viewDidLoad() { - - - - } - - override var representedObject: Any? { - didSet { - - } - } - - -} diff --git a/submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift b/submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift deleted file mode 100644 index 8505f1c4..00000000 --- a/submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift +++ /dev/null @@ -1,471 +0,0 @@ -// -// LiveActivityComponents.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-06. -// - -import SwiftUI -import EventKit - -// MARK: - Music Components - -struct AlbumArtView: View { - let image: NSImage? - - var body: some View { - Group { - if let artwork = image { - Image(nsImage: artwork) - .resizable() - } else { - Image(systemName: "music.note") - .foregroundColor(.white.opacity(0.8)) - } - } - .aspectRatio(contentMode: .fill) - .frame(width: 20, height: 20) - .clipShape(RoundedRectangle(cornerRadius: 7, style: .continuous)) - .id(image) - } -} - -struct MusicLyricsView: View { - @EnvironmentObject var musicWidget: MusicWidget - @Binding var showLyrics: Bool - - init(_ showLyrics: Binding) { - self._showLyrics = showLyrics - } - - var body: some View { - let lyricText = (musicWidget.currentLyric?.translatedText ?? musicWidget.currentLyric?.text) - - if let text = lyricText, !text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { - Text(text) - .font(.system(size: 10, weight: .semibold, design: .rounded)) - .foregroundColor(musicWidget.accentColor.opacity(0.9)) - .lineLimit(1) - .truncationMode(.tail) - .frame(maxWidth: 200) - .transition(.opacity.animation(.easeInOut(duration: 0.3))) - .id("lyric-\(musicWidget.currentLyric?.id.uuidString ?? "")") - .onTapGesture { - showLyrics = true - } - } else { - EmptyView() - } - } -} - -struct NowPlayingTextView: View { - let title: String - - var body: some View { - Text(title) - .font(.system(size: 10, weight: .semibold, design: .rounded)) - .lineLimit(1) - .truncationMode(.tail) - .frame(maxWidth: 200) - .transition(.opacity.animation(.easeInOut(duration: 0.3))) - .opacity(0.5) - } -} - -// MARK: - Activity View Components - -struct AudioSwitchActivityView { - static func left(for event: AudioSwitchEvent) -> some View { - Image(systemName: "arrow.uturn.backward.circle.fill") - .font(.system(size: 18, weight: .semibold)) - .foregroundColor(.white) - .symbolRenderingMode(.hierarchical) - } - - static func right(for event: AudioSwitchEvent) -> some View { - let targetDeviceIcon = event.direction == .switchedToMac ? "desktopcomputer" : "iphone" - let targetDeviceName = event.direction == .switchedToMac ? "Mac" : "iPhone" - - return HStack(spacing: 8) { - VStack(alignment: .leading, spacing: 1) { - Text(event.deviceName) - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.white.opacity(0.9)) - .lineLimit(1) - Text("Connected to \(targetDeviceName)") - .font(.system(size: 11)) - .foregroundColor(.white.opacity(0.7)) - } - Image(systemName: targetDeviceIcon) - .font(.system(size: 16, weight: .semibold)) - .foregroundColor(.white) - } - } -} - -struct BatteryActivityView { - static func left(for state: BatteryState) -> some View { - let iconName = state.isLow ? "battery.25" : (state.isCharging ? "bolt.fill" : "powerplug.fill") - let iconColor = state.isLow ? Color.red : (state.isCharging ? .green : .white.opacity(0.9)) - - return Image(systemName: iconName) - .frame(width: 20, height: 20) - .foregroundColor(iconColor) - } - - static func right(for state: BatteryState) -> some View { - Text("\(state.level)%") - .font(.system(size: 13, weight: .semibold)) - } -} - -struct BatteryRingView: View { - let level: Int - - private var color: Color { - if level <= 20 { return .red } - if level <= 45 { return .yellow } - return .green - } - - var body: some View { - ZStack { - Circle().stroke(Color.white.opacity(0.2), lineWidth: 2.5) - Circle() - .trim(from: 0, to: CGFloat(level) / 100.0) - .stroke(color, style: StrokeStyle(lineWidth: 2.5, lineCap: .round)) - .rotationEffect(.degrees(-90)) - .animation(.easeOut, value: level) - } - .frame(width: 18, height: 18) - } -} - -struct BluetoothActivityView { - static func left(for device: BluetoothDeviceState) -> some View { - Image(systemName: device.iconName) - .font(.system(size: 18, weight: .semibold)) - .foregroundColor(.white) - .symbolRenderingMode(.hierarchical) - } - - static func right(for device: BluetoothDeviceState) -> some View { - HStack(spacing: 8) { - Text(device.name) - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.white.opacity(0.9)) - if let level = device.batteryLevel { - BatteryRingView(level: level) - } - } - } -} - -struct BluetoothBatteryActivityView { - static func left(for device: BluetoothDeviceState) -> some View { - Image(systemName: device.iconName) - .font(.system(size: 18, weight: .semibold)) - .foregroundColor(.white) - .symbolRenderingMode(.hierarchical) - } - - static func right(for device: BluetoothDeviceState) -> some View { - HStack(spacing: 8) { - if let level = device.batteryLevel { - BatteryRingView(level: level) - Text("\(level)%") - .font(.system(size: 13, weight: .semibold, design: .rounded)) - .foregroundColor(.white.opacity(0.9)) - } else { - Text("Low Battery") - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.red) - } - } - } -} - -struct BluetoothDisconnectedActivityView { - static func left(for device: BluetoothDeviceState) -> some View { - Image(systemName: "wifi.slash") - .font(.system(size: 18, weight: .semibold)) - .foregroundColor(.white.opacity(0.8)) - .symbolRenderingMode(.hierarchical) - } - - static func right(for device: BluetoothDeviceState) -> some View { - VStack(alignment: .leading, spacing: 1) { - Text(device.name) - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.white.opacity(0.9)) - .lineLimit(1) - Text("Disconnected") - .font(.system(size: 11)) - .foregroundColor(.white.opacity(0.6)) - } - } -} - -struct CalendarActivityView { - static func left(for event: EKEvent) -> some View { - Image(systemName: "calendar") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 18, height: 18) - .foregroundColor(.white.opacity(0.85)) - .padding(.vertical, 2) - } - - static func right(for event: EKEvent) -> some View { - VStack(alignment: .leading, spacing: 2) { - Text(event.title) - .lineLimit(1) - .font(.system(size: 13, weight: .semibold)) - Text(event.startDate, style: .relative) - .lineLimit(1) - .font(.system(size: 11, weight: .medium)) - .foregroundColor(.white.opacity(0.6)) - } - } -} - -struct DesktopActivityView { - static func left(for number: Int) -> some View { - Image(systemName: "rectangle.on.rectangle") - .font(.system(size: 14, weight: .semibold)) - .foregroundColor(.white.opacity(0.9)) - } - - static func right(for number: Int) -> some View { - Text("\(number)") - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.white.opacity(0.9)) - } -} - -struct EyeBreakActivityView { - static var left: some View { - Image(systemName: "eye.fill") - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 18, height: 18) - .foregroundColor(.cyan) - } - - static var right: some View { - Text("Eye Break: Look 20ft away") - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.white.opacity(0.9)) - } - - static func bottom() -> some View { - EyeBreakButtonsView() - } -} - -fileprivate struct EyeBreakButtonsView: View { - @EnvironmentObject var eyeBreakManager: EyeBreakManager - - var body: some View { - HStack(spacing: 15) { - Button(action: { self.eyeBreakManager.dismissBreak() }) { - Text("Dismiss") - .fontWeight(.semibold) - .frame(minWidth: 80) - .padding(.vertical, 8) - .background(Color.white.opacity(0.15)) - .clipShape(Capsule()) - } - .buttonStyle(.plain) - - Button(action: { self.eyeBreakManager.completeBreak() }) { - Text(eyeBreakManager.isDoneButtonEnabled ? "Done" : "Done (\(Int(eyeBreakManager.timeRemainingInBreak))s)") - .fontWeight(.semibold) - .frame(minWidth: 80) - .padding(.vertical, 8) - .background(eyeBreakManager.isDoneButtonEnabled ? Color.blue : Color.white.opacity(0.15)) - .clipShape(Capsule()) - } - .buttonStyle(.plain) - .disabled(!eyeBreakManager.isDoneButtonEnabled) - .animation(.easeInOut, value: eyeBreakManager.isDoneButtonEnabled) - } - .foregroundColor(.white) - } -} - -struct FocusModeActivityView { - private static func color(for id: String) -> Color { - switch id { - case "moon.fill": return .purple - case "person.fill": return .blue - case "briefcase.fill": return .cyan - case "bed.double.fill": return .indigo - case "car.fill": return .gray - case "gamecontroller.fill": return .red - default: return .purple - } - } - - static func left(for mode: FocusModeInfo) -> some View { - Image(systemName: mode.identifier) - .font(.system(size: 14, weight: .semibold)) - .foregroundColor(color(for: mode.identifier)) - } - - static func right(for mode: FocusModeInfo) -> some View { - Text("Focus: \(mode.name)") - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.white.opacity(0.9)) - } -} - -struct TimerActivityView: View { - @EnvironmentObject var timerManager: TimerManager - - var body: some View { - TimelineView(.periodic(from: .now, by: 0.1)) { context in - HStack(spacing: 8) { - Image(systemName: "timer").foregroundColor(.orange) - Text(formatTime(timerManager.elapsedTime)) - } - .foregroundColor(.white.opacity(0.9)) - .font(.system(size: 13, weight: .semibold, design: .monospaced)) - } - } - - private func formatTime(_ time: TimeInterval) -> String { - let totalSeconds = Int(time) - let minutes = totalSeconds / 60 - let seconds = totalSeconds % 60 - let milliseconds = Int((time.truncatingRemainder(dividingBy: 1)) * 10) - return String(format: "%02d:%02d.%d", minutes, seconds, milliseconds) - } -} - -struct WeatherActivityView { - static func left(for data: ProcessedWeatherData) -> some View { - Image(systemName: WeatherIconMapper.map(from: data.iconCode)) - .font(.title3) - .symbolRenderingMode(.multicolor) - } - - static func right(for data: ProcessedWeatherData) -> some View { - RightView(data: data) - } - - private struct RightView: View { - @EnvironmentObject var settings: SettingsModel - let data: ProcessedWeatherData - - var body: some View { - let temp = settings.settings.weatherUseCelsius ? data.temperatureMetric : data.temperature - Text("\(temp)°") - .font(.system(size: 14, weight: .semibold, design: .rounded)) - .foregroundColor(.white) - } - } -} - -struct NotificationActivityView { - static func left(for payload: NotificationPayload) -> some View { - let iconName: String - let bgColor: Color - - switch payload.appIdentifier { - case "com.apple.facetime": - iconName = "video.fill" - bgColor = .green - case "com.apple.iChat": - iconName = "message.fill" - bgColor = .blue - case "com.apple.sharingd": - iconName = "square.and.arrow.down.on.square.fill" - bgColor = .cyan - default: - iconName = "app.badge.fill" - bgColor = .gray - } - - return Image(systemName: iconName) - .font(.system(size: 16)) - .frame(width: 28, height: 28) - .background(bgColor) - .foregroundColor(.white) - .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) - } - - static func right(for payload: NotificationPayload) -> some View { - VStack(alignment: .leading, spacing: 1) { - Text(payload.title) - .font(.system(size: 13, weight: .semibold)) - .foregroundColor(.white) - .lineLimit(1) - Text(payload.body) - .font(.system(size: 13)) - .foregroundColor(.white.opacity(0.8)) - .lineLimit(1) - } - } -} - -struct NotificationBottomView: View { - let payload: NotificationPayload - @EnvironmentObject var notificationManager: NotificationManager - - var body: some View { - HStack(spacing: 12) { - Button("Dismiss") { notificationManager.dismissLatestNotification() } - .buttonStyle(NotificationButtonStyle(color: .gray.opacity(0.4))) - - if payload.appIdentifier == "com.apple.sharingd" { - Button(action: { - if let url = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first { - NSWorkspace.shared.open(url) - } - notificationManager.dismissLatestNotification() - }) { - HStack { - Image(systemName: "folder.fill") - Text("Show") - } - } - .buttonStyle(NotificationButtonStyle(color: .cyan)) - } else if payload.hasAudioAttachment { - Button(action: { - NSWorkspace.shared.launchApplication("Messages") - notificationManager.dismissLatestNotification() - }) { - HStack { - Image(systemName: "play.fill") - Text("Play") - } - } - .buttonStyle(NotificationButtonStyle(color: .blue)) - } else { - Button("Reply") { - NSWorkspace.shared.launchApplication("Messages") - notificationManager.dismissLatestNotification() - } - .buttonStyle(NotificationButtonStyle(color: .gray.opacity(0.4))) - } - } - } -} - -struct NotificationButtonStyle: ButtonStyle { - var color: Color - - func makeBody(configuration: Configuration) -> some View { - configuration.label - .fontWeight(.semibold) - .padding(.horizontal, 12) - .padding(.vertical, 6) - .background(color) - .foregroundColor(.white) - .clipShape(Capsule()) - .scaleEffect(configuration.isPressed ? 0.95 : 1.0) - .animation(.easeOut(duration: 0.2), value: configuration.isPressed) - } -} diff --git a/submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift b/submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift deleted file mode 100644 index 8f8e3adb..00000000 --- a/submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift +++ /dev/null @@ -1,273 +0,0 @@ -// -// LiveActivityManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import Foundation -import SwiftUI -import Combine -import EventKit -import NearbyShare - -// MARK: - Enums and Structs - -enum ActivityType: Int, Equatable, Comparable, CaseIterable { - case none = 0, weather = 5, music = 10, timer = 20, desktopChange = 30, battery = 40, calendar = 50, focusModeChange = 55, bluetooth = 58, audioSwitch = 60, eyeBreak = 70, notification = 80, geminiLive = 85, nearbyShare = 90, systemHUD = 100 - static func < (lhs: ActivityType, rhs: ActivityType) -> Bool { return lhs.rawValue < rhs.rawValue } - init?(from settingsType: LiveActivityType) { - switch settingsType { - case .music: self = .music; case .weather: self = .weather; case .calendar: self = .calendar; case .timers: self = .timer; case .battery: self = .battery; case .eyeBreak: self = .eyeBreak; case .desktop: self = .desktopChange; case .focus: self = .focusModeChange - } - } -} - -private struct SystemHUDIdentifier: Hashable { - let type: HUDType - let style: HUDStyle -} - -// MARK: - LiveActivityManager - -@MainActor -class LiveActivityManager: ObservableObject { - - // MARK: - Published Properties - @Published private(set) var contentUpdateID = UUID() - @Published private(set) var currentActivity: ActivityType = .none - @Published private(set) var activityContent: LiveActivityContent = .none - @Published private(set) var currentNearDropPayload: NearDropPayload? - @Published private(set) var currentGeminiPayload: GeminiPayload? - - @Published private var showNowPlayingText: Bool = false - - // MARK: - Public Properties - var showLyricsBinding: Binding? - var isFullViewActivity: Bool { if case .full = activityContent { true } else { false } } - - // MARK: - Private Properties - private var dismissalTimer: Timer? - private var nowPlayingDismissalTimer: Timer? - private var cancellables = Set() - private var activityCheckers: [ActivityType: () -> (ActivityType, LiveActivityContent, TimeInterval?)?] = [:] - - // MARK: - State Tracking - private var hasShownPluggedInAlert = false, hasShownLowBatteryAlert = false, hasShownCurrentEyeBreak = false - private var lastShownCalendarEventID: String?, lastShownDesktopNumber: Int?, lastShownFocusModeID: String? - private var lastShownBluetoothEvent: BluetoothDeviceState?, lastShownAudioSwitchEventID: UUID? - - // MARK: - Dependencies - private let systemHUDManager: SystemHUDManager, notificationManager: NotificationManager, desktopManager: DesktopManager, focusModeManager: FocusModeManager, musicWidget: MusicWidget, calendarService: CalendarService, batteryMonitor: BatteryMonitor, bluetoothManager: BluetoothManager, audioDeviceManager: AudioDeviceManager, eyeBreakManager: EyeBreakManager, timerManager: TimerManager, weatherActivityViewModel: WeatherActivityViewModel, geminiLiveManager: GeminiLiveManager, settingsModel: SettingsModel, activeAppMonitor: ActiveAppMonitor - - // MARK: - Initialization - init(systemHUDManager: SystemHUDManager, notificationManager: NotificationManager, desktopManager: DesktopManager, focusModeManager: FocusModeManager, musicWidget: MusicWidget, calendarService: CalendarService, batteryMonitor: BatteryMonitor, bluetoothManager: BluetoothManager, audioDeviceManager: AudioDeviceManager, eyeBreakManager: EyeBreakManager, timerManager: TimerManager, weatherActivityViewModel: WeatherActivityViewModel, geminiLiveManager: GeminiLiveManager, settingsModel: SettingsModel, activeAppMonitor: ActiveAppMonitor) { - self.systemHUDManager = systemHUDManager; self.notificationManager = notificationManager; self.desktopManager = desktopManager; self.focusModeManager = focusModeManager; self.musicWidget = musicWidget; self.calendarService = calendarService; self.batteryMonitor = batteryMonitor; self.bluetoothManager = bluetoothManager; self.audioDeviceManager = audioDeviceManager; self.eyeBreakManager = eyeBreakManager; self.timerManager = timerManager; self.weatherActivityViewModel = weatherActivityViewModel; self.geminiLiveManager = geminiLiveManager; self.settingsModel = settingsModel; self.activeAppMonitor = activeAppMonitor - self.lastShownDesktopNumber = desktopManager.currentDesktopNumber - self.activityCheckers = [ .systemHUD: self.checkForSystemHUD, .nearbyShare: self.checkForNearDrop, .geminiLive: self.checkForGeminiLive, .notification: self.checkForNotification, .eyeBreak: self.checkForEyeBreak, .audioSwitch: self.checkForAudioSwitch, .bluetooth: self.checkForBluetooth, .focusModeChange: self.checkForFocusMode, .calendar: self.checkForCalendar, .battery: self.checkForBattery, .desktopChange: self.checkForDesktopChange, .timer: self.checkForTimer, .music: self.checkForMusic, .weather: self.checkForWeather ] - setupSubscriptions() - } - - // MARK: - Subscriptions - private func setupSubscriptions() { - geminiLiveManager.$isMicMuted.receive(on: DispatchQueue.main).sink { [weak self] newMuteState in guard let self, var payload = self.currentGeminiPayload, payload.isMicMuted != newMuteState else { return }; payload.isMicMuted = newMuteState; self.currentGeminiPayload = payload }.store(in: &cancellables) - geminiLiveManager.sessionDidEndPublisher.receive(on: DispatchQueue.main).sink { [weak self] in self?.finishGeminiLive() }.store(in: &cancellables) - musicWidget.playerActionPublisher.receive(on: DispatchQueue.main).sink { [weak self] action in if case .trackChanged = action { self?.triggerNowPlayingText() } }.store(in: &cancellables) - - let stateChangeTriggers: [AnyPublisher] = [ systemHUDManager.$currentHUD.mapToVoid(), $currentNearDropPayload.mapToVoid(), $currentGeminiPayload.mapToVoid(), notificationManager.$latestNotification.mapToVoid(), desktopManager.$currentDesktopNumber.mapToVoid(), focusModeManager.$currentFocusMode.mapToVoid(), calendarService.$nextEvent.mapToVoid(), batteryMonitor.$currentState.mapToVoid(), audioDeviceManager.$lastSwitchEvent.mapToVoid(), bluetoothManager.$lastEvent.mapToVoid(), eyeBreakManager.$isBreakTime.mapToVoid(), timerManager.$isRunning.mapToVoid(), weatherActivityViewModel.$weatherData.mapToVoid(), musicWidget.$shouldShowLiveActivity.mapToVoid(), musicWidget.$currentLyric.mapToVoid(), $showNowPlayingText.mapToVoid(), settingsModel.objectWillChange.mapToVoid(), activeAppMonitor.$isLyricsAllowedForActiveApp.mapToVoid() ] - Publishers.MergeMany(stateChangeTriggers).debounce(for: .milliseconds(50), scheduler: RunLoop.main).sink { [weak self] in self?.evaluateAndDisplayActivity() }.store(in: &cancellables) - } - - // MARK: - Activity Management - private func triggerNowPlayingText() { - nowPlayingDismissalTimer?.invalidate() - self.showNowPlayingText = true - - nowPlayingDismissalTimer = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false) { [weak self] _ in - DispatchQueue.main.async { - guard let self = self else { return } - self.showNowPlayingText = false - self.evaluateAndDisplayActivity() - } - } - } - - private func evaluateAndDisplayActivity(ignoring ignoredType: ActivityType? = nil) { - if musicWidget.shouldShowLiveActivity == false { - nowPlayingDismissalTimer?.invalidate() - showNowPlayingText = false - } - - let highPriorityActivities: [ActivityType] = [.systemHUD, .nearbyShare, .geminiLive, .notification, .audioSwitch, .bluetooth] - let userOrderedActivities = settingsModel.settings.liveActivityOrder.compactMap { ActivityType(from: $0) } - let finalEvaluationOrder = highPriorityActivities + userOrderedActivities - for activityType in finalEvaluationOrder { - guard activityType != ignoredType, let checker = activityCheckers[activityType] else { continue } - if let (type, content, duration) = checker() { - setActivity(type: type, content: content, dismissAfter: duration) - return - } - } - setActivity(type: .none, content: .none) - } - - private func setActivity(type: ActivityType, content: LiveActivityContent, dismissAfter duration: TimeInterval? = nil) { - if self.currentActivity == type && self.activityContent == content { return } - dismissalTimer?.invalidate() - self.currentActivity = type; self.activityContent = content; self.contentUpdateID = UUID() - if let duration = duration { - dismissalTimer = Timer.scheduledTimer(withTimeInterval: duration, repeats: false) { [weak self] _ in - guard let self, self.currentActivity == type else { return } - switch type { - case .desktopChange: self.lastShownDesktopNumber = self.desktopManager.currentDesktopNumber - case .battery: if let state = self.batteryMonitor.currentState { if state.isLow { self.hasShownLowBatteryAlert = true } else if state.isPluggedIn { self.hasShownPluggedInAlert = true } } - case .focusModeChange: self.lastShownFocusModeID = self.focusModeManager.currentFocusMode?.identifier - case .calendar: self.lastShownCalendarEventID = self.calendarService.nextEvent?.eventIdentifier - case .eyeBreak: self.hasShownCurrentEyeBreak = true - case .bluetooth: self.lastShownBluetoothEvent = self.bluetoothManager.lastEvent - case .audioSwitch: self.lastShownAudioSwitchEventID = self.audioDeviceManager.lastSwitchEvent?.id - default: break - } - self.evaluateAndDisplayActivity(ignoring: type) - } - } - } - - // MARK: - Activity Checkers - private func checkForMusic() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard settingsModel.settings.musicLiveActivityEnabled, musicWidget.shouldShowLiveActivity else { return nil } - - let lyricsAllowed = activeAppMonitor.isLyricsAllowedForActiveApp - let activityView: AnyView - - // Conditionally create the view to avoid passing an EmptyView to the bottom parameter, - // which can cause unwanted padding. - if self.showNowPlayingText { - let view = StandardActivityView( - left: { AlbumArtView(image: musicWidget.artwork) }, - right: { WaveformView().environmentObject(musicWidget).environmentObject(settingsModel) }, - bottom: { NowPlayingTextView(title: self.musicWidget.title ?? "Now Playing") } - ) - activityView = AnyView(view) - } else if self.musicWidget.isPlaying && lyricsAllowed && self.settingsModel.settings.showLyricsInLiveActivity { - let view = StandardActivityView( - left: { AlbumArtView(image: musicWidget.artwork) }, - right: { WaveformView().environmentObject(musicWidget).environmentObject(settingsModel) }, - bottom: { MusicLyricsView(self.showLyricsBinding ?? .constant(false)) } - ) - activityView = AnyView(view) - } else { - // Use an initializer that does not take a bottom view. - let view = StandardActivityView( - left: { AlbumArtView(image: musicWidget.artwork) }, - right: { WaveformView().environmentObject(musicWidget).environmentObject(settingsModel) } - ) - activityView = AnyView(view) - } - - let identifier = (musicWidget.title ?? "") + (musicWidget.artist ?? "") + "\(showNowPlayingText)" - - return (.music, .standard(view: activityView, id: identifier), nil) - } - - private func checkForWeather() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard settingsModel.settings.weatherLiveActivityEnabled, let data = weatherActivityViewModel.weatherData else { return nil } - let view = StandardActivityView(left: { WeatherActivityView.left(for: data) }, right: { WeatherActivityView.right(for: data) }) - return (.weather, .standard(view: AnyView(view), id: data), nil) - } - - private func checkForCalendar() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard settingsModel.settings.calendarLiveActivityEnabled, let event = calendarService.nextEvent, event.startDate.timeIntervalSinceNow < 15 * 60, event.eventIdentifier != lastShownCalendarEventID else { return nil } - let view = StandardActivityView(left: { CalendarActivityView.left(for: event) }, right: { CalendarActivityView.right(for: event) }) - return (.calendar, .standard(view: AnyView(view), id: event.eventIdentifier), 15.0) - } - - private func checkForTimer() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard settingsModel.settings.timersLiveActivityEnabled, timerManager.isRunning else { return nil } - return (.timer, .standard(view: AnyView(StandardActivityView(left: { TimerActivityView().environmentObject(timerManager) })), id: "active_timer"), nil) - } - - private func checkForBattery() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard settingsModel.settings.batteryLiveActivityEnabled, let state = batteryMonitor.currentState else { return nil } - if !state.isLow { hasShownLowBatteryAlert = false }; if !state.isPluggedIn { hasShownPluggedInAlert = false } - let view = StandardActivityView(left: { BatteryActivityView.left(for: state) }, right: { BatteryActivityView.right(for: state) }) - if state.isLow, !hasShownLowBatteryAlert { return (.battery, .standard(view: AnyView(view), id: "low_battery_alert"), 10.0) } - if state.isPluggedIn, !state.isLow, !hasShownPluggedInAlert { return (.battery, .standard(view: AnyView(view), id: state), 5.0) } - return nil - } - - private func checkForEyeBreak() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - if !eyeBreakManager.isBreakTime { hasShownCurrentEyeBreak = false } - guard settingsModel.settings.eyeBreakLiveActivityEnabled, eyeBreakManager.isBreakTime, !hasShownCurrentEyeBreak else { return nil } - let view = StandardActivityView(left: { EyeBreakActivityView.left }, right: { EyeBreakActivityView.right }, bottom: { EyeBreakActivityView.bottom() }) - return (.eyeBreak, .standard(view: AnyView(view), id: "eye_break_active"), 60.0) - } - - private func checkForDesktopChange() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard settingsModel.settings.desktopLiveActivityEnabled, let desktopNum = desktopManager.currentDesktopNumber, desktopNum != lastShownDesktopNumber else { return nil } - let view = StandardActivityView(left: { DesktopActivityView.left(for: desktopNum) }, right: { DesktopActivityView.right(for: desktopNum) }) - return (.desktopChange, .standard(view: AnyView(view), id: desktopNum), 2.0) - } - - private func checkForFocusMode() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard settingsModel.settings.focusLiveActivityEnabled, let mode = focusModeManager.currentFocusMode, mode.identifier != lastShownFocusModeID else { return nil } - let view = StandardActivityView(left: { FocusModeActivityView.left(for: mode) }, right: { FocusModeActivityView.right(for: mode) }) - return (.focusModeChange, .standard(view: AnyView(view), id: mode.identifier), 4.0) - } - - private func checkForSystemHUD() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard let hudType = systemHUDManager.currentHUD else { return nil } - let style: HUDStyle; switch hudType { case .volume: guard settingsModel.settings.enableVolumeHUD else { return nil }; style = settingsModel.settings.volumeHUDStyle; case .brightness: guard settingsModel.settings.enableBrightnessHUD else { return nil }; style = settingsModel.settings.brightnessHUDStyle } - let id = SystemHUDIdentifier(type: hudType, style: style) - let content: LiveActivityContent = (style == .default) ? .full(view: AnyView(SystemHUDView(type: hudType)), id: id) : .standard(view: AnyView(StandardActivityView(left: { SystemHUDSlimActivityView.left(type: hudType) }, right: { SystemHUDSlimActivityView.right(type: hudType) })), id: id) - return (.systemHUD, content, nil) - } - - private func checkForNearDrop() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard let payload = currentNearDropPayload else { return nil } - let content: LiveActivityContent = (payload.state == .waitingForConsent) ? .full(view: AnyView(NearDropLiveActivityView(payload: payload)), id: payload) : .standard(view: AnyView(StandardActivityView(left: { NearDropCompactActivityView.left() }, right: { NearDropCompactActivityView.right(payload: payload) })), id: payload) - return (.nearbyShare, content, (payload.state == .waitingForConsent) ? 60.0 : nil) - } - - private func checkForGeminiLive() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard let payload = currentGeminiPayload else { return nil } - let rightView = GeminiActiveActivityView.right(isMuted: payload.isMicMuted) { self.geminiLiveManager.isMicMuted.toggle(); if self.geminiLiveManager.isMicMuted { self.geminiLiveManager.signalEndOfUserTurn() } } - let view = StandardActivityView(left: { GeminiActiveActivityView.left() }, right: { rightView }) - return (.geminiLive, .standard(view: AnyView(view), id: payload), nil) - } - - private func checkForNotification() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard let notification = notificationManager.latestNotification else { return nil } - let view = StandardActivityView(left: { NotificationActivityView.left(for: notification) }, right: { NotificationActivityView.right(for: notification) }, bottom: { NotificationBottomView(payload: notification) }) - return (.notification, .standard(view: AnyView(view), id: notification.id), 15.0) - } - - private func checkForAudioSwitch() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard let event = audioDeviceManager.lastSwitchEvent, event.id != lastShownAudioSwitchEventID else { return nil } - let view = StandardActivityView(left: { AudioSwitchActivityView.left(for: event) }, right: { AudioSwitchActivityView.right(for: event) }) - return (.audioSwitch, .standard(view: AnyView(view), id: event.id), 5.0) - } - - private func checkForBluetooth() -> (ActivityType, LiveActivityContent, TimeInterval?)? { - guard let event = bluetoothManager.lastEvent, event != lastShownBluetoothEvent else { return nil } - let view: AnyView, duration: TimeInterval; switch event.eventType { case .connected: view = AnyView(StandardActivityView(left: { BluetoothActivityView.left(for: event) }, right: { BluetoothActivityView.right(for: event) })); duration = 6.0; case .disconnected: view = AnyView(StandardActivityView(left: { BluetoothDisconnectedActivityView.left(for: event) }, right: { BluetoothDisconnectedActivityView.right(for: event) })); duration = 5.0; case .batteryLow: view = AnyView(StandardActivityView(left: { BluetoothBatteryActivityView.left(for: event) }, right: { BluetoothBatteryActivityView.right(for: event) })); duration = 12.0 } - return (.bluetooth, .standard(view: view, id: event), duration) - } - - // MARK: - Public Control Functions - func startGeminiLive() { guard currentGeminiPayload == nil else { return }; self.currentGeminiPayload = GeminiPayload(isMicMuted: geminiLiveManager.isMicMuted); evaluateAndDisplayActivity() } - func finishGeminiLive() { self.currentGeminiPayload = nil; evaluateAndDisplayActivity() } - func startNearDropActivity(transfer: TransferMetadata, device: RemoteDeviceInfo, fileURLs: [URL]) { self.currentNearDropPayload = NearDropPayload(id: transfer.id, device: device, transfer: transfer, destinationURLs: fileURLs); evaluateAndDisplayActivity() } - func updateNearDropState(to newState: NearDropTransferState) { guard var payload = self.currentNearDropPayload else { return }; payload.state = newState; if newState == .inProgress { payload.progress = 0.0 }; self.currentNearDropPayload = payload; evaluateAndDisplayActivity() } - func declineNearDropTransfer(id: String) { NearbyConnectionManager.shared.submitUserConsent(transferID: id, accept: false); clearNearDropActivity(id: id) } - func updateNearDropProgress(id: String, progress: Double) { guard var payload = self.currentNearDropPayload, payload.id == id else { return }; payload.progress = progress; self.currentNearDropPayload = payload } - func finishNearDropTransfer(id: String, error: Error?) { guard var payload = self.currentNearDropPayload, payload.id == id, (payload.state == .waitingForConsent || payload.state == .inProgress) else { return }; if let error { let errorString: String; if let nearbyError = error as? NearbyError, case .canceled(let reason) = nearbyError { switch reason { case .userRejected: errorString = "Declined"; case .userCanceled: errorString = "Canceled"; case .notEnoughSpace: errorString = "Not enough space"; case .unsupportedType: errorString = "Unsupported type"; case .timedOut: errorString = "Timed out"; default: errorString = "Canceled" } } else { errorString = error.localizedDescription }; payload.state = .failed(errorString.isEmpty ? "Unknown Error" : errorString) } else { payload.state = .finished }; payload.progress = nil; self.currentNearDropPayload = payload; DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) { self.clearNearDropActivity(id: id) } } - func clearNearDropActivity(id: String? = nil) { if id == nil || self.currentNearDropPayload?.id == id { self.currentNearDropPayload = nil; evaluateAndDisplayActivity() } } -} - -// MARK: - Publisher Extension -extension Publisher { - func mapToVoid() -> AnyPublisher { - self.map { _ in () }.catch { _ in Empty() }.eraseToAnyPublisher() - } -} diff --git a/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift b/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift deleted file mode 100644 index 626a220f..00000000 --- a/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift +++ /dev/null @@ -1,81 +0,0 @@ -// -// NearDropCompactActivityView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-03. -// - -import SwiftUI -import NearbyShare - - -struct NearDropCompactActivityView { - - - static func left() -> some View { - ZStack { - Image(privateName: "shareplay") - .font(.system(size: 14, weight: .semibold)) - .foregroundColor(.white) - } - .frame(width: 20, height: 20) - } - - - static func right(payload: NearDropPayload) -> some View { - ZStack { - switch payload.state { - case .inProgress: - - CustomCircularProgressView(progress: payload.progress ?? 0) - .transition(.opacity.combined(with: .scale(scale: 0.8))) - - case .finished: - Image(systemName: "checkmark.circle.fill") - .foregroundColor(.green) - .transition(.opacity.combined(with: .scale(scale: 0.8))) - - case .failed: - Image(systemName: "xmark.circle.fill") - .foregroundColor(.red) - .transition(.opacity.combined(with: .scale(scale: 0.8))) - - case .waitingForConsent: - Image(systemName: "hourglass") - .foregroundColor(.secondary) - .transition(.opacity.combined(with: .scale(scale: 0.8))) - } - } - .frame(width: 15, height: 15) - .animation(.spring(response: 0.4, dampingFraction: 0.7), value: payload.state) - } -} - - - - - -private struct CustomCircularProgressView: View { - let progress: Double - private let lineWidth: CGFloat = 3.0 - - var body: some View { - ZStack { - - Circle() - .stroke(lineWidth: lineWidth) - .foregroundColor(.accentColor) - .opacity(0.3) - - - Circle() - .trim(from: 0.0, to: min(progress, 1.0)) - .stroke(style: StrokeStyle(lineWidth: lineWidth, lineCap: .round, lineJoin: .round)) - .foregroundColor(.accentColor) - .rotationEffect(Angle(degrees: 270.0)) - } - - - .animation(.linear(duration: 0.2), value: progress) - } -} diff --git a/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift b/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift deleted file mode 100644 index 247e0ef1..00000000 --- a/submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift +++ /dev/null @@ -1,257 +0,0 @@ -// -// NearDropLiveActivityView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import SwiftUI -import NearbyShare - - -struct NearDropLiveActivityView: View { - let payload: NearDropPayload - @EnvironmentObject var liveActivityManager: LiveActivityManager - - - @State private var isShowing = false - - var body: some View { - HStack(spacing: 16) { - - previewIconView - - - VStack(alignment: .leading, spacing: 10) { - - VStack(alignment: .leading, spacing: 2) { - Text("From \(payload.device.name)") - .font(.headline) - .fontWeight(.bold) - .foregroundColor(.primary) - - Text(fileInfoText) - .font(.subheadline) - .foregroundColor(.secondary) - .lineLimit(1) - .truncationMode(.middle) - } - - - actionView - .frame(height: 36) - } - - .animation(.spring(response: 0.3, dampingFraction: 0.8), value: payload.state) - } - .padding(12) - .padding(.horizontal) - .padding(.top, 25) - - - .scaleEffect(isShowing ? 1 : 0.95) - .opacity(isShowing ? 1 : 0) - .onAppear { - withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) { - isShowing = true - } - } - } - - - - @ViewBuilder - private var previewIconView: some View { - ZStack { - RoundedRectangle(cornerRadius: 18, style: .continuous) - .fill(Color.accentColor) - - Image(systemName: iconName(for: payload.transfer)) - .font(.system(size: 36, weight: .regular)) - .foregroundColor(.white) - .shadow(color: .black.opacity(0.15), radius: 3, y: 2) - } - .frame(width: 72, height: 72) - } - - @ViewBuilder - private var actionView: some View { - switch payload.state { - case .waitingForConsent: - IntegratedActionIconButtonsView(payload: payload) - .environmentObject(liveActivityManager) - - .transition(.opacity) - - case .inProgress: - ModernLinearProgressView(progress: payload.progress ?? 0) - .transition(.opacity) - - case .finished: - StatusTagView(text: "Transfer Complete", color: .green) - .transition(.opacity) - - case .failed(let reason): - StatusTagView(text: "Failed: \(reason)", color: .red) - .transition(.opacity) - } - } - - - - private var fileInfoText: String { - if let textTitle = payload.transfer.textDescription { - return textTitle - } - if payload.transfer.files.count == 1 { return payload.transfer.files[0].name } - return String.localizedStringWithFormat(NSLocalizedString("NFiles", comment: ""), payload.transfer.files.count) - } - - private func extractURL(from string: String) -> URL? { - if let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) { - if let match = detector.firstMatch(in: string, options: [], range: NSRange(location: 0, length: string.utf16.count)) { - return match.url - } - } - return nil - } - - private func iconName(for transfer: TransferMetadata) -> String { - if let desc = transfer.textDescription, extractURL(from: desc) != nil { return "link" } - if transfer.textDescription != nil { return "text.quote" } - guard let firstFile = transfer.files.first else { return "questionmark" } - if transfer.files.count > 1 { return "doc.on.doc.fill" } - let mimeType = firstFile.mimeType.lowercased() - if mimeType.starts(with: "image/") { return "photo" } - if mimeType.starts(with: "video/") { return "video.fill" } - if mimeType.starts(with: "audio/") { return "music.note" } - if mimeType.contains("pdf") { return "doc.richtext.fill" } - if mimeType.contains("zip") || mimeType.contains("archive") { return "archivebox.fill" } - return "doc.fill" - } -} - - - -private struct IntegratedActionIconButtonsView: View { - let payload: NearDropPayload - @EnvironmentObject var liveActivityManager: LiveActivityManager - - private func submitConsent(accept: Bool, action: NearDropUserAction = .save) { - if accept { liveActivityManager.updateNearDropState(to: .inProgress) } - NearbyConnectionManager.shared.submitUserConsent(transferID: payload.id, accept: accept, action: action) - } - - var body: some View { - HStack(spacing: 10) { - let declineButton = Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } - .buttonStyle(ModernIconActionButtonStyle(type: .destructive)) - .accessibilityLabel("Decline") - - if let textContent = payload.transfer.textDescription { - if let _ = URL(string: textContent) { - declineButton - Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } - .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) - .accessibilityLabel("Copy Link") - Button { submitConsent(accept: true, action: .open) } label: { Image(systemName: "arrow.up.right.square") } - .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) - .accessibilityLabel("Open Link") - } else { - declineButton - Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } - .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) - .accessibilityLabel("Copy Text") - Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "square.and.arrow.down") } - .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) - .accessibilityLabel("Save Text") - } - } else { - declineButton - Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "checkmark") } - .buttonStyle(ModernIconActionButtonStyle(type: .prominent)) - .accessibilityLabel("Accept") - } - Spacer() - } - } -} - -private struct ModernLinearProgressView: View { - let progress: Double - - var body: some View { - GeometryReader { geometry in - ZStack(alignment: .leading) { - Capsule().fill(Color.primary.opacity(0.1)) - Capsule().fill(Color.accentColor).frame(width: geometry.size.width * progress) - Text("\(Int(progress * 100))%") - .font(.caption.bold()) - .foregroundColor(.white) - .padding(.horizontal, 8) - } - } - .animation(.easeOut, value: progress) - } -} - -private struct StatusTagView: View { - let text: String - let color: Color - - var body: some View { - HStack(spacing: 6) { - Image(systemName: color == .green ? "checkmark.circle.fill" : "xmark.circle.fill") - Text(text).lineLimit(1) - } - .font(.caption.bold()) - .padding(.horizontal, 10) - .padding(.vertical, 6) - .background(color.opacity(0.2)) - .foregroundStyle(color) - .clipShape(Capsule()) - .frame(maxWidth: .infinity, alignment: .leading) - } -} - - - - -enum ModernButtonType { - case prominent, normal, destructive -} - -private struct ModernIconActionButtonStyle: ButtonStyle { - var type: ModernButtonType - - func makeBody(configuration: Configuration) -> some View { - configuration.label - .font(.system(size: 16, weight: .semibold)) - .foregroundColor(foregroundColor) - .frame(width: 36, height: 36) - .background(backgroundColor) - .clipShape(Circle()) - .scaleEffect(configuration.isPressed ? 0.90 : 1.0) - .animation(.spring(response: 0.2, dampingFraction: 0.6), value: configuration.isPressed) - } - - private var backgroundColor: Color { - switch type { - case .prominent: - return .accentColor - case .normal: - return .secondary.opacity(0.2) - case .destructive: - return .red - } - } - - private var foregroundColor: Color { - switch type { - case .prominent, .destructive: - return .white - case .normal: - return .primary - } - } -} diff --git a/submissions/sapphire/Sapphire/Models/AppModels.swift b/submissions/sapphire/Sapphire/Models/AppModels.swift deleted file mode 100644 index 9dff04fc..00000000 --- a/submissions/sapphire/Sapphire/Models/AppModels.swift +++ /dev/null @@ -1,121 +0,0 @@ -// -// AppModels.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-06. -// - -import SwiftUI -import NearbyShare - -enum LiveActivityContent: Equatable { - case none - case full(view: AnyView, id: AnyHashable) - case standard(view: AnyView, id: AnyHashable) - - static func == (lhs: LiveActivityContent, rhs: LiveActivityContent) -> Bool { - switch (lhs, rhs) { - case (.none, .none): return true - case let (.full(_, lhsId), .full(_, rhsId)): return lhsId == rhsId - case let (.standard(_, lhsId), .standard(_, rhsId)): return lhsId == rhsId - default: return false - } - } -} - -struct StandardActivityView: View { - let leftContent: LeftContent? - let rightContent: RightContent? - let bottomContent: BottomContent? - let onBottomContentTapped: (() -> Void)? - - init( - @ViewBuilder left: () -> LeftContent, - @ViewBuilder right: () -> RightContent, - @ViewBuilder bottom: () -> BottomContent, - onBottomContentTapped: (() -> Void)? = nil - ) { - self.leftContent = left() - self.rightContent = right() - self.bottomContent = bottom() - self.onBottomContentTapped = onBottomContentTapped - } - - var body: some View { - VStack(spacing: 0) { - HStack(spacing: NotchConfiguration.initialSize.width) { - leftContent.padding(.leading, 10) - rightContent.padding(.trailing, 10) - } - .frame(minHeight: NotchConfiguration.initialSize.height) - .modifier(SizeLoggingViewModifier(label: "StandardActivityView Internal HStack")) - - if !(bottomContent is EmptyView) { - VStack { - Divider().opacity(0.3) - bottomContent - .padding(.bottom, 10) - .contentShape(Rectangle()) - .onTapGesture { onBottomContentTapped?() } - } - } - } - .fixedSize() - } -} - -extension StandardActivityView where BottomContent == EmptyView { - init( - @ViewBuilder left: () -> LeftContent, - @ViewBuilder right: () -> RightContent, - onBottomContentTapped: (() -> Void)? = nil - ) { - self.init(left: left, right: right, bottom: { EmptyView() }, onBottomContentTapped: onBottomContentTapped) - } -} - -extension StandardActivityView where RightContent == EmptyView, BottomContent == EmptyView { - init( - @ViewBuilder left: () -> LeftContent, - onBottomContentTapped: (() -> Void)? = nil - ) { - self.init(left: left, right: { EmptyView() }, bottom: { EmptyView() }, onBottomContentTapped: onBottomContentTapped) - } -} - - - -struct NotificationPayload: Identifiable, Equatable { - let id: String, appIdentifier: String, title: String, body: String - var hasAudioAttachment: Bool { body.contains("Audio Message") || body.contains("sent an audio message") } - var hasImageAttachment: Bool { body.contains("sent an image") } - var appName: String { - switch appIdentifier { - case "com.apple.iChat": "Messages"; case "com.apple.facetime": "FaceTime"; case "com.apple.sharingd": "AirDrop"; default: "Notification" - } - } -} - -enum NearDropTransferState: Equatable, Hashable { case waitingForConsent, inProgress, finished, failed(String) } -struct NearDropPayload: Identifiable, Hashable { - let id: String, device: RemoteDeviceInfo, transfer: TransferMetadata, destinationURLs: [URL] - var state: NearDropTransferState = .waitingForConsent; var progress: Double? - static func == (lhs: NearDropPayload, rhs: NearDropPayload) -> Bool { lhs.id == rhs.id && lhs.state == rhs.state && lhs.progress == rhs.progress } - func hash(into hasher: inout Hasher) { hasher.combine(id); hasher.combine(state); hasher.combine(progress) } -} - -enum GeminiLiveState: Equatable, Hashable { case active } -struct GeminiPayload: Identifiable, Hashable { - let id = UUID(); var state: GeminiLiveState = .active; var isMicMuted: Bool = true -} - -struct LyricLine: Identifiable, Hashable { - let id = UUID(); let text: String; let timestamp: TimeInterval; var translatedText: String? -} - -struct BatteryState: Equatable, Hashable { - let level: Int, isCharging: Bool, isPluggedIn: Bool - var isLow: Bool { level <= 20 && !isCharging } -} - -struct FocusModeInfo: Equatable, Hashable { let name: String, identifier: String } diff --git a/submissions/sapphire/Sapphire/Models/SpotifyModels.swift b/submissions/sapphire/Sapphire/Models/SpotifyModels.swift deleted file mode 100644 index d490e2c6..00000000 --- a/submissions/sapphire/Sapphire/Models/SpotifyModels.swift +++ /dev/null @@ -1,125 +0,0 @@ -// -// SpotifyModels.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import Foundation - - -struct SpotifyImage: Codable { - let url: String -} - -struct SpotifyAlbum: Codable { - let images: [SpotifyImage] -} - -struct SpotifyArtist: Codable { - let name: String -} - - - -struct PlaybackState: Codable { - let device: SpotifyDevice - let item: SpotifyTrack? - let isPlaying: Bool - let progressMs: Int? - - enum CodingKeys: String, CodingKey { - case device, item, progressMs = "progress_ms", isPlaying = "is_playing" - } -} - -struct UserProfile: Codable, Identifiable { - let id: String - let displayName: String - let product: String - - enum CodingKeys: String, CodingKey { - case id, product, displayName = "display_name" - } -} - - -struct SpotifyUserSimple: Codable, Identifiable { - let id: String - let displayName: String - - enum CodingKeys: String, CodingKey { - case id, displayName = "display_name" - } -} - -struct SpotifyTrack: Codable, Identifiable { - let id: String - let name: String - let uri: String - let album: SpotifyAlbum - let artists: [SpotifyArtist] - - var imageURL: URL? { - guard let urlString = images.first?.url else { return nil } - return URL(string: urlString) - } - - private var images: [SpotifyImage] { - return album.images - } -} - -struct SpotifyPlaylist: Codable, Identifiable { - let id: String - let name: String - let uri: String - let images: [SpotifyImage] - - let owner: SpotifyUserSimple - - var imageURL: URL? { - guard let urlString = images.first?.url else { return nil } - return URL(string: urlString) - } -} - -struct SpotifyDevice: Codable, Identifiable { - let id: String? - let name: String - let type: String - let isActive: Bool - let volumePercent: Int? - enum CodingKeys: String, CodingKey { case id, name, type, isActive = "is_active", volumePercent = "volume_percent" } -} - -struct SpotifyQueue: Codable { - let currentlyPlaying: SpotifyTrack? - let queue: [SpotifyTrack] - enum CodingKeys: String, CodingKey { case currentlyPlaying = "currently_playing", queue } -} - - -struct AudioAnalysis: Codable { - let segments: [AnalysisSegment] -} - -struct AnalysisSegment: Codable { - let start: Double - let duration: Double - let loudness_max: Double - - enum CodingKeys: String, CodingKey { - case start, duration - case loudness_max = "loudness_max" - } -} - - -struct SearchResponse: Codable { - let tracks: TrackSearchResult -} - -struct TrackSearchResult: Codable { - let items: [SpotifyTrack] -} diff --git a/submissions/sapphire/Sapphire/Models/WeatherModels.swift b/submissions/sapphire/Sapphire/Models/WeatherModels.swift deleted file mode 100644 index 02bcb94d..00000000 --- a/submissions/sapphire/Sapphire/Models/WeatherModels.swift +++ /dev/null @@ -1,148 +0,0 @@ -// -// WeatherModels.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import Foundation - - -struct WeatherApiResponse: Codable { - var conditionsshort: ConditionsShort? - var fcstdaily10short: FcstDaily10Short? - var fcsthourly24short: FcstHourly24Short? - var nowlinks: Nowlinks? -} - -struct ConditionsShort: Codable { - var observation: Observation? -} - -struct Observation: Codable { - var imperial: ImperialObservation? - var metric: ImperialObservation? - var wx_phrase: String? - var wx_icon: Int? - var rh: Int? - var uv_index: Int? - var uv_desc: String? - var vis: Double? - var pressure: Double? -} - -struct ImperialObservation: Codable { - var temp: Int? - var feels_like: Int? - var wspd: Int? -} - -struct FcstDaily10Short: Codable { - var forecasts: [DailyForecast]? -} - -struct DailyForecast: Codable { - var dow: String? - var imperial: ImperialForecast? - var metric: ImperialForecast? - var day: DayPart? - var night: DayPart? - var sunrise: String? - var sunset: String? -} - -struct ImperialForecast: Codable { - var max_temp: Int? - var min_temp: Int? -} - -struct DayPart: Codable { - var icon_cd: Int? - var pop: Int? -} - -struct FcstHourly24Short: Codable { - var forecasts: [HourlyForecast]? -} - -struct HourlyForecast: Codable { - var fcst_valid: Int? - var icon_cd: Int? - var imperial: ImperialHourlyForecast? - var metric: ImperialHourlyForecast? -} - -struct ImperialHourlyForecast: Codable { - var temp: Int? -} - -struct Nowlinks: Codable { - var nowlink: [Nowlink]? -} - -struct Nowlink: Codable { - var url: String? -} - - -struct ProcessedWeatherData: Hashable { - let locationName: String - let temperature: Int - let temperatureMetric: Int - let highTemp: Int - let highTempMetric: Int - let lowTemp: Int - let lowTempMetric: Int - let conditionDescription: String - let iconCode: Int - let feelsLike: Int - let feelsLikeMetric: Int - let windInfo: String - let humidity: String - let precipChance: Int - let uvIndex: String - let sunriseTime: String - let sunsetTime: String - let visibility: String - let pressure: String - let dailyForecasts: [DailyForecastUIData] - let hourlyForecasts: [HourlyForecastUIData] - - static func empty() -> ProcessedWeatherData { - .init(locationName: "N/A", temperature: 0, temperatureMetric: 0, highTemp: 0, highTempMetric: 0, lowTemp: 0, lowTempMetric: 0, conditionDescription: "N/A", iconCode: 44, feelsLike: 0, feelsLikeMetric: 0, windInfo: "N/A", humidity: "N/A", precipChance: 0, uvIndex: "N/A", sunriseTime: "N/A", sunsetTime: "N/A", visibility: "N/A", pressure: "N/A", dailyForecasts: [], hourlyForecasts: []) - } -} - -struct DailyForecastUIData: Identifiable, Hashable { - let id = UUID() - let dayOfWeek: String - let iconName: String - let highTemp: Int - let lowTemp: Int - let highTempMetric: Int - let lowTempMetric: Int - - static func == (lhs: DailyForecastUIData, rhs: DailyForecastUIData) -> Bool { - lhs.dayOfWeek == rhs.dayOfWeek - } - - func hash(into hasher: inout Hasher) { - hasher.combine(dayOfWeek) - } -} - -struct HourlyForecastUIData: Identifiable, Hashable { - let id = UUID() - let time: String - let iconName: String - let temperature: String - let temperatureMetric: String - - static func == (lhs: HourlyForecastUIData, rhs: HourlyForecastUIData) -> Bool { - lhs.time == rhs.time - } - - func hash(into hasher: inout Hasher) { - hasher.combine(time) - } -} diff --git a/submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift b/submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift deleted file mode 100644 index a4e70a23..00000000 --- a/submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// weatherActivityViewModel.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-28. -// - -import Foundation -import SwiftUI -import CoreLocation - -class WeatherActivityViewModel: ObservableObject { - private let service = WeatherService() - @Published var weatherData: ProcessedWeatherData? - - init() { - fetch() - - Timer.scheduledTimer(withTimeInterval: 60 * 15, repeats: true) { [weak self] _ in - self?.fetch() - } - } - - func fetch() { - service.fetchWeather { [weak self] result in - DispatchQueue.main.async { - switch result { - case .success(let data): - self?.weatherData = data - case .failure(let error): - self?.weatherData = nil - } - } - } - } -} diff --git a/submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift b/submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift deleted file mode 100644 index 09b17ee4..00000000 --- a/submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift +++ /dev/null @@ -1,64 +0,0 @@ -// -// CustomNotchShape.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-05-12. -// - -import SwiftUI - -struct CustomNotchShape: Shape { - var cornerRadius: CGFloat - - - var animatableData: CGFloat { - get { cornerRadius } - set { cornerRadius = newValue } - } - - - - func path(in rect: CGRect) -> Path { - - - let radii = Self.calculateRadii(cornerRadius: cornerRadius, in: rect) - let topRadius = radii.top - let safeBottomRadius = radii.bottom - - - var path = Path() - path.move(to: CGPoint(x: rect.minX, y: rect.minY)) - path.addQuadCurve(to: CGPoint(x: rect.minX + topRadius, y: rect.minY + topRadius), control: CGPoint(x: rect.minX + topRadius, y: rect.minY)) - path.addLine(to: CGPoint(x: rect.minX + topRadius, y: rect.maxY - safeBottomRadius)) - if safeBottomRadius > 0 { path.addArc(center: CGPoint(x: rect.minX + topRadius + safeBottomRadius, y: rect.maxY - safeBottomRadius), radius: safeBottomRadius, startAngle: Angle(degrees: 180), endAngle: Angle(degrees: 90), clockwise: true) } else { path.addLine(to: CGPoint(x: rect.minX + topRadius, y: rect.maxY)) } - path.addLine(to: CGPoint(x: rect.maxX - topRadius - safeBottomRadius, y: rect.maxY)) - if safeBottomRadius > 0 { path.addArc(center: CGPoint(x: rect.maxX - topRadius - safeBottomRadius, y: rect.maxY - safeBottomRadius), radius: safeBottomRadius, startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 0), clockwise: true) } else { path.addLine(to: CGPoint(x: rect.maxX - topRadius, y: rect.maxY)) } - path.addLine(to: CGPoint(x: rect.maxX - topRadius, y: rect.minY + topRadius)) - path.addQuadCurve(to: CGPoint(x: rect.maxX, y: rect.minY), control: CGPoint(x: rect.maxX - topRadius, y: rect.minY)) - path.closeSubpath() - return path - } - - - - - - - - - - static func calculateRadii(cornerRadius: CGFloat, in rect: CGRect) -> (top: CGFloat, bottom: CGFloat) { - - let derivedTopRadiusBase = cornerRadius > 15 ? cornerRadius - 5 : 5 - let maxPossibleTopRadiusFromHeight = rect.height > 0 ? rect.height / 2.0 : 0 - let derivedTopRadius = min(derivedTopRadiusBase, maxPossibleTopRadiusFromHeight) - let topRadius = max(0.0, min(derivedTopRadius, rect.width / 2.0)) - - - let availableWidthForBottomRadii = rect.width - 2 * topRadius - let availableHeightForBottomRadius = rect.height - topRadius - let safeBottomRadius = max(0.0, min(cornerRadius, availableWidthForBottomRadii / 2.0, availableHeightForBottomRadius)) - - return (top: topRadius, bottom: safeBottomRadius) - } -} diff --git a/submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift b/submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift deleted file mode 100644 index c44d5a68..00000000 --- a/submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// NotchConfiguration.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-05-08. -// - -import SwiftUI - -struct NotchConfiguration { - - static let universalWidth: CGFloat = 195 - static let universalHeight: CGFloat = 32 - static let initialSize = CGSize(width: universalWidth, height: universalHeight) - static let initialCornerRadius: CGFloat = 10 - - - static let scaleFactor: CGFloat = 1.12 - static let hoverExpandedSize = CGSize(width: universalWidth * scaleFactor, height: universalHeight * scaleFactor) - static let hoverExpandedCornerRadius: CGFloat = 10 - - static let autoExpandedCornerRadius: CGFloat = 14 - static let autoExpandedTallHeight: CGFloat = 80 - - static let autoExpandedContentVerticalPadding: CGFloat = 8 - - static let clickExpandedCornerRadius: CGFloat = 40 - - - static let collapseDelay: TimeInterval = 0.07 - - - - static let expandAnimation = Animation.spring(response: 0.45, dampingFraction: 0.625, blendDuration: 0) - - - - - - - static let collapseAnimation = Animation.spring(response: 0.35, dampingFraction: 1, blendDuration: 0) - - static let autoExpandAnimation = Animation.spring(response: 0.6, dampingFraction: 0.6, blendDuration: 0) - - - static let expandedShadowColor = Color.black.opacity(0.4) - static let expandedShadowRadius: CGFloat = 18 - static let expandedShadowOffset = CGPoint(x: 0, y: 8) - - - static let contentTopPadding: CGFloat = 10 - static let contentBottomPadding: CGFloat = 10 - static let contentHorizontalPadding: CGFloat = 35 - static let contentVisibilityThresholdHeight: CGFloat = universalHeight + 1 -} diff --git a/submissions/sapphire/Sapphire/Notch/NotchController.swift b/submissions/sapphire/Sapphire/Notch/NotchController.swift deleted file mode 100644 index 257323dc..00000000 --- a/submissions/sapphire/Sapphire/Notch/NotchController.swift +++ /dev/null @@ -1,507 +0,0 @@ -// -// NotchController.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import SwiftUI -import Combine -import ScreenCaptureKit - - -fileprivate class SettingsWindowDelegate: NSObject, NSWindowDelegate { - var onClose: () -> Void - init(onClose: @escaping () -> Void) { self.onClose = onClose } - func windowWillClose(_ notification: Notification) { onClose() } -} - -struct NotchController: View { - let notchWindow: NSWindow? - - enum NotchState { - case initial, autoExpanded, hoverExpanded, clickExpanded - } - - - @EnvironmentObject var liveActivityManager: LiveActivityManager - @EnvironmentObject var geminiLiveManager: GeminiLiveManager - @EnvironmentObject var pickerHelper: ContentPickerHelper - @EnvironmentObject var settings: SettingsModel - - - @State private var notchState: NotchState = .initial - @State private var isHovered: Bool = false - @State private var collapseTimer: Timer? - @State private var widgetChangeState: Bool = false - @State private var isPinned = false - - - @State private var settingsWindow: NSWindow? - @State private var settingsDelegate: SettingsWindowDelegate? - - - @State private var isGeminiHovered = false - - - @State private var animatedWidth: CGFloat = NotchConfiguration.initialSize.width - @State private var animatedHeight: CGFloat = NotchConfiguration.initialSize.height - @State private var animatedCornerRadius: CGFloat = NotchConfiguration.initialCornerRadius - @State private var shadowOpacity: Double = 0 - - - @State private var measuredClickContentSize: CGSize = .zero - @State private var measuredAutoContentSize: CGSize = .zero - - - @State private var widgetMode: NotchWidgetMode = .defaultWidgets - - - @State private var clickContentOpacity: Double = 0 - @State private var autoContentOpacity: Double = 0 - - - private var isLiveActivityActive: Bool { liveActivityManager.currentActivity != .none } - private var isFullViewActivity: Bool { liveActivityManager.isFullViewActivity } - - private var activeScaleFactor: CGFloat { - guard notchState == .hoverExpanded && !isFullViewActivity else { return 1.0 } - return NotchConfiguration.scaleFactor - } - - public init(notchWindow: NSWindow?) { - self.notchWindow = notchWindow - } - - - var body: some View { - ZStack(alignment: .top) { - CustomNotchShape(cornerRadius: animatedCornerRadius) - .fill(Color.black) - .shadow( - color: NotchConfiguration.expandedShadowColor.opacity(shadowOpacity), - radius: notchState == .clickExpanded ? NotchConfiguration.expandedShadowRadius : 12, - y: notchState == .clickExpanded ? NotchConfiguration.expandedShadowOffset.y : 6 - ) - .onTapGesture(perform: handleTap) - - ZStack(alignment: .top) { - contentView - if notchState == .clickExpanded { - expandedOverlayIcons - .transition(.opacity.animation(.easeInOut(duration: 0.2))) - .zIndex(1) - } - } - .mask(CustomNotchShape(cornerRadius: animatedCornerRadius)) - } - .frame(width: animatedWidth, height: animatedHeight) - .contentShape(CustomNotchShape(cornerRadius: animatedCornerRadius)) - .onHover(perform: handleHover) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .background(measurementView.hidden()) - .onAppear(perform: updateMouseEventHandling) - .onChange(of: liveActivityManager.currentActivity, perform: handleActivityChange) - .onChange(of: notchState, perform: handleStateChange) - .onChange(of: isHovered, perform: { _ in updateMouseEventHandling() }) - .onChange(of: widgetMode, perform: handleWidgetModeChange) - .onChange(of: measuredClickContentSize) { newSize in - if notchState == .clickExpanded { - withAnimation(NotchConfiguration.expandAnimation) { - animatedWidth = newSize.width - animatedHeight = newSize.height - } - } - } - .onChange(of: measuredAutoContentSize) { newSize in - let scale = activeScaleFactor - let targetHeight = newSize.height * scale - let isShrinking = targetHeight < self.animatedHeight - let expandAnimation = (notchState == .hoverExpanded) ? NotchConfiguration.expandAnimation : NotchConfiguration.autoExpandAnimation - let animationToUse = isShrinking ? NotchConfiguration.collapseAnimation : expandAnimation - - if notchState == .autoExpanded || (notchState == .hoverExpanded && isLiveActivityActive) { - withAnimation(animationToUse) { - animatedWidth = newSize.width * scale - animatedHeight = targetHeight - } - } - } - .onReceive(pickerHelper.pickerResultPublisher) { result in - switch result { - case .success(let filter): - geminiLiveManager.startSession(with: filter) - liveActivityManager.startGeminiLive() - case .failure(let error): - if let error = error { - } else { - } - } - } - } - - - - @ViewBuilder - private var contentView: some View { - if notchState == .clickExpanded { - NotchWidgetView(mode: $widgetMode) - .padding(.top, NotchConfiguration.contentTopPadding) - .padding(.bottom, NotchConfiguration.contentBottomPadding) - .padding(.horizontal, NotchConfiguration.contentHorizontalPadding) - .opacity(clickContentOpacity) - .frame(width: animatedWidth, height: animatedHeight) - .clipped() - .allowsHitTesting(true) - } else if isLiveActivityActive && (notchState == .autoExpanded || notchState == .hoverExpanded) { - Group { - autoActivityView - } - .id(liveActivityManager.contentUpdateID) - .transition(.asymmetric( - insertion: .opacity.combined(with: .scale(scale: 0.98, anchor: .top)), - removal: .opacity.combined(with: .scale(scale: 1.02, anchor: .top)) - )) - .animation(NotchConfiguration.autoExpandAnimation, value: liveActivityManager.contentUpdateID) - .opacity(autoContentOpacity) - .scaleEffect(activeScaleFactor) - .animation(NotchConfiguration.expandAnimation, value: notchState) - .frame(width: animatedWidth, height: animatedHeight) - .clipped() - .allowsHitTesting(isHovered) - .transition(.opacity.animation(.easeInOut(duration: 0.2))) - } - } - - @ViewBuilder - private var autoActivityView: some View { - switch liveActivityManager.activityContent { - case .standard(let view, _): - view - case .full(let view, _): - view - case .none: - EmptyView() - } - } - - @ViewBuilder - private var measurementView: some View { - ZStack { - NotchWidgetView(mode: $widgetMode) - .padding(.top, NotchConfiguration.contentTopPadding) - .padding(.bottom, NotchConfiguration.contentBottomPadding) - .padding(.horizontal, NotchConfiguration.contentHorizontalPadding) - .fixedSize() - .background(GeometryReader { geo in Color.clear.onSizeChange(of: geo.size) { measuredClickContentSize = $0 } }) - - autoActivityView - .fixedSize() - .background(GeometryReader { geo in Color.clear.onSizeChange(of: geo.size) { measuredAutoContentSize = $0 } }) - } - } - - @ViewBuilder - private var expandedOverlayIcons: some View { - if widgetMode == .defaultWidgets { - defaultModeIcons - } else { - backButton - } - } - - @ViewBuilder - private var defaultModeIcons: some View { - HStack { - HStack(spacing: 0) { - SubtleIconButton(systemName: "gearshape", action: openSettingsWindow) - if settings.settings.geminiEnabled { geminiButton } - } - Spacer() - HStack(spacing: 0) { - if settings.settings.dropboxIconEnabled { - SubtleIconButton(systemName: "arrow.down.circle", action: { widgetMode = .nearDrop }) - } - if settings.settings.batteryEstimatorEnabled { - SubtleIconButton(systemName: "battery.100", action: { print("Battery tapped") }) - } - if settings.settings.pinEnabled { - SubtleIconButton(systemName: isPinned ? "pin.fill" : "pin", action: { isPinned.toggle(); if isPinned { collapseTimer?.invalidate() } }) - } - } - } - .padding(.horizontal, 40) - .frame(height: NotchConfiguration.initialSize.height) - .frame(width: animatedWidth) - .offset(y: -4) - } - - @ViewBuilder - private var backButton: some View { - HStack { - Button(action: { - withAnimation(NotchConfiguration.expandAnimation) { - widgetMode = .defaultWidgets - } - }) { - - ZStack(alignment: .leading) { - - Rectangle() - .fill(Color.clear) - .frame(width: 100, height: 60) - - - Image(systemName: "chevron.left.circle.fill") - .font(.title2) - .foregroundStyle(.secondary) - .symbolRenderingMode(.hierarchical) - .padding(.leading, 40) - } - } - .buttonStyle(.plain) - - Spacer() - } - .frame(height: NotchConfiguration.initialSize.height) - .frame(width: animatedWidth) - } - - @ViewBuilder - private var geminiButton: some View { - let baseSize: CGFloat = 25 - let geminiGradient = LinearGradient( - gradient: Gradient(colors: [Color.purple.opacity(0.8), Color.indigo.opacity(0.6)]), - startPoint: .topLeading, - endPoint: .bottomTrailing - ) - - Button(action: { - pickerHelper.showPicker() - }) { - HStack(spacing: 4) { - Image(systemName: "sparkle") - .font(.system(size: isGeminiHovered ? 12 : 14, weight: .medium)) - .rotationEffect(.degrees(isGeminiHovered ? 90 : 0)) - .foregroundStyle( - isGeminiHovered ? - LinearGradient(gradient: Gradient(colors: [Color.white, Color.white.opacity(0.5)]), startPoint: .topLeading, endPoint: .bottomTrailing) : - LinearGradient(gradient: Gradient(colors: [Color.blue, Color.pink]), startPoint: .topLeading, endPoint: .bottomTrailing) - ) - .animation(.spring(response: 0.5, dampingFraction: 0.6), value: isGeminiHovered) - - if isGeminiHovered { - Text("Go live") - .font(.system(size: 10, weight: .semibold)) - .fixedSize() - .foregroundColor(.white) - .transition(.opacity.combined(with: .move(edge: .leading))) - } - } - .padding(.horizontal, isGeminiHovered ? 10 : 0) - .frame(width: isGeminiHovered ? nil : baseSize, height: baseSize) - .background(isGeminiHovered ? geminiGradient : nil) - .clipShape(Capsule()) - } - .buttonStyle(.plain) - .onHover { hovering in - withAnimation(.spring(response: 0.5, dampingFraction: 1)) { - isGeminiHovered = hovering - } - } - } - - - - private func handleTap() { - collapseTimer?.invalidate() - if isPinned { return } - - if isLiveActivityActive && (notchState == .autoExpanded || notchState == .hoverExpanded) { - let activityType = liveActivityManager.currentActivity - if activityType == .music, settings.settings.musicOpenOnClick { - notchState = .clickExpanded; widgetMode = .musicPlayer; return - } - if activityType == .weather, settings.settings.weatherOpenOnClick { - notchState = .clickExpanded; widgetMode = .weatherPlayer; return - } - } - - switch notchState { - case .initial, .hoverExpanded, .autoExpanded: notchState = .clickExpanded - case .clickExpanded: notchState = isLiveActivityActive ? .autoExpanded : .initial - } - } - - private func handleHover(hovering: Bool) { - isHovered = hovering - if hovering { - collapseTimer?.invalidate() - if notchState == .initial || notchState == .autoExpanded { - notchState = .hoverExpanded - } - } else if !widgetChangeState { - let delay = (widgetMode == .defaultWidgets) ? 0.0 : NotchConfiguration.collapseDelay - scheduleCollapse(after: delay) - } - } - - private func handleActivityChange(_ newActivity: ActivityType) { - guard notchState != .clickExpanded else { return } - notchState = newActivity != .none ? .autoExpanded : .initial - } - - private func handleStateChange(newState: NotchState) { - updateMouseEventHandling() - - switch newState { - case .initial: - withAnimation(NotchConfiguration.collapseAnimation) { - animatedWidth = NotchConfiguration.initialSize.width - animatedHeight = NotchConfiguration.initialSize.height - animatedCornerRadius = NotchConfiguration.initialCornerRadius - widgetMode = .defaultWidgets - autoContentOpacity = 0 - shadowOpacity = 0 - isPinned = false - } - withAnimation(.easeOut(duration: 0.1)) { clickContentOpacity = 0 } - - case .hoverExpanded: - let scale = activeScaleFactor - let targetWidth = isLiveActivityActive ? measuredAutoContentSize.width * scale : NotchConfiguration.hoverExpandedSize.width - let targetHeight = isLiveActivityActive ? measuredAutoContentSize.height * scale : NotchConfiguration.hoverExpandedSize.height - let targetRadius = (scale > 1.0 && self.isLiveActivityActive) ? NotchConfiguration.autoExpandedCornerRadius : NotchConfiguration.hoverExpandedCornerRadius - - withAnimation(NotchConfiguration.expandAnimation) { - animatedWidth = targetWidth; animatedHeight = targetHeight; animatedCornerRadius = targetRadius - widgetMode = .defaultWidgets - if isLiveActivityActive { autoContentOpacity = 1 } - shadowOpacity = 1 - } - withAnimation(.easeOut(duration: 0.1)) { clickContentOpacity = 0 } - - case .clickExpanded: - withAnimation(NotchConfiguration.expandAnimation) { - animatedWidth = measuredClickContentSize.width - animatedHeight = measuredClickContentSize.height - animatedCornerRadius = NotchConfiguration.clickExpandedCornerRadius - autoContentOpacity = 0 - shadowOpacity = 1 - } - DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) { - withAnimation(.easeIn(duration: 0.6)) { clickContentOpacity = 1 } - } - - case .autoExpanded: - let isShrinking = measuredAutoContentSize.height < self.animatedHeight - let animationToUse = isShrinking ? NotchConfiguration.collapseAnimation : NotchConfiguration.autoExpandAnimation - - - withAnimation(animationToUse) { - animatedWidth = measuredAutoContentSize.width - animatedHeight = measuredAutoContentSize.height - animatedCornerRadius = NotchConfiguration.autoExpandedCornerRadius - widgetMode = .defaultWidgets - shadowOpacity = 0 - autoContentOpacity = 1 - } - } - } - - private func handleWidgetModeChange(_ newMode: NotchWidgetMode) { - guard notchState == .clickExpanded else { return } - widgetChangeState = true - DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { - widgetChangeState = false - if !isHovered { scheduleCollapse() } - } - } - - private func updateMouseEventHandling() { - let isInteractive = notchState == .clickExpanded || isHovered - notchWindow?.ignoresMouseEvents = !isInteractive - } - - private func scheduleCollapse(after delay: TimeInterval = NotchConfiguration.collapseDelay) { - collapseTimer?.invalidate() - guard !isPinned else { return } - collapseTimer = Timer.scheduledTimer(withTimeInterval: delay, repeats: false) { _ in if !self.isHovered { self.notchState = self.isLiveActivityActive ? .autoExpanded : .initial } } - } - - final class KeyWindow: NSWindow { - override var canBecomeKey: Bool { true } - override var canBecomeMain: Bool { true } - } - - private func openSettingsWindow() { - if let window = settingsWindow { - window.makeKeyAndOrderFront(nil) - NSApp.activate(ignoringOtherApps: true) - return - } - - let newWindow = KeyWindow( - contentRect: NSRect(x: 0, y: 0, width: 950, height: 650), - styleMask: [.borderless, .resizable, .closable], - backing: .buffered, - defer: false - ) - newWindow.center() - newWindow.isMovableByWindowBackground = false - newWindow.backgroundColor = .clear - newWindow.isOpaque = false - newWindow.hasShadow = true - newWindow.isReleasedWhenClosed = false - - let settingsView = SettingsView() - let hostingView = NSHostingView(rootView: settingsView - .environmentObject(settings) - .environment(\.window, newWindow)) - hostingView.autoresizingMask = [.width, .height] - newWindow.contentView = hostingView - - newWindow.makeKeyAndOrderFront(nil) - newWindow.makeFirstResponder(hostingView) - NSApp.activate(ignoringOtherApps: true) - - let delegate = SettingsWindowDelegate { - self.settingsWindow = nil - - } - newWindow.delegate = delegate - self.settingsWindow = newWindow - self.settingsDelegate = delegate - } - -} - -fileprivate struct SubtleIconButton: View { - let systemName: String - let action: () -> Void - @State private var isHovering = false - - var body: some View { - Button(action: action) { - Image(systemName: systemName) - .font(.system(size: 14, weight: .medium)) - .foregroundColor(.white.opacity(isHovering ? 1.0 : 0.7)) - .padding(12) - } - .buttonStyle(.plain) - .contentShape(Circle()) - .onHover { hovering in - withAnimation(.easeInOut(duration: 0.15)) { isHovering = hovering } - } - .scaleEffect(isHovering ? 1.1 : 1.0) - .animation(.spring(response: 0.4, dampingFraction: 0.6), value: isHovering) - } -} - - -fileprivate extension View { - func onSizeChange(of size: CGSize, perform action: @escaping (CGSize) -> Void) -> some View { - self.onAppear { action(size) } - .onChange(of: size) { newSize in action(newSize) } - } -} diff --git a/submissions/sapphire/Sapphire/Sapphire.entitlements b/submissions/sapphire/Sapphire/Sapphire.entitlements deleted file mode 100644 index 26a24f31..00000000 --- a/submissions/sapphire/Sapphire/Sapphire.entitlements +++ /dev/null @@ -1,16 +0,0 @@ - - - - - com.apple.security.automation.apple-events - - com.apple.security.cs.disable-library-validation - - com.apple.security.device.audio-input - - com.apple.security.personal-information.calendars - - com.apple.security.personal-information.location - - - diff --git a/submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift b/submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift deleted file mode 100644 index 05c0f497..00000000 --- a/submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift +++ /dev/null @@ -1,47 +0,0 @@ -// -// CalendarService.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-28. -// - -import Foundation -import EventKit - -class CalendarService: ObservableObject { - private let eventStore = EKEventStore() - - @Published var nextEvent: EKEvent? - - init() { - requestAccess() - } - - func requestAccess() { - eventStore.requestFullAccessToEvents { [weak self] (granted, error) in - if granted && error == nil { - DispatchQueue.main.async { - self?.fetchNextEvent() - - Timer.scheduledTimer(withTimeInterval: 60 * 5, repeats: true) { _ in - self?.fetchNextEvent() - } - } - } - } - } - - private func fetchNextEvent() { - let calendars = eventStore.calendars(for: .event) - let now = Date() - let oneDayFromNow = Date(timeIntervalSinceNow: 24 * 60 * 60) - - let predicate = eventStore.predicateForEvents(withStart: now, end: oneDayFromNow, calendars: calendars) - - let events = eventStore.events(matching: predicate).filter { !$0.isAllDay } - - DispatchQueue.main.async { - self.nextEvent = events.first - } - } -} diff --git a/submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift b/submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift deleted file mode 100644 index 60d2a4a2..00000000 --- a/submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// CalendarViewModel.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import Foundation -import SwiftUI - - -class InteractiveCalendarViewModel: ObservableObject { - @Published var dates: [Date] = [] - @Published var selectedDate: Date = Date() - let today: Date = Date() - - var selectedMonthAbbreviated: String { - selectedDate.format(as: "MMM") - } - - init() { - generateDates() - } - - private func generateDates() { - let calendar = Calendar.current - let today = Date() - let dateRange = -90...90 - - self.dates = dateRange.compactMap { dayOffset in - calendar.date(byAdding: .day, value: dayOffset, to: today) - } - } - - func selectDate(_ date: Date) { - self.selectedDate = date - } -} diff --git a/submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift b/submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift deleted file mode 100644 index d346a1aa..00000000 --- a/submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift +++ /dev/null @@ -1,137 +0,0 @@ -// -// GeminiAPI.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-06. -// - -import Foundation - - -struct GeminiAPI { - static func webSocketURL() -> URL? { - - let settings = SettingsModel() - let apiKey = settings.settings.geminiApiKey - - guard !apiKey.isEmpty else { - return nil - } - - let host = "preprod-generativelanguage.googleapis.com" - let urlString = "wss://\(host)/ws/google.ai.generativelanguage.v1alpha.GenerativeService.BidiGenerateContent?key=\(apiKey)" - return URL(string: urlString) - } - static let modelName = "models/gemini-2.0-flash-exp" -} - - - - - -enum GeminiWebSocketMessage { - - - - struct Setup: Encodable { - let setup: Payload - struct Payload: Encodable { - let model: String - } - } - - - - struct AudioInput: Encodable { - let realtimeInput: Payload - struct Payload: Encodable { - let mediaChunks: [MediaChunk] - } - struct MediaChunk: Encodable { - let mimeType: String - let data: String - } - } - - - - - struct ContentInput: Encodable { - let clientContent: Payload - - struct Payload: Encodable { - let turns: [Turn] - let turnComplete: Bool - } - - struct Turn: Encodable { - let role: String = "user" - let parts: [Part] - } - - struct Part: Encodable { - let text: String? - let inlineData: InlineData? - - - private enum CodingKeys: String, CodingKey { case text, inlineData } - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - if let text = text { - try container.encode(text, forKey: .text) - } else if let inlineData = inlineData { - try container.encode(inlineData, forKey: .inlineData) - } - } - - init(text: String) { self.text = text; self.inlineData = nil } - init(inlineData: InlineData) { self.text = nil; self.inlineData = inlineData } - } - - struct InlineData: Encodable { - let mimeType: String - let data: String - } - } -} - - - - -struct ServerSetupComplete: Decodable { - var setupComplete: EmptyObject - struct EmptyObject: Decodable {} -} - -struct ServerAudioOutput: Decodable { - var serverContent: ServerContent - struct ServerContent: Decodable { - var modelTurn: ModelTurn - struct ModelTurn: Decodable { - var parts: [Part] - struct Part: Decodable { - var inlineData: PartInlineData - struct PartInlineData: Decodable { var data: String } - } - } - } -} - -struct ServerInterrupted: Decodable { - var serverContent: ServerContent - struct ServerContent: Decodable { - var interrupted: Bool - } -} - -struct ServerTurnComplete: Decodable { - var serverContent: ServerContent - struct ServerContent: Decodable { - var turnComplete: Bool - } - var usageMetadata: UsageMetadata - struct UsageMetadata: Decodable { - var promptTokenCount: Int - var responseTokenCount: Int - } -} diff --git a/submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift b/submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift deleted file mode 100644 index ba7ae244..00000000 --- a/submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// GeminiLive.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import SwiftUI -import AppKit -import CoreGraphics - - - - -struct GeminiActiveActivityViewRight: View { - let isMuted: Bool - let action: () -> Void - - var body: some View { - Button(action: action) { - Image(systemName: isMuted ? "mic.slash.fill" : "mic.fill") - .font(.system(size: 14)) - .foregroundStyle(isMuted ? .white.opacity(0.7) : .red) - .contentTransition(.symbolEffect(.replace)) - } - .buttonStyle(.plain) - .foregroundStyle(.white.opacity(0.9)) - } -} - -struct GeminiActiveActivityView { - static func left() -> some View { - Image(systemName: "sparkle") - .font(.system(size: 18, weight: .semibold)) - .foregroundStyle(.purple) - } - - - static func right(isMuted: Bool, action: @escaping () -> Void) -> some View { - GeminiActiveActivityViewRight(isMuted: isMuted, action: action) - } -} diff --git a/submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift b/submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift deleted file mode 100644 index 51d7f8b9..00000000 --- a/submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift +++ /dev/null @@ -1,432 +0,0 @@ -// -// GeminiLiveManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import Foundation -import ScreenCaptureKit -import AVFoundation -import Combine -import CoreImage -import AppKit - -@MainActor -class GeminiLiveManager: NSObject, ObservableObject, SCStreamOutput, SCStreamDelegate { - - @Published var isSessionRunning = false - @Published var isMicMuted = true { - didSet { - } - } - - - private var webSocketTask: URLSessionWebSocketTask? - private let urlSession = URLSession(configuration: .default) - private var sessionTask: Task? - - - private let playbackEngine = AVAudioEngine() - private var captureEngine: AVAudioEngine? - private let audioPlayer = AVAudioPlayerNode() - private let geminiAudioFormat = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 24000, channels: 1, interleaved: false)! - private var playerAudioFormat: AVAudioFormat! - private var audioConverter_Playback: AVAudioConverter! - private let audioProcessingQueue = DispatchQueue(label: "com.sapphire.AudioProcessingQueue") - - - private var isSendingUserAudio = false - private let vadThreshold: Float = 0.01 - - - private var stream: SCStream? - private let videoFrameOutputQueue = DispatchQueue(label: "com.sapphire.VideoOutputQueue") - private let imageContext = CIContext() - - let sessionDidEndPublisher = PassthroughSubject() - - override init() { - super.init() - setupPlaybackEngine() - } - - func startSession(with filter: SCContentFilter) { - guard !isSessionRunning else { return } - isSessionRunning = true - isMicMuted = true - isSendingUserAudio = false - - guard let url = GeminiAPI.webSocketURL() else { - isSessionRunning = false - return - } - - webSocketTask = self.urlSession.webSocketTask(with: url) - - sessionTask = Task { - do { - if !self.playbackEngine.isRunning { - try self.playbackEngine.start() - if !self.audioPlayer.isPlaying { self.audioPlayer.play() } - } - - try self.startCaptureAudio() - - webSocketTask?.resume() - - try await Task.sleep(for: .milliseconds(100)) - - try await self.sendSetupMessage() - - try await withThrowingTaskGroup(of: Void.self) { group in - group.addTask { try await self.receiveMessages() } - group.addTask { try await self.captureAndSendScreen(with: filter) } - try await group.waitForAll() - } - - } catch { - if !(error is CancellationError) { - } - await self.cleanupSession() - } - } - } - - public func signalEndOfUserTurn() { - Task { - do { - - self.isMicMuted = true - self.isSendingUserAudio = false - - let finalPart = GeminiWebSocketMessage.ContentInput.Part(text: "That's all, please respond based on what you've seen and heard.") - let turn = GeminiWebSocketMessage.ContentInput.Turn(parts: [finalPart]) - let payload = GeminiWebSocketMessage.ContentInput.Payload(turns: [turn], turnComplete: true) - let message = GeminiWebSocketMessage.ContentInput(clientContent: payload) - try await send(message: message) - } catch { - } - } - } - - func stopSession() async { - sessionTask?.cancel() - await cleanupSession() - } - - private func cleanupSession() async { - if isSessionRunning { - isSessionRunning = false - webSocketTask?.cancel(with: .goingAway, reason: nil) - webSocketTask = nil - - if let stream = stream { try? await stream.stopCapture() } - stream = nil - - stopCaptureAudio() - - audioPlayer.stop() - audioPlayer.reset() - playbackEngine.stop() - playbackEngine.reset() - - sessionDidEndPublisher.send() - } - } - - - - private func send(message: T) async throws { - guard let webSocketTask = webSocketTask, webSocketTask.closeCode == .invalid else { - return - } - - let encoder = JSONEncoder() - let jsonData = try encoder.encode(message) - guard let jsonString = String(data: jsonData, encoding: .utf8) else { return } - - try await webSocketTask.send(.string(jsonString)) - } - - private func sendSetupMessage() async throws { - let payload = GeminiWebSocketMessage.Setup.Payload(model: GeminiAPI.modelName) - let message = GeminiWebSocketMessage.Setup(setup: payload) - try await send(message: message) - } - - private func sendContentPart(_ part: GeminiWebSocketMessage.ContentInput.Part) async throws { - let turn = GeminiWebSocketMessage.ContentInput.Turn(parts: [part]) - let payload = GeminiWebSocketMessage.ContentInput.Payload(turns: [turn], turnComplete: false) - let message = GeminiWebSocketMessage.ContentInput(clientContent: payload) - try await send(message: message) - } - - private func receiveMessages() async throws { - guard let webSocketTask = webSocketTask else { return } - - while !Task.isCancelled { - do { - let message = try await webSocketTask.receive() - switch message { - case .data(let data): - try self.handleReceivedJSONData(data) - case .string(let text): - try self.handleReceivedJSONData(Data(text.utf8)) - @unknown default: - fatalError("Received unknown WebSocket message type.") - } - } catch { - if !Task.isCancelled { - await cleanupSession() - } - break - } - } - } - - private func handleReceivedJSONData(_ data: Data) throws { - let decoder = JSONDecoder() - if (try? decoder.decode(ServerSetupComplete.self, from: data)) != nil { - Task { - let initialPart = GeminiWebSocketMessage.ContentInput.Part(text: "Please say 'Hi, what can I help you with?'") - let turn = GeminiWebSocketMessage.ContentInput.Turn(parts: [initialPart]) - let payload = GeminiWebSocketMessage.ContentInput.Payload(turns: [turn], turnComplete: true) - let message = GeminiWebSocketMessage.ContentInput(clientContent: payload) - try await self.send(message: message) - } - } else if let audioOutput = try? decoder.decode(ServerAudioOutput.self, from: data), - let audioDataB64 = audioOutput.serverContent.modelTurn.parts.first?.inlineData.data, - let audioData = Data(base64Encoded: audioDataB64) { - self.playAudioData(audioData) - - } else if let interruptedMessage = try? decoder.decode(ServerInterrupted.self, from: data), - interruptedMessage.serverContent.interrupted { - self.stopAndClearPlayback() - - } else if let turnComplete = try? decoder.decode(ServerTurnComplete.self, from: data) { - if turnComplete.serverContent.turnComplete { - - self.isMicMuted = false - self.isSendingUserAudio = false - } - } else { - let jsonString = String(data: data, encoding: .utf8) ?? "Undecodable binary" - } - } - - - - private func setupPlaybackEngine() { - playerAudioFormat = AVAudioFormat(standardFormatWithSampleRate: geminiAudioFormat.sampleRate, channels: geminiAudioFormat.channelCount)! - audioConverter_Playback = AVAudioConverter(from: geminiAudioFormat, to: playerAudioFormat)! - playbackEngine.attach(audioPlayer) - playbackEngine.connect(audioPlayer, to: playbackEngine.outputNode, format: playerAudioFormat) - playbackEngine.prepare() - } - - private func playAudioData(_ data: Data) { - guard let geminiBuffer = data.toPCMBuffer(format: geminiAudioFormat) else { return } - let playerBuffer = AVAudioPCMBuffer(pcmFormat: playerAudioFormat, frameCapacity: geminiBuffer.frameCapacity)! - isMicMuted = true - do { - try audioConverter_Playback.convert(to: playerBuffer, from: geminiBuffer) - if !playbackEngine.isRunning { try playbackEngine.start() } - if !audioPlayer.isPlaying { audioPlayer.play() } - audioPlayer.scheduleBuffer(playerBuffer) - } catch { print("[ERROR] Playback audio conversion error: \(error)") } - } - - private func stopAndClearPlayback() { - isMicMuted = false - audioPlayer.stop() - audioPlayer.reset() - } - - private func startCaptureAudio() throws { - captureEngine = AVAudioEngine() - - guard let captureEngine = captureEngine else { return } - - let inputNode = captureEngine.inputNode - - - - - - - - - - - - - let sourceFormat = inputNode.outputFormat(forBus: 0) - let targetFormat = AVAudioFormat(commonFormat: .pcmFormatInt16, sampleRate: 48000, channels: 1, interleaved: false)! - - guard let converter = AVAudioConverter(from: sourceFormat, to: targetFormat) else { - throw NSError(domain: "GeminiLiveManager", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to create audio converter"]) - } - - inputNode.installTap(onBus: 0, bufferSize: 1024, format: sourceFormat) { [weak self] inputBuffer, _ in - guard let self = self else { return } - self.audioProcessingQueue.async { - guard self.isSessionRunning, !self.isMicMuted else { return } - - - if self.isSendingUserAudio { - - self.convertAndSend(buffer: inputBuffer, using: converter) - } else { - - let level = self.calculateRMSAudioLevel(fromBuffer: inputBuffer) - if level > self.vadThreshold { - self.isSendingUserAudio = true - self.convertAndSend(buffer: inputBuffer, using: converter) - } - } - } - } - captureEngine.prepare() - try captureEngine.start() - } - - private func convertAndSend(buffer: AVAudioPCMBuffer, using converter: AVAudioConverter) { - let targetFormat = converter.outputFormat - let ratio = targetFormat.sampleRate / buffer.format.sampleRate - let outputFrameCount = AVAudioFrameCount(ceil(Double(buffer.frameLength) * ratio)) - - guard let outputBuffer = AVAudioPCMBuffer(pcmFormat: targetFormat, frameCapacity: outputFrameCount) else { - return - } - - var error: NSError? - var providedInput = false - - let inputBlock: AVAudioConverterInputBlock = { _, outStatus in - if providedInput { - outStatus.pointee = .noDataNow - return nil - } - outStatus.pointee = .haveData - providedInput = true - return buffer - } - - let status = converter.convert(to: outputBuffer, error: &error, withInputFrom: inputBlock) - - - if status == .error { - if let e = error { - } - return - } - - - guard let pcmData = outputBuffer.toData(), !pcmData.isEmpty else { return } - - let base64String = pcmData.base64EncodedString() - let chunk = GeminiWebSocketMessage.AudioInput.MediaChunk(mimeType: "audio/pcm;rate=16000", data: base64String) - let payload = GeminiWebSocketMessage.AudioInput.Payload(mediaChunks: [chunk]) - let message = GeminiWebSocketMessage.AudioInput(realtimeInput: payload) - - Task { - do { - try await self.send(message: message) - } catch { - } - } - } - - private func stopCaptureAudio() { - guard let captureEngine = captureEngine else { return } - captureEngine.stop() - captureEngine.inputNode.removeTap(onBus: 0) - self.captureEngine = nil - } - - - - private func captureAndSendScreen(with filter: SCContentFilter) async throws { - let config = SCStreamConfiguration() - config.width = 1024; config.height = 768 - config.minimumFrameInterval = CMTime(value: 1, timescale: 1) - config.queueDepth = 5 - stream = SCStream(filter: filter, configuration: config, delegate: self) - try stream?.addStreamOutput(self, type: .screen, sampleHandlerQueue: videoFrameOutputQueue) - try await stream?.startCapture() - } - - func stream(_ stream: SCStream, didOutputSampleBuffer sampleBuffer: CMSampleBuffer, of type: SCStreamOutputType) { - guard type == .screen, sampleBuffer.isValid, isSessionRunning else { return } - guard let pixelBuffer = sampleBuffer.imageBuffer else { return } - - let ciImage = CIImage(cvPixelBuffer: pixelBuffer) - guard let cgImage = imageContext.createCGImage(ciImage, from: ciImage.extent), - let jpegData = NSBitmapImageRep(cgImage: cgImage).representation(using: .jpeg, properties: [.compressionFactor: 0.7]) else { return } - - let base64String = jpegData.base64EncodedString() - let inlineData = GeminiWebSocketMessage.ContentInput.InlineData(mimeType: "image/jpeg", data: base64String) - let part = GeminiWebSocketMessage.ContentInput.Part(inlineData: inlineData) - - Task { - try? await self.sendContentPart(part) - } - } - - func stream(_ stream: SCStream, didStopWithError error: Error) { - Task { await cleanupSession() } - } - - - private func calculateRMSAudioLevel(fromBuffer buffer: AVAudioPCMBuffer) -> Float { - guard let floatChannelData = buffer.floatChannelData else { - - - return 0.0 - } - - let channelCount = Int(buffer.format.channelCount) - let frameLength = Int(buffer.frameLength) - - var rms: Float = 0.0 - for channel in 0.. AVAudioPCMBuffer? { - let frameCapacity = UInt32(self.count) / format.streamDescription.pointee.mBytesPerFrame - guard frameCapacity > 0, let buffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: frameCapacity) else { return nil } - buffer.frameLength = frameCapacity - self.withUnsafeBytes { srcBuffer in - if let baseAddress = srcBuffer.baseAddress, let dest = buffer.int16ChannelData?[0] { - memcpy(dest, baseAddress, self.count) - } - } - return buffer - } -} - -fileprivate extension AVAudioPCMBuffer { - func toData() -> Data? { - - let frameLength = Int(self.frameLength) - let channelCount = Int(self.format.channelCount) - let bytesPerFrame = Int(self.format.streamDescription.pointee.mBytesPerFrame) - let dataSize = frameLength * bytesPerFrame - - guard dataSize > 0, channelCount == 1, let channelData = self.int16ChannelData else { return nil } - - return Data(bytes: channelData[0], count: dataSize) - } -} diff --git a/submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift b/submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift deleted file mode 100644 index 5e55b5cb..00000000 --- a/submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift +++ /dev/null @@ -1,149 +0,0 @@ -// -// LyricsFetcher.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import Foundation - -class LyricsFetcher { - - - func fetchSyncedLyrics(for title: String, artist: String, album: String) async -> [LyricLine]? { - - var components = URLComponents(string: "https://lrclib.net/api/get")! - components.queryItems = [ - URLQueryItem(name: "track_name", value: title), - URLQueryItem(name: "artist_name", value: artist), - URLQueryItem(name: "album_name", value: album) - ] - - guard let url = components.url else { return nil } - - do { - let (data, _) = try await URLSession.shared.data(from: url) - - struct LrcLibResponse: Decodable { - let syncedLyrics: String? - } - - let response = try JSONDecoder().decode(LrcLibResponse.self, from: data) - - if let lrcString = response.syncedLyrics, !lrcString.isEmpty { - return parseLRC(lrcString) - } else { - return nil - } - } catch { - return nil - } - } - - private func parseLRC(_ lrcString: String) -> [LyricLine] { - var lyrics: [LyricLine] = [] - let lines = lrcString.components(separatedBy: .newlines) - - for line in lines { - if line.hasPrefix("[") && line.contains("]") { - let components = line.components(separatedBy: "]") - if components.count > 1 { - let timestampString = String(components[0].dropFirst()) - let text = components[1].trimmingCharacters(in: .whitespaces) - - let timeComponents = timestampString.components(separatedBy: ":") - if timeComponents.count == 2, - let minutes = Double(timeComponents[0]), - let seconds = Double(timeComponents[1]) { - - let timestamp = (minutes * 60) + seconds - lyrics.append(LyricLine(text: text, timestamp: timestamp)) - } - } - } - } - return lyrics.sorted { $0.timestamp < $1.timestamp } - } - - - func detectLanguage(for text: String) async -> String? { - - let trimmedText = text.trimmingCharacters(in: .whitespacesAndNewlines) - guard !trimmedText.isEmpty else { - return nil - } - - var components = URLComponents(string: "https://translate.googleapis.com/translate_a/single")! - components.queryItems = [ - URLQueryItem(name: "client", value: "gtx"), - URLQueryItem(name: "sl", value: "auto"), - URLQueryItem(name: "tl", value: "en"), - URLQueryItem(name: "dt", value: "t"), - URLQueryItem(name: "q", value: trimmedText.prefix(500).description) - ] - - guard let url = components.url else { return nil } - - struct UnofficialGoogleDetectionResponse: Decodable { - let detectedLanguage: String? - init(from decoder: Decoder) throws { - var container = try decoder.unkeyedContainer() - _ = try? container.nestedUnkeyedContainer() - _ = try? container.decode(String?.self) - self.detectedLanguage = try? container.decode(String.self) - } - } - - do { - let (data, _) = try await URLSession.shared.data(from: url) - let unofficialResponse = try JSONDecoder().decode(UnofficialGoogleDetectionResponse.self, from: data) - if let lang = unofficialResponse.detectedLanguage { - return lang - } - } catch { - } - return nil - } - - - func translate(lyrics: inout [LyricLine], from sourceLanguage: String, to targetLanguage: String) async { - - struct UnofficialGoogleTranslateResponse: Decodable { - let translatedText: String? - init(from decoder: Decoder) throws { - var container = try decoder.unkeyedContainer() - if var outerArray = try? container.nestedUnkeyedContainer(), - var firstInnerArray = try? outerArray.nestedUnkeyedContainer() { - self.translatedText = try? firstInnerArray.decode(String.self) - } else { - self.translatedText = nil - } - } - } - - for i in 0..() - - - @Published var title: String? - @Published var artist: String? - @Published var album: String? - @Published var artwork: NSImage? - @Published var isPlaying: Bool = false - @Published var playbackProgress: Double = 0.0 - @Published var currentElapsedTime: TimeInterval = 0 - @Published var totalDuration: TimeInterval = 0 - @Published var lyrics: [LyricLine] = [] - @Published var currentLyric: LyricLine? - @Published var accentColor: Color = .white - @Published var leftGradientColor: Color = .white - @Published var rightGradientColor: Color = .white - @Published var appIcon: NSImage? - @Published var systemVolume: Float = 0.0 - @Published var isDisplayingTransientIcon: Bool = false - @Published var shouldShowLiveActivity: Bool = false - - - @Published var lyricsTapped: Bool = false - - - private var volumeListener: AudioObjectPropertyListenerBlock? - private var currentTrackDuration: TimeInterval = 0 - private var lastFetchedTitle: String? - private var lastKnownBundleID: String? - private var cancellables = Set() - private var justSkipped = false - private var skipDebounceTimer: Timer? - - init() { - setupHandlers() - setupNotificationObservers() - setupVolumeListener() - setupDerivedStatePublisher() - mediaController.startListening() - } - - deinit { - mediaController.stop() - removeVolumeListener() - NotificationCenter.default.removeObserver(self) - skipDebounceTimer?.invalidate() - } - - private func setupDerivedStatePublisher() { - Publishers.CombineLatest($isPlaying, $isDisplayingTransientIcon) - .map { isPlaying, isDisplayingIcon in return isPlaying || isDisplayingIcon } - .removeDuplicates().assign(to: \.shouldShowLiveActivity, on: self).store(in: &cancellables) - } - - private func setupNotificationObservers() { - NotificationCenter.default.addObserver(self, selector: #selector(handlePlayPause), name: .mediaKeyPlayPausePressed, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(handleNextTrack), name: .mediaKeyNextPressed, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(handlePreviousTrack), name: .mediaKeyPreviousPressed, object: nil) - } - - private func setupHandlers() { - mediaController.onTrackInfoReceived = { [weak self] trackInfo in - guard let self = self else { return } - let payload = trackInfo.payload - DispatchQueue.main.async { - let hasTrackChanged = payload.title != self.lastFetchedTitle - self.title = payload.title; self.artist = payload.artist; self.album = payload.album - if let newArtwork = payload.artwork { - self.artwork = newArtwork - if let edgeColors = newArtwork.getEdgeColors() { self.accentColor = edgeColors.accent; self.leftGradientColor = edgeColors.left; self.rightGradientColor = edgeColors.right } - else { self.resetColorsToDefault() } - } else { self.artwork = nil; self.resetColorsToDefault() } - if let newIsPlaying = payload.isPlaying { - if self.isPlaying && !newIsPlaying { self.playerActionPublisher.send(.paused) } - else if !self.isPlaying && newIsPlaying { self.playerActionPublisher.send(.played) } - self.isPlaying = newIsPlaying - } - self.currentTrackDuration = TimeInterval(payload.durationMicros ?? 0) / 1_000_000 - self.totalDuration = self.currentTrackDuration - if hasTrackChanged { - self.lastFetchedTitle = payload.title - self.fetchAndTranslateLyricsIfNeeded() - if !self.justSkipped { self.playerActionPublisher.send(.trackChanged) } - } - if payload.bundleIdentifier != self.lastKnownBundleID { - self.lastKnownBundleID = payload.bundleIdentifier - self.fetchAppIcon(for: payload.bundleIdentifier) - } - } - } - mediaController.onPlaybackTimeUpdate = { [weak self] elapsedTime in - guard let self = self, self.currentTrackDuration > 0 else { return } - DispatchQueue.main.async { - self.playbackProgress = max(0.0, min(1.0, elapsedTime / self.currentTrackDuration)) - self.currentElapsedTime = elapsedTime - self.updateCurrentLyric(for: elapsedTime) - } - } - mediaController.onListenerTerminated = { print("[MusicWidget] Error: The media listener process was terminated.") } - mediaController.onDecodingError = { error, data in print("[MusicWidget] Decoding Error: \(error)") } - } - - private func setupVolumeListener() { - self.systemVolume = SystemControl.getVolume() - guard let deviceID = getDefaultOutputDeviceID() else { return } - var address = AudioObjectPropertyAddress(mSelector: kAudioDevicePropertyVolumeScalar, mScope: kAudioObjectPropertyScopeOutput, mElement: kAudioObjectPropertyElementMain) - self.volumeListener = { [weak self] _, _ in DispatchQueue.main.async { self?.systemVolume = SystemControl.getVolume() } } - AudioObjectAddPropertyListenerBlock(deviceID, &address, nil, self.volumeListener!) - } - - private func removeVolumeListener() { - guard let deviceID = getDefaultOutputDeviceID(), let listener = self.volumeListener else { return } - var address = AudioObjectPropertyAddress(mSelector: kAudioDevicePropertyVolumeScalar, mScope: kAudioObjectPropertyScopeOutput, mElement: kAudioObjectPropertyElementMain) - AudioObjectRemovePropertyListenerBlock(deviceID, &address, nil, listener) - } - - private func getDefaultOutputDeviceID() -> AudioDeviceID? { - var deviceID: AudioDeviceID = kAudioObjectUnknown, size = UInt32(MemoryLayout.size) - var address = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDefaultOutputDevice, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMain) - return AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &address, 0, nil, &size, &deviceID) == noErr ? deviceID : nil - } - - private func fetchAppIcon(for bundleIdentifier: String?) { - guard let bundleId = bundleIdentifier, !bundleId.isEmpty, let url = NSWorkspace.shared.urlForApplication(withBundleIdentifier: bundleId) else { DispatchQueue.main.async { self.appIcon = nil }; return } - DispatchQueue.main.async { self.appIcon = NSWorkspace.shared.icon(forFile: url.path) } - } - - private func fetchAndTranslateLyricsIfNeeded() { - guard let title = self.title, let artist = self.artist, let album = self.album else { return } - self.lyrics = []; self.currentLyric = nil - Task { - guard var fetchedLyrics = await lyricsFetcher.fetchSyncedLyrics(for: title, artist: artist, album: album), !fetchedLyrics.isEmpty else { return } - await MainActor.run { self.lyrics = fetchedLyrics } - let sampleText = fetchedLyrics.prefix(5).map { $0.text }.joined(separator: " ") - guard !sampleText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty, let lang = await lyricsFetcher.detectLanguage(for: sampleText) else { return } - if lang != "en" { await lyricsFetcher.translate(lyrics: &fetchedLyrics, from: lang, to: "en"); await MainActor.run { self.lyrics = fetchedLyrics } } - } - } - - private func updateCurrentLyric(for elapsedTime: TimeInterval) { - let newLyric = lyrics.last { $0.timestamp <= elapsedTime } - if newLyric?.id != self.currentLyric?.id { self.currentLyric = newLyric } - } - - private func resetColorsToDefault() { - let defaultAccent = Color(red: 0.53, green: 0.73, blue: 0.88) - self.accentColor = defaultAccent; self.leftGradientColor = defaultAccent; self.rightGradientColor = defaultAccent.opacity(0.7) - } - - private func handleSkipAction(isForward: Bool) { - justSkipped = true - skipDebounceTimer?.invalidate() - skipDebounceTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { [weak self] _ in self?.justSkipped = false } - if isForward { mediaController.nextTrack() } - else { mediaController.previousTrack() } - } - - - func play() { mediaController.play(); playerActionPublisher.send(.played) } - func pause() { mediaController.pause(); playerActionPublisher.send(.paused) } - func nextTrack() { handleSkipAction(isForward: true) } - func previousTrack() { handleSkipAction(isForward: false) } - func seek(to seconds: Double) { mediaController.setTime(seconds: seconds) } - - - @objc private func handlePlayPause() { isPlaying ? pause() : play() } - @objc private func handleNextTrack() { nextTrack() } - @objc private func handlePreviousTrack() { previousTrack() } -} diff --git a/submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift b/submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift deleted file mode 100644 index 39c5db7e..00000000 --- a/submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift +++ /dev/null @@ -1,137 +0,0 @@ -// -// SystemAudioMonitor.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-01. -// - -import Foundation -import AVFoundation -import Combine -import CoreAudio -import Accelerate - -class SystemAudioMonitor: ObservableObject { - @Published var audioLevel: Float = 0.0 - - private let engine = AVAudioEngine() - private var isMonitoring = false - - init() {} - - func start() { - guard !isMonitoring else { return } - setupAndStartEngine() - } - - func stop() { - guard isMonitoring else { return } - engine.inputNode.removeTap(onBus: 0) - engine.stop() - isMonitoring = false - } - - private func setupAndStartEngine() { - let inputNode = engine.inputNode - - guard let blackHoleDeviceID = findBlackHoleDeviceID() else { - return - } - - do { - var deviceID = blackHoleDeviceID - guard let audioUnit = inputNode.audioUnit else { - print("[SystemAudioMonitor] ❌ Could not get AudioUnit for input node."); return - } - let error = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &deviceID, UInt32(MemoryLayout.size)) - if error != noErr { - print("[SystemAudioMonitor] ❌ Failed to set input device. Error: \(error)"); return - } - try engine.start() - } catch { - print("[SystemAudioMonitor] ❌ Failed to start audio engine: \(error.localizedDescription)"); return - } - - inputNode.installTap(onBus: 0, bufferSize: 1024, format: inputNode.outputFormat(forBus: 0)) { [weak self] buffer, _ in - let level = self?.calculateRMS(from: buffer) ?? 0.0 - DispatchQueue.main.async { self?.audioLevel = level } - } - - isMonitoring = true - } - - private func findBlackHoleDeviceID() -> AudioDeviceID? { - var deviceID: AudioDeviceID = 0 - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioHardwarePropertyDefaultInputDevice, - mScope: kAudioObjectPropertyScopeGlobal, - mElement: kAudioObjectPropertyElementMain - ) - var propertySize = UInt32(MemoryLayout.size) - - let status = AudioObjectGetPropertyData( - AudioObjectID(kAudioObjectSystemObject), - &propertyAddress, - 0, - nil, - &propertySize, - &deviceID - ) - - if status == noErr, let deviceName = getDeviceName(deviceID), deviceName.contains("BlackHole") { - return deviceID - } - - - var devicesPropertyAddress = AudioObjectPropertyAddress(mSelector: kAudioHardwarePropertyDevices, mScope: kAudioObjectPropertyScopeGlobal, mElement: kAudioObjectPropertyElementMain) - var devicesPropertySize: UInt32 = 0 - guard AudioObjectGetPropertyDataSize(AudioObjectID(kAudioObjectSystemObject), &devicesPropertyAddress, 0, nil, &devicesPropertySize) == noErr else { return nil } - - let deviceCount = Int(devicesPropertySize) / MemoryLayout.size - var deviceIDs = [AudioDeviceID](repeating: 0, count: deviceCount) - guard AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &devicesPropertyAddress, 0, nil, &devicesPropertySize, &deviceIDs) == noErr else { return nil } - - for id in deviceIDs { - if let name = getDeviceName(id), name.contains("BlackHole") { - return id - } - } - - return nil - } - - private func getDeviceName(_ deviceID: AudioDeviceID) -> String? { - var name: CFString = "" as CFString - var propertySize = UInt32(MemoryLayout.size) - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioDevicePropertyDeviceNameCFString, - mScope: kAudioObjectPropertyScopeGlobal, - mElement: kAudioObjectPropertyElementMain - ) - guard AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &name) == noErr else { return nil } - return name as String - } - - - private func calculateRMS(from buffer: AVAudioPCMBuffer) -> Float { - guard let channelData = buffer.floatChannelData else { return 0 } - let frameLength = Int(buffer.frameLength) - guard frameLength > 0 else { return 0 } - - let channelCount = Int(buffer.format.channelCount) - var rms: Float = 0.0 - - for channel in 0.. some View { - let lowHeight = minHeight + (maxHeight - minHeight) * low - let highHeight = minHeight + (maxHeight - minHeight) * high - - return Capsule() - .fill(musicWidget.accentColor) - .shadow(color: musicWidget.accentColor.opacity(0.6), radius: 4, y: 2) - .frame(height: drawingHeight ? highHeight : lowHeight) - // Align to center for symmetrical expansion - .frame(height: maxHeight, alignment: .center) - } - - private var staticWaveformBody: some View { - HStack(spacing: 3) { - ForEach(0.. some View { - Image(systemName: systemName) - .font(.system(size: 16, weight: .semibold)) - .foregroundColor(musicWidget.accentColor) - .transition(.opacity.animation(.easeOut(duration: 0.2))) - } -} diff --git a/submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift b/submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift deleted file mode 100644 index 22033121..00000000 --- a/submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift +++ /dev/null @@ -1,338 +0,0 @@ -// -// SpotifyAPIManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import Foundation -import Combine -import AppKit - - -enum PlaybackResult { - case success - case failure(reason: String) - case requiresPremium - case requiresSpotifyAppOpen -} - -class SpotifyAPIManager: ObservableObject { - static let shared = SpotifyAPIManager() - - - private var clientId = "79b4d096a6f8415f8c7fc678647f4482" - private var clientSecret = "fe9a27b5e3324a949d94f67ecc86d791" - private let redirectURI = "sapphire://callback" - - @Published var isAuthenticated = false - @Published var userProfile: UserProfile? - @Published var isPremiumUser = false - - private var accessToken: String? - private var refreshToken: String? - - private let settingsModel = SettingsModel() - - private init() { - clientId = settingsModel.settings.spotifyClientId - clientSecret = settingsModel.settings.spotifyClientSecret - } - - - - func login() { - - let scope = "user-read-playback-state user-modify-playback-state user-read-currently-playing playlist-read-private user-read-private" - - var components = URLComponents(string: "https://accounts.spotify.com/authorize")! - components.queryItems = [ - URLQueryItem(name: "response_type", value: "code"), - URLQueryItem(name: "client_id", value: clientId), - URLQueryItem(name: "scope", value: scope), - URLQueryItem(name: "redirect_uri", value: redirectURI), - ] - guard let url = components.url else { return } - NSWorkspace.shared.open(url) - } - - func handleRedirect(url: URL) { - guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true), - let code = components.queryItems?.first(where: { $0.name == "code" })?.value else { - return - } - Task { await self.exchangeCodeForToken(code: code) } - } - - private struct TokenResponse: Decodable { - let accessToken: String, refreshToken: String?, expiresIn: Int - enum CodingKeys: String, CodingKey { case accessToken = "access_token", refreshToken = "refresh_token", expiresIn = "expires_in" } - } - - private func exchangeCodeForToken(code: String) async { - guard let url = URL(string: "https://accounts.spotify.com/api/token") else { return } - var request = URLRequest(url: url) - request.httpMethod = "POST" - var components = URLComponents() - components.queryItems = [ - URLQueryItem(name: "grant_type", value: "authorization_code"), - URLQueryItem(name: "code", value: code), - URLQueryItem(name: "redirect_uri", value: redirectURI), - ] - request.httpBody = components.query?.data(using: .utf8) - let authHeader = "\(clientId):\(clientSecret)".data(using: .utf8)!.base64EncodedString() - request.setValue("Basic \(authHeader)", forHTTPHeaderField: "Authorization") - request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") - - do { - let (data, _) = try await URLSession.shared.data(for: request) - let tokenResponse = try JSONDecoder().decode(TokenResponse.self, from: data) - await MainActor.run { - self.accessToken = tokenResponse.accessToken - self.refreshToken = tokenResponse.refreshToken - self.isAuthenticated = true - Task { await self.fetchUserProfile() } - } - } catch { print("--> TOKEN ERROR: \(error)") } - } - - - private func makeAPIRequest(url: URL, method: String = "GET", body: Data? = nil) async -> T? { - guard isAuthenticated, let token = accessToken else { - return nil - } - - - #if DEBUG - if url.path.contains("audio-analysis") { - } - #endif - - var request = URLRequest(url: url) - request.httpMethod = method - request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization") - if let body = body { request.httpBody = body; request.addValue("application/json", forHTTPHeaderField: "Content-Type") } - - do { - let (data, response) = try await URLSession.shared.data(for: request) - - guard let httpResponse = response as? HTTPURLResponse else { - return nil - } - - if (200...299).contains(httpResponse.statusCode) && url.path.contains("audio-analysis") { - } else if let jsonString = String(data: data, encoding: .utf8), !jsonString.isEmpty { - } - - guard (200...299).contains(httpResponse.statusCode) else { - if httpResponse.statusCode == 403 && url.path.contains("audio-analysis") { - } else { - let errorBody = String(data: data, encoding: .utf8) ?? "No error body" - } - return nil - } - - if data.isEmpty, T.self == Bool.self { return true as? T } - return try JSONDecoder().decode(T.self, from: data) - } catch { - return nil - } - } - - - private func isSpotifyAppRunning() -> Bool { - return NSWorkspace.shared.runningApplications.contains { $0.bundleIdentifier == "com.spotify.client" } - } - - private func runAppleScript(_ script: String) -> Bool { - guard isSpotifyAppRunning() else { return false } - var error: NSDictionary? - if let scriptObject = NSAppleScript(source: script) { - scriptObject.executeAndReturnError(&error) - if let err = error { print("--> AppleScript Error: \(err)"); return false } - return true - } - return false - } - - func getLocalVolume() -> Int? { - guard isSpotifyAppRunning() else { return nil } - let script = "if application \"Spotify\" is running then tell application \"Spotify\" to get sound volume" - var error: NSDictionary? - if let scriptObject = NSAppleScript(source: script) { - let result = scriptObject.executeAndReturnError(&error) - if error == nil, let volume = result.int32Value as? Int { - return volume - } - } - return nil - } - - - - private struct PlayBody: Encodable { var context_uri: String? = nil; var uris: [String]? = nil } - private struct TransferPlaybackBody: Encodable { let device_ids: [String]; let play: Bool } - - func fetchUserProfile() async { - guard isAuthenticated, let url = URL(string: "https://api.spotify.com/v1/me") else { return } - let profile: UserProfile? = await makeAPIRequest(url: url) - await MainActor.run { - self.userProfile = profile - self.isPremiumUser = (profile?.product == "premium") - } - } - - func playTrack(uri: String) async -> PlaybackResult { - if isPremiumUser { - guard let url = URL(string: "https://api.spotify.com/v1/me/player/play") else { return .failure(reason: "Invalid URL") } - let body = PlayBody(uris: [uri]) - guard let bodyData = try? JSONEncoder().encode(body) else { return .failure(reason: "Encoding failed") } - let success: Bool? = await makeAPIRequest(url: url, method: "PUT", body: bodyData) - return success == true ? .success : .failure(reason: "API request failed") - } else { - if isSpotifyAppRunning() { - guard let url = URL(string: uri) else { return .failure(reason: "Invalid URI") } - await MainActor.run { NSWorkspace.shared.open(url) } - return .success - } else { return .requiresSpotifyAppOpen } - } - } - - private func getLocalCurrentTrack() -> SpotifyTrack? { - guard isSpotifyAppRunning() else { return nil } - - let script = """ - if application "Spotify" is running then - tell application "Spotify" - if player state is playing or player state is paused then - return (get name of current track) & "|" & (get artist of current track) & "|" & (get album of current track) & "|" & (get spotify url of current track) & "|" & (get id of current track) - else - return "" - end if - end tell - end if - return "" - """ - var error: NSDictionary? - if let scriptObject = NSAppleScript(source: script) { - let result = scriptObject.executeAndReturnError(&error) - if error == nil, let resultString = result.stringValue, !resultString.isEmpty { - let parts = resultString.components(separatedBy: "|") - if parts.count == 5 { - - let mockAlbum = SpotifyAlbum(images: []) - return SpotifyTrack( - id: parts[4], - name: parts[0], - uri: parts[3], - album: mockAlbum, - artists: [SpotifyArtist(name: parts[1])] - ) - } - } - } - return nil - } - - - func playPlaylist(contextUri: String) async -> PlaybackResult { - if isPremiumUser { - guard let url = URL(string: "https://api.spotify.com/v1/me/player/play") else { return .failure(reason: "Invalid URL") } - let body = PlayBody(context_uri: contextUri) - guard let bodyData = try? JSONEncoder().encode(body) else { return .failure(reason: "Encoding failed") } - let success: Bool? = await makeAPIRequest(url: url, method: "PUT", body: bodyData) - return success == true ? .success : .failure(reason: "API request failed") - } else { - if isSpotifyAppRunning() { - guard let url = URL(string: contextUri) else { return .failure(reason: "Invalid URI") } - await MainActor.run { NSWorkspace.shared.open(url) } - return .success - } else { return .requiresSpotifyAppOpen } - } - } - - func setVolume(percent: Int) async -> PlaybackResult { - if isPremiumUser { - guard var components = URLComponents(string: "https://api.spotify.com/v1/me/player/volume") else { return .failure(reason: "Invalid URL") } - components.queryItems = [URLQueryItem(name: "volume_percent", value: "\(percent)")] - guard let url = components.url else { return .failure(reason: "Invalid URL") } - let success: Bool? = await makeAPIRequest(url: url, method: "PUT") - return success == true ? .success : .failure(reason: "API request failed") - } else { - if isSpotifyAppRunning() { - let script = "tell application \"Spotify\" to set sound volume to \(percent)" - let success = runAppleScript(script) - return success ? .success : .failure(reason: "AppleScript failed") - } else { return .requiresSpotifyAppOpen } - } - } - - func transferPlayback(to deviceId: String) async -> PlaybackResult { - guard isPremiumUser else { return .requiresPremium } - guard let url = URL(string: "https://api.spotify.com/v1/me/player") else { return .failure(reason: "Invalid URL") } - let body = TransferPlaybackBody(device_ids: [deviceId], play: true) - guard let bodyData = try? JSONEncoder().encode(body) else { return .failure(reason: "Encoding failed") } - let success: Bool? = await makeAPIRequest(url: url, method: "PUT", body: bodyData) - return success == true ? .success : .failure(reason: "API request failed") - } - - func fetchQueue() async -> SpotifyQueue? { - - guard isPremiumUser else { - return nil - } - - guard let url = URL(string: "https://api.spotify.com/v1/me/player/queue") else { return nil } - - - let queue: SpotifyQueue? = await makeAPIRequest(url: url) - - if queue == nil { - } else { - } - return queue - } - - - func fetchPlaylists() async -> [SpotifyPlaylist] { - guard isAuthenticated, let url = URL(string: "https://api.spotify.com/v1/me/playlists") else { return [] } - struct PlaylistResponse: Decodable { let items: [SpotifyPlaylist] } - let response: PlaylistResponse? = await makeAPIRequest(url: url) - return response?.items ?? [] - } - - func fetchDevices() async -> [SpotifyDevice] { - guard isPremiumUser, let url = URL(string: "https://api.spotify.com/v1/me/player/devices") else { return [] } - struct DevicesResponse: Decodable { let devices: [SpotifyDevice] } - let response: DevicesResponse? = await makeAPIRequest(url: url) - return response?.devices ?? [] - } - - func fetchPlaybackState() async -> PlaybackState? { - guard isPremiumUser, let url = URL(string: "https://api.spotify.com/v1/me/player") else { return nil } - return await makeAPIRequest(url: url) - } - - func fetchAudioAnalysis(for trackId: String) async -> AudioAnalysis? { - guard isAuthenticated, let url = URL(string: "https://api.spotify.com/v1/audio-analysis/\(trackId)") else { - return nil - } - return await makeAPIRequest(url: url) - } - - func searchForTrack(title: String, artist: String) async -> SpotifyTrack? { - guard isAuthenticated else { return nil } - var components = URLComponents(string: "https://api.spotify.com/v1/search")! - - let query = "track:\"\(title.trimmingCharacters(in: .whitespacesAndNewlines))\" artist:\"\(artist.trimmingCharacters(in: .whitespacesAndNewlines))\"" - components.queryItems = [ - URLQueryItem(name: "q", value: query), - URLQueryItem(name: "type", value: "track"), - URLQueryItem(name: "limit", value: "1") - ] - guard let url = components.url else { return nil } - - let response: SearchResponse? = await makeAPIRequest(url: url) - return response?.tracks.items.first - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift b/submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift deleted file mode 100644 index d9c983b0..00000000 --- a/submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift +++ /dev/null @@ -1,85 +0,0 @@ -// -// ActiveAppMonitor.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-09. -// - -import AppKit -import Combine - -@MainActor -class ActiveAppMonitor: ObservableObject { - - static let shared = ActiveAppMonitor() - - @Published private(set) var isLyricsAllowedForActiveApp: Bool = true - - private var activeAppBundleID: String? - private let settingsModel: SettingsModel - private var cancellables = Set() - - private init() { - self.settingsModel = SettingsModel() - - NSWorkspace.shared.notificationCenter - .publisher(for: NSWorkspace.didActivateApplicationNotification) - .compactMap { ($0.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication)?.bundleIdentifier } - .removeDuplicates() - .receive(on: DispatchQueue.main) - .sink { [weak self] bundleID in - self?.activeAppBundleID = bundleID - self?.updateLyricPermission() - } - .store(in: &cancellables) - - settingsModel.objectWillChange - .receive(on: DispatchQueue.main) - .sink { [weak self] _ in - self?.updateLyricPermission() - } - .store(in: &cancellables) - - if let initialApp = NSWorkspace.shared.frontmostApplication { - self.activeAppBundleID = initialApp.bundleIdentifier - self.updateLyricPermission() - } - } - - private func updateLyricPermission() { - var newPermissionState = true - - - - - guard settingsModel.settings.showLyricsInLiveActivity else { - newPermissionState = false - if isLyricsAllowedForActiveApp != newPermissionState { isLyricsAllowedForActiveApp = newPermissionState } - return - } - - guard let activeBundleID = activeAppBundleID else { - newPermissionState = true - if isLyricsAllowedForActiveApp != newPermissionState { isLyricsAllowedForActiveApp = newPermissionState } - return - } - - if let isAllowed = settingsModel.settings.musicAppStates[activeBundleID] { - newPermissionState = isAllowed - if isLyricsAllowedForActiveApp != newPermissionState { isLyricsAllowedForActiveApp = newPermissionState } - return - } - - if let appURL = NSWorkspace.shared.urlForApplication(withBundleIdentifier: activeBundleID), - let bundle = Bundle(url: appURL), - let urlTypes = bundle.infoDictionary?["CFBundleURLTypes"] as? [[String: Any]] { - - let isBrowser = urlTypes.contains { ($0["CFBundleURLSchemes"] as? [String])?.contains("http") ?? false } - newPermissionState = !isBrowser - } - - if isLyricsAllowedForActiveApp != newPermissionState { - isLyricsAllowedForActiveApp = newPermissionState - } - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift b/submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift deleted file mode 100644 index 20a8fd60..00000000 --- a/submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift +++ /dev/null @@ -1,124 +0,0 @@ -// -// AudioDeviceManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-08. -// - -import Foundation -import Combine -import AudioToolbox - - -struct AudioSwitchEvent: Hashable { - enum Direction: Hashable { - case switchedToMac - case switchedAwayFromMac - } - - let id = UUID() - let deviceName: String - let direction: Direction -} - - -class AudioDeviceManager: ObservableObject { - @Published var lastSwitchEvent: AudioSwitchEvent? - - private var previousDeviceName: String? - - init() { - - DispatchQueue.main.async { - self.setupAudioListener() - - self.previousDeviceName = self.getCurrentDeviceName() - } - } - - private func setupAudioListener() { - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioHardwarePropertyDefaultOutputDevice, - mScope: kAudioObjectPropertyScopeGlobal, - mElement: kAudioObjectPropertyElementMain - ) - - - let propertyListener: AudioObjectPropertyListenerBlock = { [weak self] _, _ in - DispatchQueue.main.async { - self?.handleDeviceChange() - } - } - - let status = AudioObjectAddPropertyListenerBlock( - AudioObjectID(kAudioObjectSystemObject), - &propertyAddress, - nil, - propertyListener - ) - - if status != noErr { - } - } - - private func handleDeviceChange() { - let newDeviceName = getCurrentDeviceName() - - - guard newDeviceName != previousDeviceName else { return } - - - let didSwitchAway = isAutoSwitchDevice(name: previousDeviceName) && !isAutoSwitchDevice(name: newDeviceName) - let didSwitchTo = !isAutoSwitchDevice(name: previousDeviceName) && isAutoSwitchDevice(name: newDeviceName) - - if didSwitchAway, let name = previousDeviceName { - lastSwitchEvent = AudioSwitchEvent(deviceName: name, direction: .switchedAwayFromMac) - } else if didSwitchTo, let name = newDeviceName { - lastSwitchEvent = AudioSwitchEvent(deviceName: name, direction: .switchedToMac) - } - - - self.previousDeviceName = newDeviceName - } - - - - - private func isAutoSwitchDevice(name: String?) -> Bool { - guard let lowercasedName = name?.lowercased() else { return false } - let keywords = ["airpods", "beats", "powerbeats"] - return keywords.contains { lowercasedName.contains($0) } - } - - private func getCurrentDeviceName() -> String? { - var deviceID: AudioDeviceID = kAudioObjectUnknown - var propertySize = UInt32(MemoryLayout.size) - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioHardwarePropertyDefaultOutputDevice, - mScope: kAudioObjectPropertyScopeGlobal, - mElement: kAudioObjectPropertyElementMain - ) - - guard AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &propertyAddress, 0, nil, &propertySize, &deviceID) == noErr else { - return nil - } - - return getDeviceName(for: deviceID) - } - - private func getDeviceName(for deviceID: AudioDeviceID) -> String? { - var name: CFString = "" as CFString - var propertySize = UInt32(MemoryLayout.size) - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioDevicePropertyDeviceNameCFString, - mScope: kAudioObjectPropertyScopeGlobal, - mElement: kAudioObjectPropertyElementMain - ) - - guard AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &name) == noErr else { - return nil - } - - return name as String - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift b/submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift deleted file mode 100644 index fe5f0379..00000000 --- a/submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift +++ /dev/null @@ -1,71 +0,0 @@ -// -// BatteryMonitor.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-03. -// - -import Foundation -import IOKit.ps - -class BatteryMonitor: ObservableObject { - @Published var currentState: BatteryState? - - private var runLoopSource: CFRunLoopSource? - - init() { - setupBatteryChangeNotification() - updateBatteryState() - } - - deinit { - if let source = runLoopSource { - CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, .defaultMode) - } - } - - private func setupBatteryChangeNotification() { - let callback: IOPowerSourceCallbackType = { _ in - DispatchQueue.main.async { - BatteryMonitor.shared?.updateBatteryState() - } - } - - let context = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) - - if let source = IOPSNotificationCreateRunLoopSource(callback, context)?.takeRetainedValue() { - runLoopSource = source - CFRunLoopAddSource(CFRunLoopGetCurrent(), source, .defaultMode) - } else { - } - - BatteryMonitor.shared = self - } - - private static var shared: BatteryMonitor? - - private func updateBatteryState() { - guard let snapshot = IOPSCopyPowerSourcesInfo()?.takeRetainedValue(), - let sources = IOPSCopyPowerSourcesList(snapshot)?.takeRetainedValue() as? [CFTypeRef], - let powerSource = sources.first, - let info = IOPSGetPowerSourceDescription(snapshot, powerSource)?.takeUnretainedValue() as? [String: AnyObject] else { - return - } - - let level = info[kIOPSCurrentCapacityKey] as? Int ?? -1 - let isCharging = info[kIOPSIsChargingKey] as? Bool ?? false - let sourceState = info[kIOPSPowerSourceStateKey] as? String ?? "" - - - let newState = BatteryState( - level: level, - isCharging: isCharging, - isPluggedIn: sourceState == kIOPSACPowerValue - ) - - - if newState != currentState { - currentState = newState - } - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift b/submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift deleted file mode 100644 index 96bf5deb..00000000 --- a/submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift +++ /dev/null @@ -1,160 +0,0 @@ -// -// BluetoothManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-07. -// - -import Foundation -import Combine -import IOBluetooth -import AppKit -import IOKit.hid -import IOKit - -struct BluetoothDeviceState: Hashable { - enum EventType: Hashable { - case connected, disconnected, batteryLow - } - let eventUUID = UUID() - let id: String, name: String, iconName: String, eventType: EventType - var batteryLevel: Int? = nil - static func == (lhs: Self, rhs: Self) -> Bool { lhs.eventUUID == rhs.eventUUID } - func hash(into hasher: inout Hasher) { hasher.combine(eventUUID) } -} - -class BluetoothManager: ObservableObject { - @Published var lastEvent: BluetoothDeviceState? - - private var batteryCheckTimer: Timer? - private var lowBatteryNotifiedDevices = Set() - - - private let privateMonitor = PrivateBluetoothMonitor() - private var cancellables = Set() - - private let lowBatteryThreshold = 20 - private let lowBatteryRefreshThreshold = 30 - - init() { - setupPrivateListener() - setupBatteryMonitor() - } - - private func setupPrivateListener() { - privateMonitor.eventPublisher - .sink { [weak self] event in - self?.processPrivateEvent(event) - } - .store(in: &cancellables) - } - - private func processPrivateEvent(_ event: PrivateBluetoothEvent) { - - guard let device = IOBluetoothDevice(addressString: event.address), - let deviceName = device.name else { return } - - let batteryLevel = (event.type == .connected) ? self.getBatteryLevel(for: device) : nil - - - if event.type == .disconnected { - lowBatteryNotifiedDevices.remove(event.address) - } - - let deviceState = BluetoothDeviceState( - id: event.address, - name: deviceName, - iconName: Self.getIconName(for: device), - eventType: (event.type == .connected) ? .connected : .disconnected, - batteryLevel: batteryLevel - ) - - DispatchQueue.main.async { - self.lastEvent = deviceState - } - } - - private func setupBatteryMonitor() { - batteryCheckTimer = Timer.scheduledTimer(timeInterval: 300.0, target: self, selector: #selector(checkForLowBattery), userInfo: nil, repeats: true) - batteryCheckTimer?.fireDate = Date(timeIntervalSinceNow: 15.0) - } - - @objc private func checkForLowBattery() { - guard let pairedDevices = IOBluetoothDevice.pairedDevices() as? [IOBluetoothDevice] else { return } - for device in pairedDevices where device.isConnected() { - guard let addressString = device.addressString, let level = self.getBatteryLevel(for: device) else { continue } - if level <= lowBatteryThreshold { - if !lowBatteryNotifiedDevices.contains(addressString) { - let deviceState = BluetoothDeviceState(id: addressString, name: device.name ?? "Device", iconName: Self.getIconName(for: device), eventType: .batteryLow, batteryLevel: level) - DispatchQueue.main.async { self.lastEvent = deviceState; NSSound(named: "Tink")?.play() } - lowBatteryNotifiedDevices.insert(addressString) - } - } else if level >= lowBatteryRefreshThreshold { - lowBatteryNotifiedDevices.remove(addressString) - } - } - } - - private func getBatteryLevel(for device: IOBluetoothDevice) -> Int? { - guard let deviceName = device.name else { return nil } - let batteryKeys = ["BatteryPercent", "battery-level", "device-battery-level", "Battery Level"] - var batteryLevel: Int? - let matchingDict = IOServiceMatching(kIOHIDDeviceKey) - var iterator: io_iterator_t = 0 - guard IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &iterator) == KERN_SUCCESS else { return nil } - var service = IOIteratorNext(iterator) - while service != 0 { - var properties: Unmanaged? - guard IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS, - let serviceProperties = properties?.takeRetainedValue() as? [String: Any] else { - IOObjectRelease(service); service = IOIteratorNext(iterator); continue - } - if let productName = serviceProperties[kIOHIDProductKey] as? String, productName.caseInsensitiveCompare(deviceName) == .orderedSame { - for key in batteryKeys { - if let level = serviceProperties[key] as? Int { batteryLevel = level; break } - } - } - IOObjectRelease(service) - if batteryLevel != nil { break } - service = IOIteratorNext(iterator) - } - IOObjectRelease(iterator) - if batteryLevel == nil { print("--> BluetoothManager: No standard battery level key found for '\(deviceName)'.") } - return batteryLevel - } - - private static func getIconName(for device: IOBluetoothDevice) -> String { - let majorClass = device.deviceClassMajor - let minorClass = device.deviceClassMinor - let deviceName = device.name?.lowercased() ?? "" - if deviceName.contains("keyboard") || deviceName.contains("keys") { return "keyboard.fill" } - switch majorClass { - case UInt32(kBluetoothDeviceClassMajorPeripheral): - switch minorClass { - case UInt32(kBluetoothDeviceClassMinorPeripheral1Keyboard): return "keyboard.fill" - case UInt32(kBluetoothDeviceClassMinorPeripheral1Pointing): - if deviceName.contains("trackpad") { return "magictrackpad.gen2.fill" } - if deviceName.contains("mouse") { return "magicmouse.fill" } - return "cursorarrow.click.2" - default: - if deviceName.contains("controller") { return "gamecontroller.fill" } - return "platter.filled.top.applewatch.case" - } - case UInt32(kBluetoothDeviceClassMajorAudio): - if deviceName.contains("airpods max") { return "airpods.max" } - if deviceName.contains("airpods pro") { return "airpodspro.right" } - if deviceName.contains("airpods") { return "airpods" } - if deviceName.contains("homepod") { return "homepod.fill" } - if deviceName.contains("beats") { return "beats.headphones" } - switch minorClass { - case UInt32(kBluetoothDeviceClassMinorAudioHeadphones): return "headphones" - case UInt32(kBluetoothDeviceClassMinorAudioLoudspeaker): return "speaker.wave.2.fill" - default: return "headphones" - } - case UInt32(kBluetoothDeviceClassMajorComputer): return "desktopcomputer" - case UInt32(kBluetoothDeviceClassMajorPhone): return "iphone" - case UInt32(kBluetoothDeviceClassMajorWearable): return "applewatch" - default: return "b.circle.fill" - } - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/DesktopManager.swift b/submissions/sapphire/Sapphire/Services/System/DesktopManager.swift deleted file mode 100644 index 30d1d75b..00000000 --- a/submissions/sapphire/Sapphire/Services/System/DesktopManager.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// DesktopManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import AppKit -import Combine - -class DesktopManager: ObservableObject { - - @Published private(set) var currentDesktopNumber: Int? - - init() { - - self.currentDesktopNumber = CGSHelper.getActiveDesktopNumber() - - - NSWorkspace.shared.notificationCenter.addObserver( - self, - selector: #selector(activeSpaceDidChange), - name: NSWorkspace.activeSpaceDidChangeNotification, - object: nil - ) - } - - @objc private func activeSpaceDidChange() { - DispatchQueue.main.async { - - self.currentDesktopNumber = CGSHelper.getActiveDesktopNumber() - } - } - - deinit { - NSWorkspace.shared.notificationCenter.removeObserver(self) - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift b/submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift deleted file mode 100644 index 782a3f6e..00000000 --- a/submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift +++ /dev/null @@ -1,86 +0,0 @@ -// -// EyeBreakManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import Foundation -import Combine -import AppKit - -class EyeBreakManager: ObservableObject { - private let settingsModel = SettingsModel() - - private var workInterval: TimeInterval { TimeInterval(settingsModel.settings.eyeBreakWorkInterval * 60) } - private var breakInterval: TimeInterval { TimeInterval(settingsModel.settings.eyeBreakBreakDuration) } - private var soundAlertsEnabled: Bool { settingsModel.settings.eyeBreakSoundAlerts } - - @Published var isBreakTime: Bool = false - @Published var timeUntilNextBreak: TimeInterval - @Published var timeRemainingInBreak: TimeInterval = 0 - @Published var isDoneButtonEnabled: Bool = false - - private var timer: Timer? - - init() { - - self.timeUntilNextBreak = 20 * 60 - - startWorkTimer() - } - - private func startWorkTimer() { - isBreakTime = false - isDoneButtonEnabled = false - timeRemainingInBreak = 0 - - timer?.invalidate() - timeUntilNextBreak = workInterval - - timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in - guard let self = self else { return } - - if self.timeUntilNextBreak > 0 { - self.timeUntilNextBreak -= 1 - } else { - self.startBreakTimer() - } - } - } - - private func startBreakTimer() { - timer?.invalidate() - - if soundAlertsEnabled { - NSSound(named: "Glass")?.play() - } - - isBreakTime = true - isDoneButtonEnabled = false - timeRemainingInBreak = breakInterval - - timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in - guard let self = self else { return } - - if self.timeRemainingInBreak > 0 { - self.timeRemainingInBreak -= 1 - } else { - self.isDoneButtonEnabled = true - self.timer?.invalidate() - } - } - } - - func dismissBreak() { - resetAndStartWork() - } - - func completeBreak() { - resetAndStartWork() - } - - private func resetAndStartWork() { - self.startWorkTimer() - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift b/submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift deleted file mode 100644 index 1735d1b2..00000000 --- a/submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift +++ /dev/null @@ -1,81 +0,0 @@ -// -// FocusModeManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import Foundation -import Combine -import Intents - - - -class FocusModeManager: ObservableObject { - - - @Published private(set) var currentFocusMode: FocusModeInfo? - - private var timer: Timer? - - init() { - - - INFocusStatusCenter.default.requestAuthorization { status in - - guard status == .authorized else { - return - } - - - DispatchQueue.main.async { - self.timer = Timer.scheduledTimer(withTimeInterval: 100, repeats: true) { [weak self] _ in - self?.checkFocusState() - } - - self.checkFocusState() - } - } - } - - - private func checkFocusState() { - - let isFocused = INFocusStatusCenter.default.focusStatus.isFocused - - - - let newMode: FocusModeInfo? = (isFocused == true) ? getActiveFocusDetails() : nil - - - if self.currentFocusMode != newMode { - DispatchQueue.main.async { - self.currentFocusMode = newMode - if let mode = newMode { - } else { - } - } - } - } - - - - private func getActiveFocusDetails() -> FocusModeInfo? { - let dndServiceDefaults = UserDefaults(suiteName: "com.apple.do-not-disturb-service") - - guard let preferences = dndServiceDefaults?.persistentDomain(forName: "com.apple.do-not-disturb-service"), - let assertionDetails = preferences["assertionDetails"] as? [[String: Any]], - let activeModeDict = assertionDetails.first, - let name = activeModeDict["name"] as? String, - let identifier = activeModeDict["identifier"] as? String else { - - return FocusModeInfo(name: "Do Not Disturb", identifier: "moon.fill") - } - - return FocusModeInfo(name: name, identifier: identifier) - } - - deinit { - timer?.invalidate() - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/NotificationManager.swift b/submissions/sapphire/Sapphire/Services/System/NotificationManager.swift deleted file mode 100644 index 0ebb4730..00000000 --- a/submissions/sapphire/Sapphire/Services/System/NotificationManager.swift +++ /dev/null @@ -1,173 +0,0 @@ -// -// NotificationManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import Foundation -import Combine -import SQLite3 - - - -class NotificationManager: ObservableObject { - - @Published var latestNotification: NotificationPayload? - - private var dbPath: String? - private var fileMonitor: DispatchSourceFileSystemObject? - private var db: OpaquePointer? - private var lastNotificationUUID: String? - - init() { - DispatchQueue.global(qos: .background).async { - self.dbPath = self.getNotificationDbPath() - self.setupDatabaseMonitoring() - } - } - - deinit { - fileMonitor?.cancel() - if db != nil { - sqlite3_close(db) - } - } - - func dismissLatestNotification() { - DispatchQueue.main.async { - self.latestNotification = nil - } - } - - private func setupDatabaseMonitoring() { - guard let dbPath = dbPath else { - return - } - - let url = URL(fileURLWithPath: dbPath) - let fileDescriptor = open(url.path, O_EVTONLY) - guard fileDescriptor != -1 else { - return - } - - fileMonitor = DispatchSource.makeFileSystemObjectSource(fileDescriptor: fileDescriptor, eventMask: .write, queue: .global(qos: .background)) - - fileMonitor?.setEventHandler { [weak self] in - self?.queryLatestNotification() - } - - fileMonitor?.setCancelHandler { - close(fileDescriptor) - } - - fileMonitor?.resume() - } - - private func queryLatestNotification() { - guard let dbPath = dbPath else { return } - - if sqlite3_open(dbPath, &db) != SQLITE_OK { - return - } - defer { sqlite3_close(db) } - - let query = "SELECT uuid, app_id, title, body, request_data FROM record WHERE presented = 0 ORDER BY delivered_date DESC LIMIT 1;" - - var statement: OpaquePointer? - if sqlite3_prepare_v2(db, query, -1, &statement, nil) != SQLITE_OK { - return - } - defer { sqlite3_finalize(statement) } - - if sqlite3_step(statement) == SQLITE_ROW { - - guard let uuid_c = sqlite3_column_text(statement, 0), - let app_id_c = sqlite3_column_text(statement, 1) else { - return - } - - let uuid = String(cString: uuid_c) - if uuid == lastNotificationUUID { return } - lastNotificationUUID = uuid - - let appIdentifier = String(cString: app_id_c) - - - let allowedIdentifiers = ["com.apple.iChat", "com.apple.facetime", "com.apple.sharingd", "com.apple.controlcenter"] - guard allowedIdentifiers.contains(appIdentifier) else { return } - - preemptSystemNotification(uuid: uuid) - - - - if appIdentifier == "com.apple.controlcenter" { - return - } - - let title_c = sqlite3_column_text(statement, 2) - let body_c = sqlite3_column_text(statement, 3) - - var finalTitle = title_c != nil ? String(cString: title_c!) : "" - var finalBody = body_c != nil ? String(cString: body_c!) : "" - - - if appIdentifier == "com.apple.sharingd" { - if let dataBlob = sqlite3_column_blob(statement, 4) { - let dataSize = sqlite3_column_bytes(statement, 4) - let requestData = Data(bytes: dataBlob, count: Int(dataSize)) - - if let plist = try? PropertyListSerialization.propertyList(from: requestData, options: [], format: nil) as? [String: Any], - let aps = plist["aps"] as? [String: Any], - let alert = aps["alert"] as? [String: Any] { - - if let titleArgs = alert["title-loc-args"] as? [String], let senderName = titleArgs.first { - finalTitle = senderName - } - - if let bodyArgs = alert["body-loc-args"] as? [String], let fileName = bodyArgs.first { - finalBody = fileName - } - } - } - } - - let payload = NotificationPayload(id: uuid, appIdentifier: appIdentifier, title: finalTitle, body: finalBody) - - DispatchQueue.main.async { - self.latestNotification = payload - } - } - } - - private func preemptSystemNotification(uuid: String) { - guard let dbPath = dbPath else { return } - var write_db: OpaquePointer? - - if sqlite3_open_v2(dbPath, &write_db, SQLITE_OPEN_READWRITE, nil) != SQLITE_OK { - return - } - defer { sqlite3_close(write_db) } - - let updateQuery = "UPDATE record SET presented = 1 WHERE uuid = ?;" - var statement: OpaquePointer? - - if sqlite3_prepare_v2(write_db, updateQuery, -1, &statement, nil) == SQLITE_OK { - sqlite3_bind_text(statement, 1, (uuid as NSString).utf8String, -1, nil) - - if sqlite3_step(statement) == SQLITE_DONE { - } - } - sqlite3_finalize(statement) - } - - private func getNotificationDbPath() -> String? { - let basePath = ("~/Library/Application Support/NotificationCenter" as NSString).expandingTildeInPath - do { - let files = try FileManager.default.contentsOfDirectory(atPath: basePath) - return files.first { $0.hasSuffix(".db") }.map { (basePath as NSString).appendingPathComponent($0) } - } catch { - return nil - } - } -} diff --git a/submissions/sapphire/Sapphire/Services/System/TimerManager.swift b/submissions/sapphire/Sapphire/Services/System/TimerManager.swift deleted file mode 100644 index e4266af5..00000000 --- a/submissions/sapphire/Sapphire/Services/System/TimerManager.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// TimerManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-28. -// - -import Foundation - - - -class TimerManager: ObservableObject { - @Published var isRunning: Bool = false - @Published var elapsedTime: TimeInterval = 0 - private var timer: Timer? - - func start() { - guard !isRunning else { return } - isRunning = true - timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { [weak self] _ in - self?.elapsedTime += 0.1 - } - } - - func stop() { - isRunning = false - timer?.invalidate() - } - - func reset() { - stop() - elapsedTime = 0 - } -} diff --git a/submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift b/submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift deleted file mode 100644 index b24ce631..00000000 --- a/submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift +++ /dev/null @@ -1,174 +0,0 @@ -// -// WeatherService.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import Foundation -import CoreLocation -import SwiftUI - -class WeatherService: NSObject, CLLocationManagerDelegate { - private let locationManager = CLLocationManager() - private var completionHandler: ((Result) -> Void)? - - private let weatherAPIKey = "e45ff1b7c7bda231216c7ab7c33509b8" - - private static let apiDateFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" - formatter.locale = Locale(identifier: "en_US_POSIX") - return formatter - }() - - private static let displayTimeFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.timeStyle = .short - return formatter - }() - - private static let hourlyTimeFormatter: DateFormatter = { - let formatter = DateFormatter() - formatter.dateFormat = "ha" - return formatter - }() - - override init() { - super.init() - locationManager.delegate = self - locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers - } - - public func fetchWeather(completion: @escaping (Result) -> Void) { - self.completionHandler = completion - - if !CLLocationManager.locationServicesEnabled() { - let error = NSError(domain: "WeatherService", code: 3, userInfo: [NSLocalizedDescriptionKey: "Location services are disabled system-wide."]) - completionHandler?(.failure(error)) - return - } - - switch locationManager.authorizationStatus { - case .authorized, .authorizedAlways: - locationManager.requestLocation() - case .denied, .restricted: - let error = NSError(domain: "WeatherService", code: 2, userInfo: [NSLocalizedDescriptionKey: "Location access was denied. Please enable it in System Settings."]) - completionHandler?(.failure(error)) - case .notDetermined: - locationManager.requestLocation() - @unknown default: - let error = NSError(domain: "WeatherService", code: 99, userInfo: [NSLocalizedDescriptionKey: "Unknown location authorization status."]) - completionHandler?(.failure(error)) - } - } - - func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { - guard let location = locations.last else { return } - locationManager.stopUpdatingLocation() - fetchAPIs(for: location) - } - - func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { - completionHandler?(.failure(error)) - } - - func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { - fetchWeather(completion: self.completionHandler ?? { _ in }) - } - - private func fetchAPIs(for location: CLLocation) { - let lat = location.coordinate.latitude - let lon = location.coordinate.longitude - let urlString = "https://api.weather.com/v1/geocode/\(lat)/\(lon)/aggregate.json?apiKey=\(weatherAPIKey)&products=conditionsshort,fcstdaily10short,fcsthourly24short,nowlinks" - - guard let url = URL(string: urlString) else { - let error = NSError(domain: "WeatherService", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]) - completionHandler?(.failure(error)) - return - } - - Task { - do { - let placemarks = try await CLGeocoder().reverseGeocodeLocation(location) - let locationName = placemarks.first?.locality ?? placemarks.first?.name ?? "Unknown Location" - - let (data, _) = try await URLSession.shared.data(from: url) - - let decoder = JSONDecoder() - let apiResponse = try decoder.decode(WeatherApiResponse.self, from: data) - - let processedData = self.process(response: apiResponse, locationName: locationName) - self.completionHandler?(.success(processedData)) - - } catch { - self.completionHandler?(.failure(error)) - } - } - } - - private func process(response: WeatherApiResponse, locationName: String) -> ProcessedWeatherData { - let observation = response.conditionsshort?.observation - let todayForecast = response.fcstdaily10short?.forecasts?.first - - let uiDailyForecasts: [DailyForecastUIData] = response.fcstdaily10short?.forecasts?.prefix(7).compactMap { forecast in - guard let dow = forecast.dow, - let maxTemp = forecast.imperial?.max_temp, let minTemp = forecast.imperial?.min_temp, - let maxTempMetric = forecast.metric?.max_temp, let minTempMetric = forecast.metric?.min_temp else { - return nil - } - return DailyForecastUIData( - dayOfWeek: String(dow.prefix(3)).uppercased(), - iconName: WeatherIconMapper.map(from: forecast.day?.icon_cd ?? 44), - highTemp: maxTemp, - lowTemp: minTemp, - highTempMetric: maxTempMetric, - lowTempMetric: minTempMetric - ) - } ?? [] - - let uiHourlyForecasts: [HourlyForecastUIData] = response.fcsthourly24short?.forecasts?.prefix(8).compactMap { forecast in - guard let gmt = forecast.fcst_valid, let icon = forecast.icon_cd, - let tempImperial = forecast.imperial?.temp, - let tempMetric = forecast.metric?.temp else { - return nil - } - let date = Date(timeIntervalSince1970: TimeInterval(gmt)) - return HourlyForecastUIData( - time: Self.hourlyTimeFormatter.string(from: date).uppercased(), - iconName: WeatherIconMapper.map(from: icon), - temperature: "\(tempImperial)°", - temperatureMetric: "\(tempMetric)°" - ) - } ?? [] - - return ProcessedWeatherData( - locationName: locationName, - temperature: observation?.imperial?.temp ?? 0, - temperatureMetric: observation?.metric?.temp ?? 0, - highTemp: todayForecast?.imperial?.max_temp ?? 0, - highTempMetric: todayForecast?.metric?.max_temp ?? 0, - lowTemp: todayForecast?.imperial?.min_temp ?? 0, - lowTempMetric: todayForecast?.metric?.min_temp ?? 0, - conditionDescription: observation?.wx_phrase ?? "Unavailable", - iconCode: observation?.wx_icon ?? 44, - feelsLike: observation?.imperial?.feels_like ?? 0, - feelsLikeMetric: observation?.metric?.feels_like ?? 0, - windInfo: "\(observation?.imperial?.wspd ?? 0) mph", - humidity: "\(observation?.rh ?? 0)%", - precipChance: todayForecast?.day?.pop ?? 0, - uvIndex: "\(observation?.uv_index ?? 0) (\(observation?.uv_desc ?? "N/A"))", - sunriseTime: formatTime(from: todayForecast?.sunrise), - sunsetTime: formatTime(from: todayForecast?.sunset), - visibility: observation?.vis != nil ? "\(Int(observation!.vis!)) mi" : "-- mi", - pressure: observation?.pressure != nil ? "\(String(format: "%.2f", observation!.pressure! * 0.02953)) in" : "-- in", - dailyForecasts: uiDailyForecasts, - hourlyForecasts: uiHourlyForecasts - ) - } - - private func formatTime(from dateString: String?) -> String { - guard let dateString = dateString, let date = Self.apiDateFormatter.date(from: dateString) else { return "--:--" } - return Self.displayTimeFormatter.string(from: date) - } -} diff --git a/submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift b/submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift deleted file mode 100644 index b30c5e36..00000000 --- a/submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift +++ /dev/null @@ -1,102 +0,0 @@ -// -// WeatherViewModel.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI -import CoreLocation - -class WeatherViewModel: ObservableObject { - private let weatherService = WeatherService() - private let settingsModel = SettingsModel() - - - @Published var locationName: String = "Loading..." - @Published var temperature: String = "—°" - @Published var conditionDescription: String = "Fetching..." - @Published var highLowTemp: String = "H: —° L: —°" - @Published var feelsLike: String = "—°" - @Published var windInfo: String = "— mph" - @Published var humidity: String = "—%" - @Published var uvIndex: String = "—" - @Published var visibility: String = "—" - @Published var pressure: String = "—" - @Published var precipChance: String = "—%" - @Published var iconName: String = "icloud" - @Published var gradientColors: [Color] = [.blue.opacity(0.8), .purple.opacity(0.8)] - @Published var hourlyForecasts: [HourlyForecastUIData] = [] - - init() { - fetch() - Timer.scheduledTimer(withTimeInterval: 60 * 15, repeats: true) { [weak self] _ in - self?.fetch() - } - } - - - func fetch() { - weatherService.fetchWeather { [weak self] result in - DispatchQueue.main.async { - switch result { - case .success(let data): - self?.updateUI(with: data) - case .failure(let error): - self?.handleError(error) - } - } - } - } - - - private func updateUI(with data: ProcessedWeatherData) { - let useCelsius = settingsModel.settings.weatherUseCelsius - - self.locationName = data.locationName - self.temperature = useCelsius ? "\(data.temperatureMetric)°" : "\(data.temperature)°" - self.conditionDescription = data.conditionDescription - self.highLowTemp = useCelsius ? "H: \(data.highTempMetric)° L: \(data.lowTempMetric)°" : "H: \(data.highTemp)° L: \(data.lowTemp)°" - self.feelsLike = useCelsius ? "\(data.feelsLikeMetric)°" : "\(data.feelsLike)°" - self.windInfo = data.windInfo - self.humidity = data.humidity - self.uvIndex = data.uvIndex - self.visibility = data.visibility - self.pressure = data.pressure - self.precipChance = "\(data.precipChance)%" - self.iconName = WeatherIconMapper.map(from: data.iconCode) - self.hourlyForecasts = data.hourlyForecasts - self.gradientColors = gradientColors(for: data.iconCode) - } - - private func handleError(_ error: Error) { - self.locationName = "Error" - self.temperature = "—°" - self.conditionDescription = "Failed to load" - self.highLowTemp = "H: —° L: —°" - self.feelsLike = "—°" - self.windInfo = "— mph" - self.humidity = "—%" - self.uvIndex = "—" - self.visibility = "—" - self.pressure = "—" - self.precipChance = "—%" - self.iconName = "exclamationmark.triangle.fill" - self.gradientColors = [.gray, .black.opacity(0.8)] - self.hourlyForecasts = [] - } - - - private func gradientColors(for iconCode: Int) -> [Color] { - switch iconCode { - case 31, 32, 33, 34, 36: return [Color("#4A90E2"), Color("#81C7F4")] - case 27, 28, 29, 30: return [Color("#5D7A98"), Color("#8E9EAE")] - case 26: return [Color("#8E9EAE"), Color("#B4C1CC")] - case 3, 4, 37, 38, 47: return [Color("#2c3e50"), Color("#465868")] - case 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 35, 39, 40, 45: return [Color("#5A7D9A"), Color("#829AB1")] - case 13, 14, 15, 16, 41, 42, 43, 46: return [Color("#B4C1CC"), Color("#E0E6EB")] - case 19, 20, 21, 22: return [Color("#95A5A6"), Color("#BDC3C7")] - default: return [Color("#4A90E2"), Color("#81C7F4")] - } - } -} diff --git a/submissions/sapphire/Sapphire/System/PrivateAPIs.swift b/submissions/sapphire/Sapphire/System/PrivateAPIs.swift deleted file mode 100644 index fa26d126..00000000 --- a/submissions/sapphire/Sapphire/System/PrivateAPIs.swift +++ /dev/null @@ -1,254 +0,0 @@ -// -// PrivateAPIs.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import SwiftUI -import Cocoa -import AudioToolbox - - - -fileprivate typealias CGSConnectionID = Int -fileprivate typealias CGSSpaceID = UInt64 - - -@_silgen_name("_CGSDefaultConnection") -fileprivate func _CGSDefaultConnection() -> CGSConnectionID - - -@_silgen_name("CGSSpaceCreate") -fileprivate func CGSSpaceCreate(_ cid: CGSConnectionID, _ unknown: Int, _ options: NSDictionary?) -> CGSSpaceID -@_silgen_name("CGSSpaceDestroy") -fileprivate func CGSSpaceDestroy(_ cid: CGSConnectionID, _ space: CGSSpaceID) -@_silgen_name("CGSSpaceSetAbsoluteLevel") -fileprivate func CGSSpaceSetAbsoluteLevel(_ cid: CGSConnectionID, _ space: CGSSpaceID, _ level: Int) -@_silgen_name("CGSAddWindowsToSpaces") -fileprivate func CGSAddWindowsToSpaces(_ cid: CGSConnectionID, _ windows: NSArray, _ spaces: NSArray) -@_silgen_name("CGSRemoveWindowsFromSpaces") -fileprivate func CGSRemoveWindowsFromSpaces(_ cid: CGSConnectionID, _ windows: NSArray, _ spaces: NSArray) -@_silgen_name("CGSHideSpaces") -fileprivate func CGSHideSpaces(_ cid: CGSConnectionID, _ spaces: NSArray) -@_silgen_name("CGSShowSpaces") -fileprivate func CGSShowSpaces(_ cid: CGSConnectionID, _ spaces: NSArray) -@_silgen_name("CGSGetActiveSpace") -private func CGSGetActiveSpace(_ cid: CGSConnectionID) -> CGSSpaceID -@_silgen_name("CGSCopyManagedDisplaySpaces") -private func CGSCopyManagedDisplaySpaces(_ cid: CGSConnectionID) -> CFArray - - - -@_silgen_name("DisplayServicesGetBrightness") -private func DisplayServicesGetBrightness(_ display: CGDirectDisplayID, _ brightness: UnsafeMutablePointer) -> Int32 -@_silgen_name("DisplayServicesSetBrightness") -private func DisplayServicesSetBrightness(_ display: CGDirectDisplayID, _ brightness: Float) -> Int32 - - - -@_silgen_name("$s7SwiftUI5ImageV19_internalSystemNameACSS_tcfC") -private func _swiftUI_image(internalSystemName: String) -> Image? - -extension Image { - - init?(privateName: String) { - guard let systemImage = _swiftUI_image(internalSystemName: privateName) else { - return nil - } - self = systemImage - } -} - - - - -public final class CGSSpace { - private let identifier: CGSSpaceID - private let createdByInit: Bool - private let connectionID: CGSConnectionID - - public var windows: Set = [] { - didSet { - let remove = oldValue.subtracting(self.windows) - let add = self.windows.subtracting(oldValue) - - if connectionID != 0 { - if !remove.isEmpty { - CGSRemoveWindowsFromSpaces(connectionID, remove.map { $0.windowNumber } as NSArray, [self.identifier] as NSArray) - } - if !add.isEmpty { - CGSAddWindowsToSpaces(connectionID, add.map { $0.windowNumber } as NSArray, [self.identifier] as NSArray) - } - } else { - } - } - } - - - public init(level: Int = 0) { - self.connectionID = _CGSDefaultConnection() - let flag = 0x1 - - self.identifier = CGSSpaceCreate(connectionID, flag, nil as NSDictionary?) - CGSSpaceSetAbsoluteLevel(connectionID, self.identifier, level) - CGSShowSpaces(connectionID, [self.identifier] as NSArray) - self.createdByInit = true - } - - deinit { - if connectionID != 0 && identifier != 0 { - CGSHideSpaces(connectionID, [self.identifier] as NSArray) - if createdByInit { - CGSSpaceDestroy(connectionID, self.identifier) - } - } - } -} - - - - -class OSDManager { - static func disableSystemHUD() { - let kickstart = Process() - kickstart.launchPath = "/bin/launchctl" - kickstart.arguments = ["kickstart", "gui/\(getuid())/com.apple.OSDUIHelper"] - - do { - try kickstart.run() - kickstart.waitUntilExit() - } catch { - } - - let stopProcess = Process() - stopProcess.launchPath = "/usr/bin/killall" - stopProcess.arguments = ["-STOP", "OSDUIHelper"] - - do { - try stopProcess.run() - } catch { - } - } - - static func enableSystemHUD() { - let continueProcess = Process() - continueProcess.launchPath = "/usr/bin/killall" - continueProcess.arguments = ["-CONT", "OSDUIHelper"] - - do { - try continueProcess.run() - } catch { - } - } -} - - - - -struct SystemControl { - - - private static func getDefaultOutputDeviceID() -> AudioDeviceID? { - var deviceID: AudioDeviceID = kAudioObjectUnknown - var propertySize = UInt32(MemoryLayout.size) - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioHardwarePropertyDefaultOutputDevice, - mScope: kAudioObjectPropertyScopeGlobal, - mElement: kAudioObjectPropertyElementMain - ) - let status = AudioObjectGetPropertyData(AudioObjectID(kAudioObjectSystemObject), &propertyAddress, 0, nil, &propertySize, &deviceID) - return status == noErr ? deviceID : nil - } - - static func getVolume() -> Float { - guard let deviceID = getDefaultOutputDeviceID() else { return 0.5 } - var volume: Float32 = 0.0 - var propertySize = UInt32(MemoryLayout.size) - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioDevicePropertyVolumeScalar, - mScope: kAudioObjectPropertyScopeOutput, - mElement: kAudioObjectPropertyElementMain - ) - AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &volume) - return Float(volume) - } - - static func setVolume(to level: Float) { - guard let deviceID = getDefaultOutputDeviceID() else { return } - var newVolume = Float32(max(0.0, min(1.0, level))) - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioDevicePropertyVolumeScalar, - mScope: kAudioObjectPropertyScopeOutput, - mElement: kAudioObjectPropertyElementMain - ) - AudioObjectSetPropertyData(deviceID, &propertyAddress, 0, nil, UInt32(MemoryLayout.size(ofValue: newVolume)), &newVolume) - } - - static func isMuted() -> Bool { - guard let deviceID = getDefaultOutputDeviceID() else { return false } - var isMuted: UInt32 = 0 - var propertySize = UInt32(MemoryLayout.size) - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioDevicePropertyMute, - mScope: kAudioObjectPropertyScopeOutput, - mElement: kAudioObjectPropertyElementMain - ) - AudioObjectGetPropertyData(deviceID, &propertyAddress, 0, nil, &propertySize, &isMuted) - return isMuted == 1 - } - - static func setMuted(to isMuted: Bool) { - guard let deviceID = getDefaultOutputDeviceID() else { return } - var muteVal: UInt32 = isMuted ? 1 : 0 - var propertyAddress = AudioObjectPropertyAddress( - mSelector: kAudioDevicePropertyMute, - mScope: kAudioObjectPropertyScopeOutput, - mElement: kAudioObjectPropertyElementMain - ) - AudioObjectSetPropertyData(deviceID, &propertyAddress, 0, nil, UInt32(MemoryLayout.size(ofValue: muteVal)), &muteVal) - } - - - static func getBrightness() -> Float { - var brightness: Float = 0.0 - guard let screen = NSScreen.main else { return 0.5 } - let displayID = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID ?? 0 - if DisplayServicesGetBrightness(displayID, &brightness) != 0 { - return 0.5 - } - return brightness - } - - static func setBrightness(to level: Float) { - let clampedLevel = min(1.0, max(0.0, level)) - for screen in NSScreen.screens { - let displayID = screen.deviceDescription[NSDeviceDescriptionKey("NSScreenNumber")] as? CGDirectDisplayID ?? 0 - DisplayServicesSetBrightness(displayID, clampedLevel) - } - } -} - - - - -struct CGSHelper { - private static let connection = _CGSDefaultConnection() - - - static func getActiveDesktopNumber() -> Int? { - let activeSpaceID = CGSGetActiveSpace(connection) - - guard let displaySpaces = CGSCopyManagedDisplaySpaces(connection) as? [[String: Any]], - let mainDisplay = displaySpaces.first, - let spacesForMainDisplay = mainDisplay["Spaces"] as? [[String: Any]] else { - return nil - } - - if let index = spacesForMainDisplay.firstIndex(where: { ($0["id64"] as? CGSSpaceID) == activeSpaceID }) { - return index + 1 - } - - return nil - } -} diff --git a/submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift b/submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift deleted file mode 100644 index c88b70dd..00000000 --- a/submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift +++ /dev/null @@ -1,52 +0,0 @@ -// -// PrivateBluetoothMonitor.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-07. -// - -import Foundation -import Combine - -class PrivateBluetoothMonitor { - private var diagnosticObserver: NSObjectProtocol? - - init() { - - let dnc = DistributedNotificationCenter.default() - - - diagnosticObserver = dnc.addObserver( - forName: nil, - object: nil, - queue: nil - ) { notification in - - } - - - DispatchQueue.main.asyncAfter(deadline: .now() + 30) { [weak self] in - if let observer = self?.diagnosticObserver { - DistributedNotificationCenter.default().removeObserver(observer) - } - } - } - - deinit { - if let observer = diagnosticObserver { - DistributedNotificationCenter.default().removeObserver(observer) - } - } - - - let eventPublisher = PassthroughSubject() -} - - -struct PrivateBluetoothEvent { - enum EventType { - case connected, disconnected - } - let address: String - let type: EventType -} diff --git a/submissions/sapphire/Sapphire/System/SystemHUD.swift b/submissions/sapphire/Sapphire/System/SystemHUD.swift deleted file mode 100644 index 424274fa..00000000 --- a/submissions/sapphire/Sapphire/System/SystemHUD.swift +++ /dev/null @@ -1,357 +0,0 @@ -// -// SystemHUD.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-06. -// - -import SwiftUI -import AppKit -import Combine - - -fileprivate func eventTapCallback(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent, refcon: UnsafeMutableRawPointer?) -> Unmanaged? { - guard type.rawValue == NX_SYSDEFINED else { - return Unmanaged.passRetained(event) - } - - - if SystemHUDManager.shared.handleMediaKeyEvent(event) { - return nil - } - - return Unmanaged.passRetained(event) -} - - -extension Notification.Name { - static let mediaKeyPlayPausePressed = Notification.Name("mediaKeyPlayPausePressed") - static let mediaKeyNextPressed = Notification.Name("mediaKeyNextPressed") - static let mediaKeyPreviousPressed = Notification.Name("mediaKeyPreviousPressed") -} - - - -enum HUDType: Hashable { - case volume(level: Float) - case brightness(level: Float) - - var caseIdentifier: CaseIdentifier { - switch self { - case .volume: return .volume - case .brightness: return .brightness - } - } - enum CaseIdentifier { case volume, brightness } -} - -private enum MediaKeyAction { - case volumeUp, volumeDown - case brightnessUp, brightnessDown -} - - -class SystemHUDManager: ObservableObject { - static let shared = SystemHUDManager() - - @Published private(set) var currentHUD: HUDType? - var style: HUDStyle = .default - - private var eventTap: CFMachPort? - private var hudDismissalTimer: Timer? - private var changeAnimator: Timer? - private var currentAction: MediaKeyAction? - private var isFineTuning: Bool = false - private var keyPressStartTime: Date? - - private let initialStepAmount: Float = 1.0 / 16.0 - private let keyRepeatDelay: TimeInterval = 0.2 - private let animationInterval: TimeInterval = 1.0 / 60.0 - private let baseAnimationRate: Float = 1.0 / 2.0 - private let maxAnimationRate: Float = 1.0 / 0.7 - private let accelerationDuration: TimeInterval = 1.5 - private let fineAnimationRate: Float = 1.0 / 5.0 - - private init() { - setupEventTap() - } - - private func setupEventTap() { - let eventsToMonitor: CGEventMask = (1 << NX_SYSDEFINED) - eventTap = CGEvent.tapCreate( - tap: .cgSessionEventTap, - place: .headInsertEventTap, - options: .defaultTap, - eventsOfInterest: eventsToMonitor, - callback: eventTapCallback, - userInfo: nil - ) - - guard let eventTap = eventTap else { - return - } - let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0) - CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, .commonModes) - CGEvent.tapEnable(tap: eventTap, enable: true) - } - - fileprivate func handleMediaKeyEvent(_ cgEvent: CGEvent) -> Bool { - guard let nsEvent = NSEvent(cgEvent: cgEvent), - nsEvent.type == .systemDefined, - nsEvent.subtype.rawValue == 8 else { - return false - } - - let keyCode = Int32((nsEvent.data1 & 0xFFFF0000) >> 16) - let keyState = (nsEvent.data1 & 0xFF00) >> 8 - let isKeyDown = (keyState == 0x0A) - let isKeyUp = (keyState == 0x0B) - - - - switch keyCode { - case NX_KEYTYPE_PLAY: - NotificationCenter.default.post(name: .mediaKeyPlayPausePressed, object: nil) - return true - case NX_KEYTYPE_FAST: - NotificationCenter.default.post(name: .mediaKeyNextPressed, object: nil) - return true - case NX_KEYTYPE_REWIND: - NotificationCenter.default.post(name: .mediaKeyPreviousPressed, object: nil) - return true - default: - break - } - - - let action: MediaKeyAction? - switch keyCode { - case NX_KEYTYPE_SOUND_UP: action = .volumeUp - case NX_KEYTYPE_SOUND_DOWN: action = .volumeDown - case NX_KEYTYPE_BRIGHTNESS_UP: action = .brightnessUp - case NX_KEYTYPE_BRIGHTNESS_DOWN: action = .brightnessDown - case NX_KEYTYPE_MUTE: - if isKeyDown { - DispatchQueue.main.async { self.handleMute() } - } - return true - default: - return false - } - - guard let validAction = action else { return false } - - DispatchQueue.main.async { - if isKeyDown { - if self.currentAction == nil { - self.startSmoothChange(for: validAction, with: nsEvent.modifierFlags) - } - } else if isKeyUp { - if validAction == self.currentAction { - self.stopSmoothChange() - } - } - } - - return true - } - - private func handleMute() { - stopSmoothChange() - let isMuted = SystemControl.isMuted() - SystemControl.setMuted(to: !isMuted) - let currentVolume = SystemControl.getVolume() - showHUD(for: .volume(level: !isMuted ? 0.0 : (currentVolume > 0 ? currentVolume : 0.01))) - if !isMuted { NSSound(named: "Tink")?.play() } - } - - private func startSmoothChange(for action: MediaKeyAction, with modifiers: NSEvent.ModifierFlags) { - currentAction = action - isFineTuning = modifiers.contains([.shift, .option]) - keyPressStartTime = Date() - - let initialStep = isFineTuning ? (initialStepAmount / 4.0) : initialStepAmount - performChange(by: initialStep, isInitialPress: true) - - changeAnimator = Timer.scheduledTimer( - timeInterval: animationInterval, - target: self, - selector: #selector(performAnimatedStep), - userInfo: nil, - repeats: true - ) - changeAnimator?.fireDate = Date(timeIntervalSinceNow: keyRepeatDelay) - } - - private func stopSmoothChange() { - changeAnimator?.invalidate() - changeAnimator = nil - currentAction = nil - keyPressStartTime = nil - } - - @objc private func performAnimatedStep() { - guard let startTime = keyPressStartTime else { - stopSmoothChange() - return - } - - let effectiveRate: Float - if isFineTuning { - effectiveRate = fineAnimationRate - } else { - let duration = Date().timeIntervalSince(startTime) - let elapsedSinceAnimationStart = max(0, duration - keyRepeatDelay) - let progress = min(1.0, elapsedSinceAnimationStart / accelerationDuration) - let easedProgress = Float(progress * progress) - effectiveRate = baseAnimationRate + (maxAnimationRate - baseAnimationRate) * easedProgress - } - - let step = effectiveRate * Float(animationInterval) - performChange(by: step, isInitialPress: false) - } - - private func performChange(by amount: Float, isInitialPress: Bool) { - guard let action = currentAction else { return } - - switch action { - case .volumeUp: - let newVolume = min(1.0, SystemControl.getVolume() + amount) - SystemControl.setVolume(to: newVolume) - SystemControl.setMuted(to: false) - showHUD(for: .volume(level: newVolume)) - if isInitialPress { NSSound(named: "Tink")?.play() } - case .volumeDown: - let newVolume = max(0.0, SystemControl.getVolume() - amount) - SystemControl.setVolume(to: newVolume) - SystemControl.setMuted(to: false) - showHUD(for: .volume(level: newVolume)) - if isInitialPress { NSSound(named: "Tink")?.play() } - case .brightnessUp: - let newBrightness = min(1.0, SystemControl.getBrightness() + amount) - SystemControl.setBrightness(to: newBrightness) - showHUD(for: .brightness(level: newBrightness)) - case .brightnessDown: - let newBrightness = max(0.0, SystemControl.getBrightness() - amount) - SystemControl.setBrightness(to: newBrightness) - showHUD(for: .brightness(level: newBrightness)) - } - } - - private func showHUD(for hudType: HUDType) { - self.currentHUD = hudType - hudDismissalTimer?.invalidate() - hudDismissalTimer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { [weak self] _ in - self?.currentHUD = nil - } - } -} - - -struct SystemHUDView: View { - let type: HUDType - @State private var isShowing = false - - private var iconName: String { - switch type { - case .volume(let level): - if level == 0 { return "speaker.slash.fill" } - if level < 0.33 { return "speaker.wave.1.fill" } - if level < 0.66 { return "speaker.wave.2.fill" } - return "speaker.wave.3.fill" - case .brightness: return "sun.max.fill" - } - } - - private var level: Float { - switch type { - case .volume(let level): return level - case .brightness(let level): return level - } - } - - var body: some View { - HStack(spacing: 12) { - ZStack { - Circle().fill(.white.opacity(0.1)) - Image(systemName: iconName) - .font(.system(size: 18, weight: .semibold)) - .foregroundStyle(.white) - } - .frame(width: 40, height: 40) - - ModernLinearIndicator(level: CGFloat(level)) - .frame(height: 8) - } - .padding(.horizontal, 16) - .padding(.vertical, 10) - .background(.thinMaterial) - .background(.black.opacity(0.4)) - .clipShape(Capsule()) - .overlay(Capsule().strokeBorder(.white.opacity(0.2), lineWidth: 1)) - .shadow(color: .black.opacity(0.3), radius: 15, y: 5) - .padding(.top, 30) - .frame(width: 240) - .scaleEffect(isShowing ? 1 : 0.9) - .opacity(isShowing ? 1 : 0) - .onAppear { - withAnimation(.spring(response: 0.4, dampingFraction: 0.8)) { - isShowing = true - } - } - .transition(.identity) - } -} - - -struct SystemHUDSlimActivityView { - static func left(type: HUDType) -> some View { - let iconName: String = { - switch type { - case .volume(let level): - if level == 0 { return "speaker.slash.fill" } - if level < 0.33 { return "speaker.wave.1.fill" } - if level < 0.66 { return "speaker.wave.2.fill" } - return "speaker.wave.3.fill" - case .brightness: return "sun.max.fill" - } - }() - - return ZStack { - Image(systemName: iconName) - .font(.system(size: 14, weight: .semibold)) - .foregroundColor(.white) - .animation(nil, value: type) - } - .frame(width: 20, height: 20) - .animation(.default, value: type.caseIdentifier) - } - - static func right(type: HUDType) -> some View { - let level: Float = { - switch type { - case .volume(let level): return level - case .brightness(let level): return level - } - }() - - return ModernLinearIndicator(level: CGFloat(level)) - .frame(width: 100, height: 6) - .fixedSize() - } -} - - -struct ModernLinearIndicator: View { - var level: CGFloat - var body: some View { - GeometryReader { geometry in - ZStack(alignment: .leading) { - Capsule().fill(.primary.opacity(0.15)) - Capsule().fill(Color.white) - .frame(width: geometry.size.width * max(0, level)) - .animation(.linear(duration: 0.05), value: level) - } - } - } -} diff --git a/submissions/sapphire/Sapphire/Utilities/Extensions.swift b/submissions/sapphire/Sapphire/Utilities/Extensions.swift deleted file mode 100644 index 3440f42f..00000000 --- a/submissions/sapphire/Sapphire/Utilities/Extensions.swift +++ /dev/null @@ -1,184 +0,0 @@ -// -// Extensions.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import SwiftUI -import AppKit -import Combine -import ScreenCaptureKit - - -extension Date { - func format(as format: String) -> String { - let formatter = DateFormatter() - formatter.dateFormat = format - return formatter.string(from: self) - } - func isSameDay(as otherDate: Date) -> Bool { - return Calendar.current.isDate(self, inSameDayAs: otherDate) - } - var isWeekend: Bool { - return Calendar.current.isDateInWeekend(self) - } -} - -extension Color { - func lerp(to otherColor: Color, t: CGFloat) -> Color { - let t_clamped = min(max(t, 0), 1) - let from = self.resolve(in: .init()) - let to = otherColor.resolve(in: .init()) - let r = from.red + (to.red - from.red) * Float(t_clamped) - let g = from.green + (to.green - from.green) * Float(t_clamped) - let b = from.blue + (to.blue - from.blue) * Float(t_clamped) - return Color(red: Double(r), green: Double(g), blue: Double(b)) - } -} - -extension NSImage { - func getEdgeColors() -> (left: Color, right: Color, accent: Color)? { - guard let cgImage = self.cgImage(forProposedRect: nil, context: nil, hints: nil) else { return nil } - - let ciImage = CIImage(cgImage: cgImage) - let extent = ciImage.extent - let context = CIContext() - - func getRawAverageNSColor(from rect: CGRect) -> NSColor? { - let filter = CIFilter(name: "CIAreaAverage", parameters: [kCIInputImageKey: ciImage, kCIInputExtentKey: CIVector(cgRect: rect)])! - guard let outputImage = filter.outputImage else { return nil } - - var bitmap = [UInt8](repeating: 0, count: 4) - context.render(outputImage, toBitmap: &bitmap, rowBytes: 4, bounds: CGRect(x: 0, y: 0, width: 1, height: 1), format: .RGBA8, colorSpace: nil) - - return NSColor(red: CGFloat(bitmap[0]) / 255.0, green: CGFloat(bitmap[1]) / 255.0, blue: CGFloat(bitmap[2]) / 255.0, alpha: 1.0) - } - - let edgeWidth = extent.width * 0.1 - let leftRect = CGRect(x: extent.origin.x, y: extent.origin.y, width: edgeWidth, height: extent.height) - let rightRect = CGRect(x: extent.maxX - edgeWidth, y: extent.origin.y, width: edgeWidth, height: extent.height) - - guard var leftNSColor = getRawAverageNSColor(from: leftRect), - var rightNSColor = getRawAverageNSColor(from: rightRect) else { - return nil - } - - if leftNSColor.isSimilar(to: rightNSColor, threshold: 0.05) { - rightNSColor = rightNSColor.madeDistinct() - } - - let accentNSColor = leftNSColor.withBrightness(increasedBy: 0.2) - - let finalLeftColor = Color(leftNSColor.saturated(by: 0.3).withMinimumBrightness(0.45)) - let finalRightColor = Color(rightNSColor.saturated(by: 0.3).withMinimumBrightness(0.45)) - let finalAccentColor = Color(accentNSColor.saturated(by: 0.3).withMinimumBrightness(0.50)) - - return (left: finalLeftColor, right: finalRightColor, accent: finalAccentColor) - } -} - -extension NSColor { - func withBrightness(increasedBy amount: CGFloat) -> NSColor { - var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 - self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) - let newBrightness = min(brightness + amount, 1.0) - return NSColor(hue: hue, saturation: saturation, brightness: newBrightness, alpha: alpha) - } - - func isSimilar(to otherColor: NSColor, threshold: CGFloat) -> Bool { - var h1: CGFloat = 0, s1: CGFloat = 0, b1: CGFloat = 0, a1: CGFloat = 0 - var h2: CGFloat = 0, s2: CGFloat = 0, b2: CGFloat = 0, a2: CGFloat = 0 - self.getHue(&h1, saturation: &s1, brightness: &b1, alpha: &a1) - otherColor.getHue(&h2, saturation: &s2, brightness: &b2, alpha: &a2) - let brightnessDiff = abs(b1 - b2) - let hueDiff = abs(h1 - h2) - return brightnessDiff < threshold && hueDiff < threshold - } - - func madeDistinct() -> NSColor { - var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 - self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) - let newBrightness = min(brightness + 0.15, 1.0) - let newSaturation = max(saturation - 0.15, 0.0) - return NSColor(hue: hue, saturation: newSaturation, brightness: newBrightness, alpha: alpha) - } - - func saturated(by percentage: CGFloat) -> NSColor { - var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 - self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) - let newSaturation = min(saturation + percentage, 1.0) - return NSColor(hue: hue, saturation: newSaturation, brightness: brightness, alpha: alpha) - } - - func withMinimumBrightness(_ minBrightness: CGFloat) -> NSColor { - var hue: CGFloat = 0, saturation: CGFloat = 0, brightness: CGFloat = 0, alpha: CGFloat = 0 - self.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha) - if brightness < minBrightness { - return NSColor(hue: hue, saturation: saturation, brightness: minBrightness, alpha: alpha) - } - return self - } -} - - - - - - - - - -enum PickerResult { - case success(SCContentFilter) - case failure(Error?) -} - - -class ContentPickerHelper: NSObject, ObservableObject, SCContentSharingPickerObserver { - - - let pickerResultPublisher = PassthroughSubject() - - override init() { - super.init() - } - - deinit { - } - - func showPicker() { - let picker = SCContentSharingPicker.shared - picker.add(self) - picker.isActive = true - picker.present() - } - - - - - - - func contentSharingPicker(_ picker: SCContentSharingPicker, didUpdateWith filter: SCContentFilter, for stream: SCStream?) { - SCContentSharingPicker.shared.remove(self) - DispatchQueue.main.async { - self.pickerResultPublisher.send(.success(filter)) - } - } - - - func contentSharingPicker(_ picker: SCContentSharingPicker, didCancelFor stream: SCStream?) { - SCContentSharingPicker.shared.remove(self) - DispatchQueue.main.async { - self.pickerResultPublisher.send(.failure(nil)) - } - } - - - func contentSharingPickerStartDidFailWithError(_ error: Error) { - SCContentSharingPicker.shared.remove(self) - DispatchQueue.main.async { - self.pickerResultPublisher.send(.failure(error)) - } - } -} diff --git a/submissions/sapphire/Sapphire/Utilities/Helpers.swift b/submissions/sapphire/Sapphire/Utilities/Helpers.swift deleted file mode 100644 index 2ccdb249..00000000 --- a/submissions/sapphire/Sapphire/Utilities/Helpers.swift +++ /dev/null @@ -1,99 +0,0 @@ -// -// Helpers.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import Foundation -import SwiftUI -import AppKit - - -public class Debouncer { - private let delay: TimeInterval - private var workItem: DispatchWorkItem? - private let queue: DispatchQueue - - public init(delay: TimeInterval, queue: DispatchQueue = .main) { - self.delay = delay - self.queue = queue - } - - - public func debounce(action: @escaping (() -> Void)) { - workItem?.cancel() - let newWorkItem = DispatchWorkItem(block: action) - workItem = newWorkItem - queue.asyncAfter(deadline: .now() + delay, execute: newWorkItem) - } - - - public func cancel() { - workItem?.cancel() - } -} - - -struct SizeLoggingViewModifier: ViewModifier { - let label: String - func body(content: Content) -> some View { - content - .background( - GeometryReader { geometry in - Color.clear - .onAppear { - } - .onChange(of: geometry.size) { newSize in - } - } - ) - } -} - - -struct HapticManager { - static func perform(_ pattern: NSHapticFeedbackManager.FeedbackPattern) { - NSHapticFeedbackManager.defaultPerformer.perform(pattern, performanceTime: .now) - } -} - -struct BlurButtonStyle: ButtonStyle { - func makeBody(configuration: Configuration) -> some View { - configuration.label - .blur(radius: configuration.isPressed ? 4 : 0) - .scaleEffect(configuration.isPressed ? 0.9 : 1.0) - .opacity(configuration.isPressed ? 0.8 : 1.0) - .animation(.spring(response: 0.35, dampingFraction: 0.5), value: configuration.isPressed) - } -} - -struct InteractiveProgressBar: View { - @Binding var value: Double - var gradient: Gradient - var onSeek: (Double) -> Void - @State private var isDragging = false - @State private var dragValue: Double = 0.0 - - var body: some View { - GeometryReader { geometry in - ZStack(alignment: .leading) { - Rectangle().fill(Color.secondary.opacity(0.3)).frame(height: 10) - Rectangle().fill(LinearGradient(gradient: gradient, startPoint: .leading, endPoint: .trailing)).frame(width: geometry.size.width * CGFloat(isDragging ? dragValue : value), height: 10) - } - .clipShape(Capsule()) - .position(x: geometry.size.width / 2, y: geometry.size.height / 2) - .contentShape(Rectangle()) - .gesture(DragGesture(minimumDistance: 0).onChanged { gestureValue in - if !isDragging { isDragging = true; dragValue = value } - let newProgress = min(max(0, gestureValue.location.x / geometry.size.width), 1) - self.dragValue = newProgress - }.onEnded { gestureValue in - let finalProgress = min(max(0, gestureValue.location.x / geometry.size.width), 1) - onSeek(finalProgress) - isDragging = false - }) - .animation(isDragging ? .none : .linear(duration: 0.5), value: value) - } - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift deleted file mode 100644 index 7dcd10c8..00000000 --- a/submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift +++ /dev/null @@ -1,170 +0,0 @@ -// -// CalendarWidgetView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import SwiftUI - - -struct CenterDateInfo: Equatable { - let date: Date - let distance: CGFloat -} -struct CenterDatePreferenceKey: PreferenceKey { - typealias Value = CenterDateInfo? - static var defaultValue: Value = nil - static func reduce(value: inout Value, nextValue: () -> Value) { - guard let next = nextValue() else { return } - if value == nil || next.distance < value!.distance { - value = next - } - } -} - - -@available(macOS 14.0, *) -struct CalendarWidgetView: View { - @StateObject private var viewModel = InteractiveCalendarViewModel() - - var body: some View { - HStack(alignment: .top, spacing: 10) { - Text(viewModel.selectedMonthAbbreviated) - .font(.system(size: 28, weight: .bold, design: .rounded)) - .lineLimit(1) - .minimumScaleFactor(0.6) - .frame(width: 55, alignment: .leading) - .padding(.top, 4) - .id("Month-\(viewModel.selectedMonthAbbreviated)") - .transition(.asymmetric( - insertion: .opacity.combined(with: .offset(y: -10)), - removal: .opacity.combined(with: .offset(y: 10)) - )) - - VStack(alignment: .leading, spacing: 8) { - interactiveCalendar() - eventsView - } - } - .padding(.horizontal, 12) - .padding(.vertical, 10) - .frame(width: 240, height: 100) - .clipShape(RoundedRectangle(cornerRadius: 30, style: .continuous)) - .foregroundColor(.white) - .environmentObject(viewModel) - } - - private func interactiveCalendar() -> some View { - ScrollViewReader { proxy in - GeometryReader { containerProxy in - let itemWidth: CGFloat = 28 - let itemSpacing: CGFloat = 10 - let horizontalPadding = (containerProxy.size.width / 2) - (itemWidth / 2) - - ScrollView(.horizontal, showsIndicators: false) { - LazyHStack(spacing: itemSpacing) { - ForEach(viewModel.dates, id: \.self) { date in - DynamicDayView( - date: date, - containerMidX: containerProxy.frame(in: .global).midX - ) - .id(date) - .onTapGesture { - - HapticManager.perform(.generic) - - withAnimation(.spring(response: 0.3, dampingFraction: 0.75)) { - viewModel.selectDate(date) - proxy.scrollTo(date, anchor: .center) - } - } - } - } - .padding(.horizontal, horizontalPadding) - } - .onPreferenceChange(CenterDatePreferenceKey.self) { centerInfo in - if let newDate = centerInfo?.date, !newDate.isSameDay(as: viewModel.selectedDate) { - - HapticManager.perform(.alignment) - - withAnimation(.easeInOut(duration: 0.1)) { - viewModel.selectDate(newDate) - } - } - } - .onAppear { - proxy.scrollTo(viewModel.today, anchor: .center) - } - } - .frame(height: 38) - } - } - - private var eventsView: some View { - HStack(spacing: 6) { - Image(systemName: "calendar.badge.checkmark") - .font(.system(size: 12)) - .foregroundColor(.gray) - Text("Nothing for today") - .font(.system(size: 13, weight: .medium)) - .foregroundColor(.gray) - } - .frame(maxWidth: .infinity) - } -} - - - -struct DynamicDayView: View { - let date: Date - let containerMidX: CGFloat - - @EnvironmentObject private var viewModel: InteractiveCalendarViewModel - - var body: some View { - let isSelected = date.isSameDay(as: viewModel.selectedDate) - let dayName = date.format(as: isSelected ? "EEE" : "EEEEE").uppercased() - - GeometryReader { itemProxy in - let itemMidX = itemProxy.frame(in: .global).midX - let distance = itemMidX - containerMidX - - let absDistance = abs(distance) - let focusFactor = max(0, 1 - (absDistance / 80)) - - let scale = 0.7 + (focusFactor * 0.7) - let opacity = 0.5 + (focusFactor * 0.5) - let blur = (1 - focusFactor) * 1.5 - let rotationAngle = Angle.degrees(Double(distance / 10)) - - let baseColor = date.isWeekend ? Color.red.opacity(0.8) : Color.white.opacity(0.8) - let finalColor = baseColor.lerp(to: .blue, t: focusFactor) - let dayLetterColor = Color.gray.lerp(to: .blue, t: focusFactor) - - VStack(spacing: 3) { - Text(dayName) - .font(.system(size: 10, weight: .semibold, design: .rounded)) - .foregroundColor(dayLetterColor) - .id(dayName) - .transition( - .asymmetric( - insertion: .offset(y: 10).combined(with: .opacity), - removal: .offset(y: -10).combined(with: .opacity) - ) - ) - - Text(date.format(as: "d")) - .font(.system(size: 13, weight: .bold, design: .rounded)) - .foregroundColor(finalColor) - } - .scaleEffect(scale) - .blur(radius: blur) - .opacity(opacity) - .rotation3DEffect(rotationAngle, axis: (x: 0, y: 1, z: 0), perspective: 0.5) - .frame(width: itemProxy.size.width, height: itemProxy.size.height) - .preference(key: CenterDatePreferenceKey.self, value: CenterDateInfo(date: date, distance: absDistance)) - } - .frame(width: 28) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift b/submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift deleted file mode 100644 index 51d079df..00000000 --- a/submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// ScrollOffsetPreferenceKey.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import SwiftUI - - -struct DayFrame: Equatable { - let id: Date - let frame: CGRect -} - - -struct DayFramesPreferenceKey: PreferenceKey { - static var defaultValue: [DayFrame] = [] - - static func reduce(value: inout [DayFrame], nextValue: () -> [DayFrame]) { - value.append(contentsOf: nextValue()) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift deleted file mode 100644 index 351ce439..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift +++ /dev/null @@ -1,126 +0,0 @@ -// -// LyricsView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import SwiftUI - - -struct LyricLineView: View { - let lyric: LyricLine - let isCurrent: Bool - let accentColor: Color - - var body: some View { - VStack(alignment: .center, spacing: 6) { - Text(lyric.text) - .font(.system(size: 26, weight: .bold)) - .multilineTextAlignment(.center) - .foregroundColor(isCurrent ? accentColor : .primary) - .shadow(radius: 5) - - if let translated = lyric.translatedText, !translated.isEmpty { - Text(translated) - .font(.system(size: 18, weight: .medium)) - .multilineTextAlignment(.center) - .foregroundColor(isCurrent ? accentColor : .secondary) - .opacity(isCurrent ? 0.8 : 0.6) - } - } - .scaleEffect(isCurrent ? 1.0 : 0.90) - .opacity(isCurrent ? 1.0 : 0.5) - .animation(.spring(response: 0.6, dampingFraction: 0.7), value: isCurrent) - } -} - - -struct LyricsView: View { - - var lyrics: [LyricLine] - var currentLyricID: UUID? - var accentColor: Color - var onDismiss: () -> Void - - - private let lineSpacing: CGFloat = 70.0 - - - var body: some View { - GeometryReader { geometry in - let computedOffset = calculateScrollOffset(fullViewHeight: geometry.size.height) - - ZStack(alignment: .top) { - if lyrics.isEmpty { - emptyLyricsView - .frame(maxWidth: .infinity, maxHeight: .infinity) - } else { - VStack(spacing: 0) { - ForEach(lyrics) { lyric in - LyricLineView( - lyric: lyric, - isCurrent: lyric.id == currentLyricID, - accentColor: accentColor - ) - .frame(height: lineSpacing) - } - } - .frame(width: geometry.size.width) - .offset(y: computedOffset) - .animation(.spring(response: 0.8, dampingFraction: 0.8), value: computedOffset) - } - } - .mask { - - let viewHeight = geometry.size.height - - if viewHeight > 0 { - let fadeLength: CGFloat = 5 - let fadePercentage = fadeLength / viewHeight - - let solidStartLocation = min(fadePercentage, 0.5) - let solidEndLocation = max(1.0 - fadePercentage, 0.5) - - LinearGradient( - gradient: Gradient(stops: [ - - .init(color: .clear, location: 0.0), - - .init(color: .black, location: solidStartLocation), - - .init(color: .black, location: solidEndLocation), - - .init(color: .clear, location: 1.0) - ]), - startPoint: .top, - endPoint: .bottom - ) - } else { - Color.black - } - } - } - .frame(width: 400) - .onTapGesture(perform: onDismiss) - } - - - - private func calculateScrollOffset(fullViewHeight: CGFloat) -> CGFloat { - guard let currentIndex = lyrics.firstIndex(where: { $0.id == currentLyricID }) else { - let totalContentHeight = CGFloat(lyrics.count) * lineSpacing - return (fullViewHeight - totalContentHeight) / 2 - } - - let targetOffset = (fullViewHeight / 2) - (lineSpacing / 2) - (CGFloat(currentIndex) * lineSpacing) - return targetOffset - } - - - private var emptyLyricsView: some View { - Text("No lyrics available.") - .font(.headline) - .foregroundColor(.secondary) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift deleted file mode 100644 index a9d41e55..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift +++ /dev/null @@ -1,157 +0,0 @@ -// -// MusicPlayerView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import SwiftUI -import AppKit - -struct MusicPlayerView: View { - @Binding var mode: NotchWidgetMode - @EnvironmentObject var musicWidget: MusicWidget - @EnvironmentObject var spotifyManager: SpotifyAPIManager - - @EnvironmentObject var liveActivityManager: LiveActivityManager - - private enum ActiveView { - case player, loginPrompt, queueAndPlaylists, devices, lyrics - } - @State private var activeView: ActiveView = .player - - - @State private var showLyrics: Bool = false - - - var body: some View { - ZStack(alignment: .topLeading) { - - ZStack { - switch activeView { - case .player: - playerView - .transition(.asymmetric( - insertion: .move(edge: .leading).combined(with: .opacity), - removal: .move(edge: .trailing).combined(with: .opacity)) - ) - case .loginPrompt: - LoginPromptView(onDismiss: { dismissSubView() }) - .transition(.asymmetric( - insertion: .scale(scale: 0.9).combined(with: .opacity), - removal: .scale(scale: 0.9).combined(with: .opacity)) - ) - case .queueAndPlaylists: - QueueAndPlaylistsView(onDismiss: { dismissSubView() }) - .transition(.asymmetric( - insertion: .move(edge: .trailing).combined(with: .opacity), - removal: .move(edge: .leading).combined(with: .opacity)) - ) - case .devices: - DevicesView(onDismiss: { dismissSubView() }) - .transition(.asymmetric( - insertion: .move(edge: .trailing).combined(with: .opacity), - removal: .move(edge: .leading).combined(with: .opacity)) - ) - - case .lyrics: - LyricsView( - lyrics: musicWidget.lyrics, - currentLyricID: musicWidget.currentLyric?.id, - accentColor: musicWidget.accentColor, - onDismiss: { dismissSubView() } - ) - .transition(.asymmetric( - insertion: .scale(scale: 1.05).combined(with: .opacity), - removal: .scale(scale: 0.9).combined(with: .opacity)) - ) - } - } - .id(activeView) - .animation(.spring(response: 0.4, dampingFraction: 0.8), value: activeView) - } - - .onAppear { - liveActivityManager.showLyricsBinding = $showLyrics - } - .onChange(of: showLyrics) { shouldShow in - if shouldShow { - activeView = .lyrics - - showLyrics = false - } - } - } - - - private var playerView: some View { - VStack(spacing: 3) { - HStack(spacing: 12) { - Image(nsImage: musicWidget.artwork ?? NSImage(systemSymbolName: "waveform", accessibilityDescription: "Album art")!) - .resizable().aspectRatio(contentMode: .fit).frame(width: 60, height: 60) - .cornerRadius(8).shadow(color: musicWidget.accentColor.opacity(0.7), radius: 5) - VStack(alignment: .leading, spacing: 3) { - Text(musicWidget.title ?? "Title").font(.system(size: 16, weight: .semibold)).lineLimit(1) - Text(musicWidget.artist ?? "Artist").font(.system(size: 13)).foregroundColor(.secondary).lineLimit(1) - } - Spacer() - WaveformView().environmentObject(musicWidget).scaleEffect(1.3) - } - - HStack(alignment: .center, spacing: 8) { - Text(formatTime(musicWidget.currentElapsedTime)) - InteractiveProgressBar( - value: $musicWidget.playbackProgress, - gradient: Gradient(colors: [musicWidget.leftGradientColor, musicWidget.rightGradientColor]), - onSeek: { [musicWidget] newProgress in - let seekTime = newProgress * musicWidget.totalDuration - if seekTime.isFinite && musicWidget.totalDuration > 0 { musicWidget.seek(to: seekTime) } - } - ).frame(height: 30).shadow(color: musicWidget.accentColor.opacity(0.5), radius: 8, y: 3) - Text("-\(formatTime(musicWidget.totalDuration - musicWidget.currentElapsedTime))") - }.font(.system(size: 10, weight: .medium, design: .monospaced)).foregroundColor(.secondary) - - - if let lyricText = (musicWidget.currentLyric?.translatedText ?? musicWidget.currentLyric?.text), - !lyricText.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { - Text(lyricText).font(.system(size: 12, weight: .medium)).foregroundColor(musicWidget.accentColor) - .multilineTextAlignment(.center).lineLimit(2).frame(minHeight: 35, alignment: .center) - .transition(.opacity.animation(.easeInOut(duration: 0.3))).id(musicWidget.currentLyric?.id) - .contentShape(Rectangle()) - .onTapGesture { - - activeView = .lyrics - } - } - - HStack { - Button(action: { handleButtonTap(for: .queueAndPlaylists) }) { Image(systemName: "list.bullet").font(.system(size: 20)) }.foregroundColor(.secondary).frame(width: 40, height: 40).contentShape(Rectangle()) - Spacer() - Button(action: { musicWidget.previousTrack() }) { Image(systemName: "backward.fill") }.frame(width: 44, height: 44).contentShape(Rectangle()) - Spacer() - Button(action: { musicWidget.isPlaying ? musicWidget.pause() : musicWidget.play() }) { Image(systemName: musicWidget.isPlaying ? "pause.fill" : "play.fill").font(.system(size: 28)) }.frame(width: 44, height: 44).contentShape(Rectangle()) - Spacer() - Button(action: { musicWidget.nextTrack() }) { Image(systemName: "forward.fill") }.frame(width: 44, height: 44).contentShape(Rectangle()) - Spacer() - Button(action: { handleButtonTap(for: .devices) }) { Image(systemName: "hifispeaker").font(.system(size: 18)) }.foregroundColor(.secondary).frame(width: 40, height: 40).contentShape(Rectangle()) - }.buttonStyle(BlurButtonStyle()).font(.system(size: 22)).foregroundColor(.primary) - .padding(.top, musicWidget.currentLyric == nil ? 10 : 0) - .padding(.bottom, musicWidget.currentLyric == nil ? 5 : 0) - } - .frame(width: 400).padding(10) - .animation(.easeInOut(duration: 0.3), value: musicWidget.currentLyric) - } - - - private func handleButtonTap(for view: ActiveView) { - if spotifyManager.isAuthenticated { activeView = view } - else { activeView = .loginPrompt } - } - - private func dismissSubView() { activeView = .player } - private func formatTime(_ seconds: Double) -> String { - let cleanSeconds = seconds.isNaN || seconds.isInfinite ? 0 : seconds - let (minutes, seconds) = (Int(cleanSeconds) / 60, Int(cleanSeconds) % 60) - return String(format: "%d:%02d", minutes, seconds) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift deleted file mode 100644 index 864c6eda..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift +++ /dev/null @@ -1,150 +0,0 @@ -// -// MusicWidgetView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import SwiftUI -import AppKit - -struct MusicWidgetView: View { - @EnvironmentObject var musicWidget: MusicWidget - @EnvironmentObject var settings: SettingsModel - @Binding var mode: NotchWidgetMode - @State private var isHoveringArtwork = false - - var body: some View { - - if let title = musicWidget.title, !title.isEmpty { - - HStack(alignment: .center, spacing: 16) { - albumArtWithOverlay - - VStack(alignment: .leading, spacing: 8) { - MusicInfoView( - title: musicWidget.title, - album: musicWidget.album, - artist: musicWidget.artist - ) - - MusicControlsView( - isPlaying: musicWidget.isPlaying, - onPrevious: musicWidget.previousTrack, - onPlayPause: { musicWidget.isPlaying ? musicWidget.pause() : musicWidget.play() }, - onNext: musicWidget.nextTrack - ) - } - .frame(maxWidth: .infinity, alignment: .leading) - } - .frame(height: 100) - .frame(maxWidth: 300) - .fixedSize() - } else { - - OpenPlayerView( - player: settings.settings.defaultMusicPlayer, - action: openDefaultPlayer - ) - } - } - - private var albumArtWithOverlay: some View { - Image(nsImage: musicWidget.artwork ?? NSImage(systemSymbolName: "waveform", accessibilityDescription: "Album art")!) - .resizable().aspectRatio(contentMode: .fill) - .frame(width: 100, height: 100).cornerRadius(30) - .shadow(color: musicWidget.accentColor.opacity(0.7), radius: 8, y: 5) - .overlay(alignment: .bottomLeading) { - if let icon = musicWidget.appIcon { - Image(nsImage: icon).resizable().aspectRatio(contentMode: .fit) - .frame(width: 22, height: 22).clipShape(Circle()).padding(6) - } - } - .onHover { hovering in - self.isHoveringArtwork = hovering - if hovering { HapticManager.perform(.alignment) } - } - .onTapGesture { mode = .musicPlayer } - } - - - private func openDefaultPlayer() { - let player = settings.settings.defaultMusicPlayer - let bundleId = player == .appleMusic ? "com.apple.Music" : "com.spotify.client" - NSWorkspace.shared.launchApplication(bundleId) - } -} - - -private struct OpenPlayerView: View { - let player: DefaultMusicPlayer - let action: () -> Void - - var body: some View { - VStack(spacing: 12) { - Image(systemName: "music.note") - .font(.system(size: 40, weight: .light)) - .foregroundColor(.white.opacity(0.8)) - - Button(action: action) { - Text("Open \(player.displayName)") - .font(.system(size: 14, weight: .medium)) - .foregroundColor(.white) - .padding(.horizontal, 16) - .padding(.vertical, 8) - .background(Color.white.opacity(0.15)) - .clipShape(Capsule()) - } - .buttonStyle(.plain) - } - .frame(width: 300, height: 100) - } -} - - -private struct MusicInfoView: View { - let title: String? - let album: String? - let artist: String? - - var body: some View { - VStack(alignment: .leading, spacing: 4) { - if let title = title, !title.isEmpty { - Text(title) - .font(.system(size: 17, weight: .semibold)) - } - - if let album = album, !album.isEmpty, album != title { - Text(album) - .font(.system(size: 14, weight: .medium)) - } - if let artist = artist, !artist.isEmpty { - Text(artist) - .font(.system(size: 13, weight: .regular)) - .foregroundColor(.white.opacity(0.7)) - } - } - .foregroundStyle(.white) - .lineLimit(1) - .minimumScaleFactor(0.8) - } -} - - -private struct MusicControlsView: View { - let isPlaying: Bool - let onPrevious: () -> Void - let onPlayPause: () -> Void - let onNext: () -> Void - - var body: some View { - HStack(spacing: 18) { - Button(action: onPrevious) { Image(systemName: "backward.end.fill") } - Button(action: onPlayPause) { Image(systemName: isPlaying ? "pause.fill" : "play.fill").font(.system(size: 20, weight: .semibold)) } - Button(action: onNext) { Image(systemName: "forward.end.fill") } - } - .buttonStyle(BlurButtonStyle()) - .font(.system(size: 16)) - .foregroundColor(.white) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift deleted file mode 100644 index b1d65e14..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift +++ /dev/null @@ -1,127 +0,0 @@ -// -// DevicesView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import SwiftUI - -struct DevicesView: View { - var onDismiss: () -> Void - @EnvironmentObject var spotifyManager: SpotifyAPIManager - - @State private var devices: [SpotifyDevice] = [] - @State private var isLoading = true - @State private var volume: Double = 75 - @State private var debouncer = Debouncer(delay: 0.2) - - var body: some View { - VStack(spacing: 15) { - - - if isLoading { - ProgressView().frame(maxHeight: .infinity) - } else if spotifyManager.isPremiumUser { - premiumUserView - } else { - freeUserView - } - } - .padding(20).onAppear { Task { await fetchInitialData() } } - } - - private var premiumUserView: some View { - VStack { - if devices.contains(where: { $0.isActive }) { - VolumeControl(volume: $volume) - .onChange(of: volume) { newValue in - debouncer.debounce { Task { _ = await spotifyManager.setVolume(percent: Int(newValue)) } } - } - } - ScrollView { - VStack(spacing: 8) { - ForEach(devices) { device in - DeviceRow(device: device, isActive: device.isActive) - .onTapGesture { - guard !device.isActive, let deviceId = device.id else { return } - Task { _ = await spotifyManager.transferPlayback(to: deviceId); await fetchInitialData() } - } - } - } - } - } - } - - private var freeUserView: some View { - VStack(spacing: 20) { - Text("Local Volume Control").font(.headline) - VolumeControl(volume: $volume) - .onChange(of: volume) { newValue in - debouncer.debounce { Task { _ = await spotifyManager.setVolume(percent: Int(newValue)) } } - } - VStack(spacing: 8) { - Image(systemName: "exclamationmark.lock.fill").font(.largeTitle).foregroundColor(.yellow) - Text("Device Switching Requires Premium").font(.headline) - Text("You can control the volume of your local Spotify app. To switch playback to other devices, a Premium account is required.").font(.subheadline).foregroundColor(.secondary).multilineTextAlignment(.center) - }.padding().background(.thinMaterial).cornerRadius(16) - Spacer() - } - } - - private func fetchInitialData() async { - if spotifyManager.isPremiumUser { - let allDevices = await spotifyManager.fetchDevices() - let playbackState = await spotifyManager.fetchPlaybackState() - await MainActor.run { - self.devices = allDevices - if let currentVolume = playbackState?.device.volumePercent { self.volume = Double(currentVolume) } - self.isLoading = false - } - } else { - if let localVolume = spotifyManager.getLocalVolume() { await MainActor.run { self.volume = Double(localVolume) } } - await MainActor.run { self.isLoading = false } - } - } -} - - - -struct VolumeControl: View { - @Binding var volume: Double - var body: some View { - HStack(spacing: 10) { - Image(systemName: volume < 1 ? "speaker.slash.fill" : "speaker.wave.1.fill") - Slider(value: $volume, in: 0...100) - Image(systemName: volume > 66 ? "speaker.wave.3.fill" : "speaker.wave.2.fill") - } - .foregroundColor(.secondary).padding().background(.ultraThinMaterial).cornerRadius(16) - } -} - -struct DeviceRow: View { - let device: SpotifyDevice - let isActive: Bool - - var body: some View { - HStack { - Image(systemName: iconName(for: device.type)).font(.title2).frame(width: 30).foregroundColor(isActive ? .green : .primary) - Text(device.name).fontWeight(isActive ? .semibold : .regular) - Spacer() - if isActive { Image(systemName: "speaker.wave.2.fill").foregroundColor(.green) } - } - .padding().background(.thinMaterial).cornerRadius(12) - .overlay(RoundedRectangle(cornerRadius: 12).stroke(isActive ? Color.green.opacity(0.7) : Color.secondary.opacity(0.2), lineWidth: 1.5)) - .scaleEffect(isActive ? 1.0 : 0.98).animation(.spring(response: 0.4, dampingFraction: 0.6), value: isActive) - } - - private func iconName(for type: String) -> String { - switch type.lowercased() { - case "computer": return "desktopcomputer" - case "speaker": return "hifispeaker.2.fill" - case "smartphone": return "iphone" - case "avr", "stb": return "tv.inset.filled" - default: return "questionmark.circle" - } - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift deleted file mode 100644 index 6f5663bd..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift +++ /dev/null @@ -1,34 +0,0 @@ -// -// LoginPromptView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import SwiftUI - -struct LoginPromptView: View { - var onDismiss: () -> Void - - var body: some View { - VStack(spacing: 20) { - Image("spotify-logo") - .resizable().aspectRatio(contentMode: .fit).frame(width: 80) - - Text("Connect to Spotify") - .font(.title2).bold() - - Text("Log in to control playback, see your queue, and manage devices.") - .font(.subheadline).foregroundColor(.secondary).multilineTextAlignment(.center) - - Button("Log in with Spotify") { - SpotifyAPIManager.shared.login() - } - .buttonStyle(.borderedProminent).tint(.green) - - Button("Not Now", action: onDismiss) - .buttonStyle(.plain).foregroundColor(.secondary) - } - .padding(30) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift deleted file mode 100644 index 14a06f3b..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift +++ /dev/null @@ -1,112 +0,0 @@ -// -// PlaylistView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import SwiftUI - -struct PlaylistView: View { - - var onDismiss: () -> Void - var onSelectPlaylist: (SpotifyPlaylist) -> Void - - - @State private var playlists: [SpotifyPlaylist] = [] - @State private var isLoading = true - - var body: some View { - VStack(spacing: 0) { - - HStack { - Text("Your Playlists") - .font(.system(size: 18, weight: .bold)) - Spacer() - Button(action: onDismiss) { - Image(systemName: "xmark.circle.fill") - .font(.title2) - .foregroundStyle(.secondary, .tertiary) - } - .buttonStyle(PlainButtonStyle()) - } - .padding([.top, .horizontal], 20) - .padding(.bottom, 15) - - - ZStack { - if isLoading { - ProgressView() - .progressViewStyle(CircularProgressViewStyle()) - .scaleEffect(1.5) - .frame(maxHeight: .infinity) - } else if playlists.isEmpty { - Text("No playlists found.") - .foregroundColor(.secondary) - .frame(maxHeight: .infinity) - } else { - - ScrollView { - LazyVStack(spacing: 12) { - ForEach(playlists) { playlist in - PlaylistRow(playlist: playlist) - .onTapGesture { - onSelectPlaylist(playlist) - } - } - } - .padding(.horizontal, 20) - .padding(.bottom, 20) - } - } - } - } - .onAppear(perform: fetchPlaylists) - } - - private func fetchPlaylists() { - Task { - - let fetchedPlaylists = await SpotifyAPIManager.shared.fetchPlaylists() - - - await MainActor.run { - self.playlists = fetchedPlaylists - self.isLoading = false - } - } - } -} - - -struct PlaylistRow: View { - let playlist: SpotifyPlaylist - - var body: some View { - HStack(spacing: 12) { - - - ZStack { - Color.secondary.opacity(0.3) - Image(systemName: "music.note.list") - .font(.title2) - .foregroundColor(.white.opacity(0.8)) - } - .frame(width: 50, height: 50) - .cornerRadius(6) - - VStack(alignment: .leading, spacing: 3) { - Text(playlist.name) - .font(.system(size: 15, weight: .semibold)) - .lineLimit(1) - Text("By \(playlist.owner.displayName)") - .font(.system(size: 12)) - .foregroundColor(.secondary) - .lineLimit(1) - } - } - .padding(8) - .background(Color.white.opacity(0.05)) - .cornerRadius(10) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift deleted file mode 100644 index fa489ad8..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift +++ /dev/null @@ -1,218 +0,0 @@ -// -// QueueAndPlaylistsView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import SwiftUI - - -struct CustomUnavailableView: View { - let title: String - let systemImage: String - var description: String? = nil - - var body: some View { - VStack(spacing: 12) { - Image(systemName: systemImage).font(.largeTitle).foregroundColor(.secondary.opacity(0.7)) - Text(title).font(.headline).foregroundColor(.primary) - if let description = description { - Text(description).font(.subheadline).foregroundColor(.secondary).multilineTextAlignment(.center).padding(.horizontal) - } - }.frame(maxHeight: .infinity) - } -} - - -struct QueueAndPlaylistsView: View { - var onDismiss: () -> Void - @State private var selection: Int = 0 - @State private var queue: SpotifyQueue? - @State private var playlists: [SpotifyPlaylist] = [] - @State private var isLoading = true - @State private var showSpotifyNotOpenAlert = false - - var body: some View { - VStack(spacing: 15) { - - HStack { - Button(action: onDismiss) { Image(systemName: "chevron.left"); Text("Back") } - .buttonStyle(.plain).foregroundColor(.secondary) - Spacer() - }.font(.system(size: 18)) - - - HStack(spacing: 10) { - TabButton(title: "Queue", systemImage: "list.bullet.rectangle", isSelected: selection == 0) { selection = 0 } - TabButton(title: "Playlists", systemImage: "music.note.list", isSelected: selection == 1) { selection = 1 } - } - - - if isLoading { - ProgressView().frame(maxHeight: .infinity) - } else { - if selection == 0 { queueView } - else { playlistsView } - } - - - } - .padding(20) - .onAppear(perform: fetchData) - .alert("Spotify App Is Not Open", isPresented: $showSpotifyNotOpenAlert) { - Button("OK", role: .cancel) { } - } message: { - Text("To control playback with a free account, please open the Spotify desktop app first.") - } - } - - private func fetchData() { - Task { - async let queueData = SpotifyAPIManager.shared.fetchQueue() - async let playlistsData = SpotifyAPIManager.shared.fetchPlaylists() - self.queue = await queueData - self.playlists = await playlistsData - self.isLoading = false - } - } - - - - private var queueView: some View { - ScrollView { - if let queue = queue, let nowPlaying = queue.currentlyPlaying { - VStack(alignment: .leading, spacing: 18) { - SectionHeader(title: "Now Playing") - QueueTrackRow(track: nowPlaying, onPlay: handlePlaybackResult) - - if !queue.queue.isEmpty { - SectionHeader(title: "Next Up") - ForEach(queue.queue) { track in - QueueTrackRow(track: track, onPlay: handlePlaybackResult) - } - } else { - CustomUnavailableView(title: "No Songs Up Next", systemImage: "music.note.list", description: "Add songs to your queue in the Spotify app to see them here.").padding(.top, 20) - } - } - } else { - CustomUnavailableView(title: "Queue Unavailable", systemImage: "speaker.slash.fill", description: "Start playing music in Spotify and ensure you have a Premium account to view your queue.") - } - } - } - - private var playlistsView: some View { - ScrollView { - if !playlists.isEmpty { - VStack(spacing: 10) { - ForEach(playlists) { playlist in - FullPlaylistRow(playlist: playlist, onPlay: handlePlaybackResult) - } - } - } else { - CustomUnavailableView(title: "No Playlists Found", systemImage: "music.mic") - } - } - } - - private func handlePlaybackResult(_ result: PlaybackResult) { - switch result { - case .requiresSpotifyAppOpen: - showSpotifyNotOpenAlert = true - default: - break - } - } -} - -struct TabButton: View { - let title: String - let systemImage: String - let isSelected: Bool - let action: () -> Void - - var body: some View { - Button(action: action) { - HStack { - Image(systemName: systemImage) - Text(title) - } - .font(.system(size: 14, weight: .semibold)) - .padding(.horizontal, 16) - .padding(.vertical, 8) - - .contentShape(Capsule()) - } - .buttonStyle(.plain) - .background(isSelected ? Color.accentColor : .clear) - .foregroundColor(isSelected ? .white : .primary) - .clipShape(Capsule()) - .animation(.spring(response: 0.3, dampingFraction: 0.7), value: isSelected) - } -} - -struct SectionHeader: View { - let title: String - var body: some View { Text(title).font(.headline).foregroundColor(.secondary).padding(.leading, 5) } -} - -struct QueueTrackRow: View { - let track: SpotifyTrack - var onPlay: (PlaybackResult) -> Void - @State private var isHovered = false - - var body: some View { - HStack(spacing: 12) { - AsyncImage(url: track.imageURL) { $0.resizable() } placeholder: { ZStack { Color.secondary.opacity(0.3); Image(systemName: "music.note") } } - .frame(width: 45, height: 45).cornerRadius(6) - .overlay( - ZStack { - if isHovered { - Color.black.opacity(0.5) - Image(systemName: "play.fill").font(.title3).foregroundColor(.white) - } - }.cornerRadius(6) - ) - VStack(alignment: .leading) { Text(track.name).fontWeight(.medium).lineLimit(1); Text(track.artists.map(\.name).joined(separator: ", ")).font(.subheadline).foregroundColor(.secondary).lineLimit(1) } - Spacer() - } - .padding(8).background(.thinMaterial).cornerRadius(10) - - .onHover { hovering in - self.isHovered = hovering - } - .onTapGesture { performPlayback() } - - .animation(.easeInOut(duration: 0.15), value: isHovered) - } - - private func performPlayback() { - Task { - let result = await SpotifyAPIManager.shared.playTrack(uri: track.uri) - onPlay(result) - } - } -} - -struct FullPlaylistRow: View { - let playlist: SpotifyPlaylist - var onPlay: (PlaybackResult) -> Void - var body: some View { - HStack(spacing: 12) { - AsyncImage(url: playlist.imageURL) { $0.resizable() } placeholder: { ZStack { Color.secondary.opacity(0.3); Image(systemName: "music.note.list") } } - .frame(width: 45, height: 45).cornerRadius(6) - VStack(alignment: .leading) { Text(playlist.name).fontWeight(.medium).lineLimit(1); Text("By \(playlist.owner.displayName)").font(.subheadline).foregroundColor(.secondary).lineLimit(1) } - Spacer() - Image(systemName: "chevron.right").foregroundColor(.secondary) - } - .padding(8).background(.thinMaterial).cornerRadius(10) - .onTapGesture { performPlayback() } - } - - private func performPlayback() { - Task { - let result = await SpotifyAPIManager.shared.playPlaylist(contextUri: playlist.uri) - onPlay(result) - } - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift b/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift deleted file mode 100644 index ca607fb0..00000000 --- a/submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -// SpotifyPlaybackManager.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import Foundation - - -class SpotifyPlaybackManager { - static let shared = SpotifyPlaybackManager() - - - - private var localPlayer: LibrespotSession? - - init() { - - - self.localPlayer = LibrespotSession() - } - - - func play(trackUri: String) { - let spotifyManager = SpotifyAPIManager.shared - - - if spotifyManager.isPremiumUser { - - - Task { - await spotifyManager.playTrack(uri: trackUri) - } - } else { - - - - - localPlayer?.play(uri: trackUri) - } - } - - - func play(contextUri: String) { - let spotifyManager = SpotifyAPIManager.shared - - if spotifyManager.isPremiumUser { - Task { - await spotifyManager.playPlaylist(contextUri: contextUri) - } - } else { - localPlayer?.play(contextUri: contextUri) - } - } -} - - - -struct LibrespotSession { - func play(uri: String) { - - - - - - - } - - func play(contextUri: String) { - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift b/submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift deleted file mode 100644 index 89b80ee6..00000000 --- a/submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift +++ /dev/null @@ -1,229 +0,0 @@ -// -// NearDropProgressView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-05. -// - -import SwiftUI -import NearbyShare - - - -struct NearDropProgressView: View { - @StateObject private var nearbyManager = NearbyConnectionManager.shared - @EnvironmentObject var liveActivityManager: LiveActivityManager - - - @State private var isShowing = false - - private var allDisplayableTransfers: [TransferProgressInfo] { - let pending = nearbyManager.pendingTransfers.values.sorted { $0.id > $1.id } - let active = nearbyManager.transfers - return pending + active - } - - var body: some View { - VStack(alignment: .leading, spacing: 0) { - HeaderView() - - - - Group { - if allDisplayableTransfers.isEmpty { - EmptyStateView() - .transition(.opacity.combined(with: .scale(scale: 0.95))) - } else { - ScrollView { - - LazyVStack(spacing: 8) { - ForEach(allDisplayableTransfers) { transfer in - ModernTransferRowView(transfer: transfer) - .transition(.opacity) - } - } - .padding(8) - } - .transition(.opacity) - } - } - - .animation(.spring(response: 0.3, dampingFraction: 0.8), value: allDisplayableTransfers.isEmpty) - } - .frame(width: 400) - .frame(maxHeight: 500) - .fixedSize(horizontal: false, vertical: true) - - .background(Color(red: 0.1, green: 0.1, blue: 0.21), in: RoundedRectangle(cornerRadius: 28, style: .continuous)) - .environmentObject(liveActivityManager) - - .scaleEffect(isShowing ? 1 : 0.98) - .opacity(isShowing ? 1 : 0) - .padding(.top, 1) - .onAppear { - withAnimation(.spring(response: 0.4, dampingFraction: 0.7)) { - isShowing = true - } - } - } -} - - - - -private struct HeaderView: View { - var body: some View { - HStack { - Image(privateName: "shareplay") - .font(.system(size: 20, weight: .semibold)) - .foregroundColor(.primary) - - Text("AirDrops") - .font(.headline) - .fontWeight(.bold) - - Spacer() - } - .padding(16) - .background(.black.opacity(0.3)) - - - } -} - -private struct EmptyStateView: View { - var body: some View { - VStack(spacing: 12) { - Image(systemName: "tray") - .font(.system(size: 40, weight: .light)) - .foregroundColor(.secondary) - Text("No Active Transfers") - .font(.headline) - .foregroundColor(.secondary) - } - .frame(maxWidth: .infinity, minHeight: 150) - .padding() - } -} - - - - -private struct ModernTransferRowView: View { - let transfer: TransferProgressInfo - @EnvironmentObject var liveActivityManager: LiveActivityManager - - var body: some View { - HStack(spacing: 12) { - ZStack { - Circle().fill(Color.accentColor.opacity(0.15)) - Image(systemName: transfer.iconName).font(.title3).foregroundColor(.accentColor) - }.frame(width: 44, height: 44) - - VStack(alignment: .leading, spacing: 2) { - Text(transfer.deviceName).font(.callout).fontWeight(.semibold).lineLimit(1) - Text(transfer.fileDescription).font(.caption).foregroundColor(.secondary).lineLimit(1) - } - Spacer(minLength: 8) - - - trailingItem - .animation(.spring(response: 0.3, dampingFraction: 0.8), value: transfer.state) - } - .padding(10) - .background(Color.black.opacity(0.1)) - .clipShape(RoundedRectangle(cornerRadius: 12, style: .continuous)) - } - - @ViewBuilder - private var trailingItem: some View { - - switch transfer.state { - case .waiting: - IntegratedActionIconButtonsView(transfer: transfer) - .environmentObject(liveActivityManager) - .transition(.opacity.combined(with: .scale(scale: 0.9))) - case .inProgress: - CircularProgressIndicator(progress: transfer.progress) - .transition(.opacity.combined(with: .scale(scale: 0.9))) - case .finished: - Image(systemName: "checkmark.circle.fill").font(.title2).foregroundStyle(.green) - .transition(.opacity.combined(with: .scale(scale: 0.9))) - case .failed: - Image(systemName: "xmark.circle.fill").font(.title2).foregroundStyle(.red) - .transition(.opacity.combined(with: .scale(scale: 0.9))) - case .canceled: - Image(systemName: "xmark.circle.fill").font(.title2).foregroundStyle(.secondary) - .transition(.opacity.combined(with: .scale(scale: 0.9))) - } - } -} - - - -private struct IntegratedActionIconButtonsView: View { - let transfer: TransferProgressInfo - @EnvironmentObject var liveActivityManager: LiveActivityManager - - private func submitConsent(accept: Bool, action: NearDropUserAction = .save) { - liveActivityManager.clearNearDropActivity(id: transfer.id) - NearbyConnectionManager.shared.submitUserConsent(transferID: transfer.id, accept: accept, action: action) - } - - var body: some View { - HStack(spacing: 8) { - if transfer.iconName == "link" { - Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) - Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) - Button { submitConsent(accept: true, action: .open) } label: { Image(systemName: "arrow.up.right.square") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: true)) - } else if transfer.iconName == "text.quote" { - Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) - Button { submitConsent(accept: true, action: .copy) } label: { Image(systemName: "doc.on.doc") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) - Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "square.and.arrow.down") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: true)) - } else { - Button { submitConsent(accept: false) } label: { Image(systemName: "xmark") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: false)) - Button { submitConsent(accept: true, action: .save) } label: { Image(systemName: "checkmark") } - .buttonStyle(ModernIconActionButtonStyle(isProminent: true)) - } - } - } -} - -private struct CircularProgressIndicator: View { - let progress: Double - var body: some View { - ZStack { - Circle().stroke(lineWidth: 4.0).opacity(0.2).foregroundColor(.secondary) - Circle().trim(from: 0.0, to: CGFloat(min(self.progress, 1.0))) - .stroke(style: StrokeStyle(lineWidth: 4.0, lineCap: .round, lineJoin: .round)) - .foregroundColor(.accentColor) - .rotationEffect(Angle(degrees: 270.0)) - Text("\(Int(progress * 100))%").font(.caption2).fontWeight(.bold).foregroundColor(.secondary) - } - .frame(width: 36, height: 36) - } -} - - - -private struct ModernIconActionButtonStyle: ButtonStyle { - var isProminent: Bool - - func makeBody(configuration: Configuration) -> some View { - configuration.label - .font(.system(size: 14, weight: .semibold)) - .foregroundColor(isProminent ? .white : .primary) - .frame(width: 32, height: 32) - .background(isProminent ? Color.accentColor : Color.secondary.opacity(0.25)) - .clipShape(Circle()) - .scaleEffect(configuration.isPressed ? 0.9 : 1.0) - .animation(.spring(response: 0.3, dampingFraction: 0.7), value: configuration.isPressed) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift deleted file mode 100644 index e72f1366..00000000 --- a/submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift +++ /dev/null @@ -1,106 +0,0 @@ -// -// NotchWidgetView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-26. -// - -import SwiftUI - -enum NotchWidgetMode { - case defaultWidgets - case musicPlayer - case nearDrop - case weatherPlayer -} - -struct NotchWidgetView: View { - @Binding var mode: NotchWidgetMode - - @StateObject private var settings = SettingsModel() - - @State private var showContent = false - - private var enabledAndOrderedWidgets: [WidgetType] { - let orderedTypes = settings.settings.widgetOrder - - return orderedTypes.filter { widgetType in - switch widgetType { - case .music: - return settings.settings.musicWidgetEnabled - case .weather: - return settings.settings.weatherWidgetEnabled - case .calendar: - return settings.settings.calendarWidgetEnabled - case .shortcuts: - return settings.settings.shortcutsWidgetEnabled - } - } - } - - var body: some View { - Group { - switch mode { - case .defaultWidgets: - AnyView( - HStack(spacing: 0) { - ForEach(enabledAndOrderedWidgets) { widgetType in - widgetView(for: widgetType) - } - } - ) - .blur(radius: showContent ? 0 : 8) - .opacity(showContent ? 1 : 0) - .scaleEffect(showContent ? 1 : 0.98) - - case .musicPlayer: - AnyView( - - MusicPlayerView(mode: $mode) - .environmentObject(settings) - ) - .blur(radius: showContent ? 0 : 8) - .opacity(showContent ? 1 : 0) - - case .nearDrop: - AnyView(NearDropProgressView()) - .blur(radius: showContent ? 0 : 8) - .opacity(showContent ? 1 : 0) - - case .weatherPlayer: - AnyView( - - WeatherPlayerView(mode: $mode) - .environmentObject(settings) - ) - .blur(radius: showContent ? 0 : 8) - .opacity(showContent ? 1 : 0) - } - } - .padding(.top, NotchConfiguration.universalHeight - 10) - .padding(.horizontal, 10) - .onAppear { - withAnimation(.spring(response: 1.0, dampingFraction: 0.8)) { - showContent = true - } - } - .onDisappear { - showContent = false - } - } - - @ViewBuilder - private func widgetView(for widgetType: WidgetType) -> some View { - switch widgetType { - case .music: - MusicWidgetView(mode: $mode) - case .weather: - WeatherWidgetView(mode: $mode) - case .calendar: - CalendarWidgetView() - case .shortcuts: - - EmptyView() - } - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift deleted file mode 100644 index ec0e9498..00000000 --- a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift +++ /dev/null @@ -1,134 +0,0 @@ -// -// WeatherDetailView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI - - - -struct WeatherPlayerView: View { - @StateObject private var viewModel = WeatherViewModel() - @Binding var mode: NotchWidgetMode - - var body: some View { - ZStack(alignment: .topLeading) { - ZStack { - VStack(spacing: 0) { - - currentWeatherAndDetailsSection - .padding(.horizontal, 24) - .padding(.top, 20) - .padding(.bottom, 10) - - - hourlyForecastSection - .padding(.horizontal, 24) - .padding(.bottom, 30) - } - } - .frame(width: 560, height: 240) - .onAppear { - viewModel.fetch() - } - .animation(.spring(response: 0.6, dampingFraction: 1, blendDuration: 0.2), value: viewModel.temperature) - .animation(.easeInOut(duration: 0.8), value: viewModel.gradientColors.first) - - } - } - - private var currentWeatherAndDetailsSection: some View { - HStack(alignment: .top, spacing: 20) { - - Image(systemName: viewModel.iconName) - .font(.system(size: 88, weight: .thin)) - .symbolRenderingMode(.multicolor) - .shadow(color: .black.opacity(0.2), radius: 8, y: 4) - .frame(width: 100, height: 100) - .padding(10) - - - VStack(alignment: .leading, spacing: 4) { - Text(viewModel.locationName) - .font(.title2.weight(.semibold)) - .lineLimit(1) - - Text(viewModel.temperature) - .font(.system(size: 72, weight: .heavy, design: .rounded)) - .lineLimit(1) - .minimumScaleFactor(0.6) - - Text(viewModel.conditionDescription.capitalized) - .font(.title3).fontWeight(.medium) - .lineLimit(1) - - - VStack(alignment: .leading, spacing: 2) { - HStack(spacing: 8) { - Text(viewModel.highLowTemp) - } - .font(.callout).fontWeight(.medium) - .opacity(0.8) - - HStack(spacing: 12) { - HStack(spacing: 4) { - Image(systemName: "thermometer.medium") - .font(.caption) - Text("Feels: \(viewModel.feelsLike)") - } - HStack(spacing: 4) { - Image(systemName: "wind") - .font(.caption) - Text("Wind: \(viewModel.windInfo)") - } - } - .font(.subheadline).fontWeight(.regular) - .opacity(0.7) - } - .padding(.top, 8) - } - Spacer() - } - .frame(maxHeight: .infinity, alignment: .topLeading) - } - - private var hourlyForecastSection: some View { - VStack(alignment: .leading, spacing: 8) { - Text("HOURLY FORECAST") - .font(.caption2.weight(.bold)) - .opacity(0.6) - .kerning(0.5) - .padding(.horizontal, 12) - - HStack(spacing: 18) { - ForEach(viewModel.hourlyForecasts) { forecast in - HourlyForecastCell(forecast: forecast) - } - } - } - .frame(height: 80) - } -} - - - -private struct HourlyForecastCell: View { - let forecast: HourlyForecastUIData - @EnvironmentObject private var settings: SettingsModel - - var body: some View { - VStack(spacing: 4) { - Text(forecast.time) - .font(.caption2).fontWeight(.medium) - .opacity(0.8) - Image(systemName: forecast.iconName) - .font(.title2).symbolRenderingMode(.multicolor) - .frame(height: 28) - Text(settings.settings.weatherUseCelsius ? forecast.temperatureMetric : forecast.temperature) - .font(.subheadline).fontWeight(.semibold) - } - .frame(width: 50) - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift deleted file mode 100644 index ba6f2c70..00000000 --- a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// WeatherIconMapper.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-30. -// - -import Foundation - - -struct WeatherIconMapper { - - - - - static func map(from code: Int) -> String { - switch code { - - case 0: return "tornado" - case 1: return "tropicalstorm" - case 2: return "hurricane" - case 3: return "cloud.bolt.rain.fill" - case 4: return "cloud.bolt.rain.fill" - - - case 5: return "cloud.sleet.fill" - case 6: return "cloud.sleet.fill" - case 7: return "cloud.sleet.fill" - case 8: return "cloud.hail.fill" - case 10: return "thermometer.snowflake" - - - case 9: return "cloud.drizzle.fill" - case 11: return "cloud.rain.fill" - case 12: return "cloud.heavyrain.fill" - case 40: return "cloud.heavyrain.fill" - case 35: return "cloud.hail.fill" - - - case 13: return "cloud.snow.fill" - case 14: return "cloud.snow.fill" - case 15: return "wind.snow" - case 16: return "snowflake" - case 42: return "cloud.snow.fill" - case 43: return "snowflake" - - - case 17: return "cloud.hail.fill" - case 18: return "cloud.sleet.fill" - - - case 19: return "wind" - case 20: return "cloud.fog.fill" - case 21: return "sun.haze.fill" - case 22: return "smoke.fill" - - - case 23: return "wind" - case 24: return "wind" - - - case 25: return "thermometer.snowflake" - - - case 26: return "cloud.fill" - - - case 27: return "cloud.moon.fill" - case 29: return "cloud.moon.fill" - case 31: return "moon.stars.fill" - case 33: return "moon.fill" - - - case 28: return "cloud.sun.fill" - case 30: return "cloud.sun.fill" - case 32: return "sun.max.fill" - case 34: return "sun.min.fill" - - - case 37: return "cloud.sun.bolt.fill" - case 38: return "cloud.sun.rain.fill" - case 39: return "cloud.sun.rain.fill" - case 41: return "cloud.sun.rain.fill" - - - case 45: return "cloud.moon.rain.fill" - case 46: return "cloud.moon.rain.fill" - case 47: return "cloud.moon.bolt.fill" - - - case 36: return "sun.max.trianglebadge.exclamationmark" - - - case 44: return "questionmark.circle" - - default: - return "questionmark.circle" - } - } -} diff --git a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift b/submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift deleted file mode 100644 index 7aed0c88..00000000 --- a/submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift +++ /dev/null @@ -1,97 +0,0 @@ -// -// WeatherWidgetView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-06-27. -// - -import SwiftUI - -struct WeatherWidgetView: View { - @StateObject private var viewModel = WeatherViewModel() - @Binding var mode: NotchWidgetMode - - var body: some View { - Button(action: { - withAnimation(.spring(response: 0.4, dampingFraction: 0.8)) { - mode = .weatherPlayer - } - }) { - HStack(alignment: .center, spacing: 0) { - primaryInfo.layoutPriority(1) - secondaryInfo - } - .frame(width: 250, height: 100) - } - .buttonStyle(.plain) - .onAppear { - viewModel.fetch() - } - } - - private var primaryInfo: some View { - HStack(spacing: 8) { - Image(systemName: viewModel.iconName) - .font(.system(size: 44)) - .symbolRenderingMode(.multicolor) - .shadow(radius: 2) - .minimumScaleFactor(0.8) - .id(viewModel.iconName) - .transition(.opacity) - - VStack(alignment: .leading, spacing: 2) { - Text(viewModel.temperature) - .font(.system(size: 42, weight: .bold, design: .rounded)) - .minimumScaleFactor(0.5) - .id(viewModel.temperature) - .transition(.opacity) - - Text(viewModel.locationName) - .font(.headline).fontWeight(.medium).lineLimit(1).minimumScaleFactor(0.7) - .id(viewModel.locationName) - .transition(.opacity) - - Text(viewModel.conditionDescription) - .font(.subheadline).opacity(0.8).lineLimit(1).minimumScaleFactor(0.7) - .id(viewModel.conditionDescription) - .transition(.opacity) - } - - .animation(.easeInOut(duration: 0.4), value: viewModel.locationName) - } - } - - private var secondaryInfo: some View { - VStack(alignment: .trailing, spacing: 4) { - CompactInfoRow(iconName: "wind", value: viewModel.windInfo) - CompactInfoRow(iconName: "drop.fill", value: viewModel.precipChance) - CompactInfoRow(iconName: "humidity.fill", value: viewModel.humidity) - } - - .animation(.easeInOut(duration: 0.4), value: viewModel.windInfo) - } -} - - -struct CompactInfoRow: View { - let iconName: String - let value: String - - var body: some View { - HStack(spacing: 5) { - Image(systemName: iconName) - .font(.callout) - .frame(width: 20) - .symbolRenderingMode(.hierarchical) - .opacity(0.8) - - Text(value) - .font(.system(.subheadline, design: .rounded)) - .fontWeight(.semibold) - .lineLimit(1) - .minimumScaleFactor(0.7) - } - .id(value) - .transition(.opacity) - } -}

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 z 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist deleted file mode 100644 index a0186a00..00000000 --- a/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist b/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index d4823260..00000000 --- a/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,42 +0,0 @@ - - - - - SchemeUserState - - DynamicNotch.xcscheme_^#shared#^_ - - orderHint - 0 - - NearbyShare.xcscheme_^#shared#^_ - - orderHint - 1 - - Sapphire.xcscheme_^#shared#^_ - - orderHint - 0 - - - SuppressBuildableAutocreation - - DA46CF752DCBCA0000F00EC5 - - primary - - - DA46CF862DCBCA0100F00EC5 - - primary - - - DA46CF902DCBCA0100F00EC5 - - primary - - - - - From 834f0a9a2a26ae75ef27a85d2134522ed174ee0d Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:48:38 -0400 Subject: [PATCH 15/16] Delete submissions/sapphire/SapphireNotchTests directory --- .../SapphireNotchTests/DynamicNotchTests.swift | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift diff --git a/submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift b/submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift deleted file mode 100644 index 8ca6fb44..00000000 --- a/submissions/sapphire/SapphireNotchTests/DynamicNotchTests.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// DynamicNotchTests.swift -// DynamicNotchTests -// -// Created by Shariq Charolia on 2025-05-07. -// - -//import Testing -//@testable import Sapphire -// -//struct DynamicNotchTests { -// -// @Test func example() async throws { -// // Write your test here and use APIs like `#expect(...)` to check expected conditions. -// } -// -//} From dbfbc6f0467756b6328f0a7cbef7f32be80fe2d0 Mon Sep 17 00:00:00 2001 From: Shariq Charolia <134816402+cshariq@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:49:42 -0400 Subject: [PATCH 16/16] Delete submissions/sapphire/Sapphire directory --- .../App Settings/SettingsComponents.swift | 380 -------- .../Sapphire/App Settings/SettingsModel.swift | 211 ----- .../Sapphire/App Settings/SettingsPanes.swift | 886 ------------------ .../App Settings/SettingsSidebar.swift | 87 -- .../Sapphire/App Settings/SettingsView.swift | 78 -- .../Sapphire/App Settings/UpdateChecker.swift | 122 --- .../Sapphire/App Settings/UserDefault.swift | 44 - .../sapphire/Sapphire/App/AppDelegate.swift | 245 ----- .../AppIcon.appiconset/Artboard 1.png | Bin 118918 -> 0 bytes .../AppIcon.appiconset/Artboard 1@0.5x 1.png | Bin 32336 -> 0 bytes .../AppIcon.appiconset/Artboard 1@0.5x.png | Bin 32336 -> 0 bytes .../AppIcon.appiconset/Artboard 2.png | Bin 8675 -> 0 bytes .../AppIcon.appiconset/Artboard 3.png | Bin 2687 -> 0 bytes .../AppIcon.appiconset/Artboard 4.png | Bin 1075 -> 0 bytes .../AppIcon.appiconset/Artboard 5.png | Bin 1075 -> 0 bytes .../AppIcon.appiconset/Artboard 6.png | Bin 473 -> 0 bytes .../AppIcon.appiconset/Contents.json | 68 -- .../AppIcon.appiconset/Frame 32.png | Bin 181896 -> 0 bytes .../AppIcon.appiconset/Frame 33.png | Bin 181896 -> 0 bytes .../App/Assets.xcassets/Contents.json | 9 - .../Google-Gemini-Logo.imageset/Contents.json | 21 - .../Google-Gemini-Logo.png | Bin 16697 -> 0 bytes .../Sapphire/App/Base.lproj/Main.storyboard | 701 -------------- submissions/sapphire/Sapphire/App/Info.plist | 25 - .../Sapphire/App/OnboardingView.swift | 233 ----- .../Sapphire/App/PermissionsManager.swift | 185 ---- .../Sapphire/App/ViewController.swift | 25 - .../LiveActivityComponents.swift | 471 ---------- .../LiveActivities/LiveActivityManager.swift | 273 ------ .../NearDropCompactActivityView.swift | 81 -- .../NearDropLiveActivityView.swift | 257 ----- .../sapphire/Sapphire/Models/AppModels.swift | 121 --- .../Sapphire/Models/SpotifyModels.swift | 125 --- .../Sapphire/Models/WeatherModels.swift | 148 --- .../Models/weatherActivityViewModel.swift | 36 - .../Sapphire/Notch/CustomNotchShape.swift | 64 -- .../Sapphire/Notch/NotchConfiguration.swift | 55 -- .../Sapphire/Notch/NotchController.swift | 507 ---------- .../sapphire/Sapphire/Sapphire.entitlements | 16 - .../Services/Calendar/CalendarService.swift | 47 - .../Services/Calendar/CalendarViewModel.swift | 38 - .../Sapphire/Services/Gemini/GeminiAPI.swift | 137 --- .../Sapphire/Services/Gemini/GeminiLive.swift | 42 - .../Services/Gemini/GeminiLiveManager.swift | 432 --------- .../Services/Music/LyricsFetcher.swift | 149 --- .../Sapphire/Services/Music/MusicWidget.swift | 191 ---- .../Services/Music/SystemAudioMonitor.swift | 137 --- .../Services/Music/WaveformView.swift | 141 --- .../Services/Spotify/SpotifyAPIManager.swift | 338 ------- .../Services/System/ActiveAppMonitor.swift | 85 -- .../Services/System/AudioDeviceManager.swift | 124 --- .../Services/System/BatteryMonitor.swift | 71 -- .../Services/System/BluetoothManager.swift | 160 ---- .../Services/System/DesktopManager.swift | 38 - .../Services/System/EyeBreakManager.swift | 86 -- .../Services/System/FocusModeManager.swift | 81 -- .../Services/System/NotificationManager.swift | 173 ---- .../Services/System/TimerManager.swift | 34 - .../Services/Weather/WeatherService.swift | 174 ---- .../Services/Weather/WeatherViewModel.swift | 102 -- .../Sapphire/System/PrivateAPIs.swift | 254 ----- .../System/PrivateBluetoothMonitor.swift | 52 - .../sapphire/Sapphire/System/SystemHUD.swift | 357 ------- .../Sapphire/Utilities/Extensions.swift | 184 ---- .../sapphire/Sapphire/Utilities/Helpers.swift | 99 -- .../Widgets/Calendar/CalendarWidgetView.swift | 170 ---- .../Calendar/ScrollOffsetPreferenceKey.swift | 23 - .../Widgets/MusicPlayer/LyricsView.swift | 126 --- .../Widgets/MusicPlayer/MusicPlayerView.swift | 157 ---- .../Widgets/MusicPlayer/MusicWidgetView.swift | 150 --- .../MusicPlayer/Spotify/DevicesView.swift | 127 --- .../MusicPlayer/Spotify/LoginPromptView.swift | 34 - .../MusicPlayer/Spotify/PlaylistView.swift | 112 --- .../Spotify/QueueAndPlaylistsView.swift | 218 ----- .../Spotify/SpotifyPlaybackManager.swift | 72 -- .../NearbyShare/NearDropProgressView.swift | 229 ----- .../Sapphire/Widgets/NotchWidgetView.swift | 106 --- .../Widgets/Weather/WeatherDetailView.swift | 134 --- .../Widgets/Weather/WeatherIconMapper.swift | 100 -- .../Widgets/Weather/WeatherWidgetView.swift | 97 -- 80 files changed, 11055 deletions(-) delete mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift delete mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsModel.swift delete mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift delete mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift delete mode 100644 submissions/sapphire/Sapphire/App Settings/SettingsView.swift delete mode 100644 submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift delete mode 100644 submissions/sapphire/Sapphire/App Settings/UserDefault.swift delete mode 100644 submissions/sapphire/Sapphire/App/AppDelegate.swift delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x 1.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 2.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 3.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 4.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 5.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 6.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 32.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Frame 33.png delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/Contents.json delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Contents.json delete mode 100644 submissions/sapphire/Sapphire/App/Assets.xcassets/Google-Gemini-Logo.imageset/Google-Gemini-Logo.png delete mode 100644 submissions/sapphire/Sapphire/App/Base.lproj/Main.storyboard delete mode 100644 submissions/sapphire/Sapphire/App/Info.plist delete mode 100644 submissions/sapphire/Sapphire/App/OnboardingView.swift delete mode 100644 submissions/sapphire/Sapphire/App/PermissionsManager.swift delete mode 100644 submissions/sapphire/Sapphire/App/ViewController.swift delete mode 100644 submissions/sapphire/Sapphire/LiveActivities/LiveActivityComponents.swift delete mode 100644 submissions/sapphire/Sapphire/LiveActivities/LiveActivityManager.swift delete mode 100644 submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropCompactActivityView.swift delete mode 100644 submissions/sapphire/Sapphire/LiveActivities/NearbyShare/NearDropLiveActivityView.swift delete mode 100644 submissions/sapphire/Sapphire/Models/AppModels.swift delete mode 100644 submissions/sapphire/Sapphire/Models/SpotifyModels.swift delete mode 100644 submissions/sapphire/Sapphire/Models/WeatherModels.swift delete mode 100644 submissions/sapphire/Sapphire/Models/weatherActivityViewModel.swift delete mode 100644 submissions/sapphire/Sapphire/Notch/CustomNotchShape.swift delete mode 100644 submissions/sapphire/Sapphire/Notch/NotchConfiguration.swift delete mode 100644 submissions/sapphire/Sapphire/Notch/NotchController.swift delete mode 100644 submissions/sapphire/Sapphire/Sapphire.entitlements delete mode 100644 submissions/sapphire/Sapphire/Services/Calendar/CalendarService.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Calendar/CalendarViewModel.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Gemini/GeminiAPI.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Gemini/GeminiLive.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Gemini/GeminiLiveManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Music/LyricsFetcher.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Music/MusicWidget.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Music/SystemAudioMonitor.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Music/WaveformView.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Spotify/SpotifyAPIManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/ActiveAppMonitor.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/AudioDeviceManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/BatteryMonitor.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/BluetoothManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/DesktopManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/EyeBreakManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/FocusModeManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/NotificationManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/System/TimerManager.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Weather/WeatherService.swift delete mode 100644 submissions/sapphire/Sapphire/Services/Weather/WeatherViewModel.swift delete mode 100644 submissions/sapphire/Sapphire/System/PrivateAPIs.swift delete mode 100644 submissions/sapphire/Sapphire/System/PrivateBluetoothMonitor.swift delete mode 100644 submissions/sapphire/Sapphire/System/SystemHUD.swift delete mode 100644 submissions/sapphire/Sapphire/Utilities/Extensions.swift delete mode 100644 submissions/sapphire/Sapphire/Utilities/Helpers.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/Calendar/CalendarWidgetView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/Calendar/ScrollOffsetPreferenceKey.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/LyricsView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicPlayerView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/MusicWidgetView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/DevicesView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/LoginPromptView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/PlaylistView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/QueueAndPlaylistsView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/MusicPlayer/Spotify/SpotifyPlaybackManager.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/NearbyShare/NearDropProgressView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/NotchWidgetView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/Weather/WeatherDetailView.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/Weather/WeatherIconMapper.swift delete mode 100644 submissions/sapphire/Sapphire/Widgets/Weather/WeatherWidgetView.swift diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift b/submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift deleted file mode 100644 index e35ea4c2..00000000 --- a/submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift +++ /dev/null @@ -1,380 +0,0 @@ -// -// SettingsComponents.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI - - - -struct InfoContainer: View { - let text: String - let iconName: String - let color: Color - - var body: some View { - HStack(alignment: .top, spacing: 12) { - Image(systemName: iconName) - .font(.title3) - .foregroundColor(color) - .padding(.top, 2) - - Text(text) - .font(.system(size: 13)) - .foregroundStyle(.white.opacity(0.8)) - .lineSpacing(4) - } - .padding() - .background(color.opacity(0.15)) - .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous)) - .overlay( - RoundedRectangle(cornerRadius: 16, style: .continuous) - .stroke(color.opacity(0.5), lineWidth: 1) - ) - } -} - -struct GeneralSettingToggleRowView: View { - let setting: GeneralSettingType - @Binding var isEnabled: Bool - - var body: some View { - HStack(spacing: 15) { - Image(systemName: setting.systemImage) - .font(.system(size: 18, weight: .medium)) - .foregroundColor(setting.iconColor) - .frame(width: 36, height: 36) - .background(setting.iconColor.opacity(0.15)) - .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) - - Text(setting.displayName) - .font(.system(size: 14, weight: .medium)) - .foregroundStyle(.white) - - Spacer() - - Toggle("", isOn: $isEnabled) - .labelsHidden() - .toggleStyle(.switch) - } - .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) - } -} - -struct WidgetRowView: View { - let widgetType: WidgetType - @EnvironmentObject var settings: SettingsModel - - private var isEnabledBinding: Binding { - switch widgetType { - case .weather: return $settings.settings.weatherWidgetEnabled - case .calendar: return $settings.settings.calendarWidgetEnabled - case .shortcuts: return $settings.settings.shortcutsWidgetEnabled - case .music: return $settings.settings.musicWidgetEnabled - } - } - - var body: some View { - HStack { - Text(widgetType.displayName) - .font(.system(size: 14, weight: .medium)) - .foregroundStyle(.white) - - Spacer() - - Toggle("", isOn: isEnabledBinding) - .labelsHidden() - .toggleStyle(.switch) - - Image(systemName: "line.3.horizontal") - .font(.system(size: 16, weight: .medium)) - .foregroundStyle(.white.opacity(0.6)) - .padding(.leading, 8) - } - .padding(EdgeInsets(top: 18, leading: 20, bottom: 18, trailing: 20)) - } -} - -struct LiveActivityRowView: View { - let activityType: LiveActivityType - @EnvironmentObject var settings: SettingsModel - - private var isEnabledBinding: Binding { - switch activityType { - case .music: return $settings.settings.musicLiveActivityEnabled - case .weather: return $settings.settings.weatherLiveActivityEnabled - case .calendar: return $settings.settings.calendarLiveActivityEnabled - case .timers: return $settings.settings.timersLiveActivityEnabled - case .battery: return $settings.settings.batteryLiveActivityEnabled - case .eyeBreak: return $settings.settings.eyeBreakLiveActivityEnabled - case .desktop: return $settings.settings.desktopLiveActivityEnabled - - case .focus: return $settings.settings.focusLiveActivityEnabled - } - } - - var body: some View { - HStack { - Text(activityType.displayName) - .font(.system(size: 14, weight: .medium)) - .foregroundStyle(.white) - - Spacer() - - Toggle("", isOn: isEnabledBinding) - .labelsHidden() - .toggleStyle(.switch) - - Image(systemName: "line.3.horizontal") - .font(.system(size: 16, weight: .medium)) - .foregroundStyle(.white.opacity(0.6)) - .padding(.leading, 8) - } - .padding(EdgeInsets(top: 18, leading: 20, bottom: 18, trailing: 20)) - } -} - - -struct NotificationToggleRowView: View { - let source: NotificationSource - @EnvironmentObject var settings: SettingsModel - - private var isEnabledBinding: Binding { - switch source { - case .iMessage: return $settings.settings.iMessageNotificationsEnabled - case .faceTime: return $settings.settings.faceTimeNotificationsEnabled - case .airDrop: return $settings.settings.airDropNotificationsEnabled - } - } - - var body: some View { - HStack(spacing: 15) { - Image(systemName: source.systemImage) - .font(.system(size: 18, weight: .medium)) - .foregroundColor(source.iconColor) - .frame(width: 36, height: 36) - .background(source.iconColor.opacity(0.15)) - .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) - - Text(source.displayName) - .font(.system(size: 14, weight: .medium)) - .foregroundStyle(.white) - - Spacer() - - Toggle("", isOn: isEnabledBinding) - .labelsHidden() - .toggleStyle(.switch) - } - .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) - } -} - -struct SystemAppRowView: View { - let app: SystemApp - @Binding var isEnabled: Bool - - var body: some View { - HStack(spacing: 12) { - Image(nsImage: app.icon) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(width: 28, height: 28) - .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) - - Text(app.name) - .font(.system(size: 13)) - .foregroundStyle(.white) - - Spacer() - - Toggle("", isOn: $isEnabled) - .labelsHidden() - .toggleStyle(.switch) - } - .padding(EdgeInsets(top: 8, leading: 20, bottom: 8, trailing: 20)) - } -} - -struct ReorderableVStack: View { - @Binding var items: [Item] - @ViewBuilder var content: (Item) -> Content - - @State private var draggingItem: Item? - @State private var dragOffset: CGSize = .zero - - init(items: Binding<[Item]>, @ViewBuilder content: @escaping (Item) -> Content) { - self._items = items - self.content = content - } - - var body: some View { - VStack(spacing: 0) { - ForEach(items) { item in - content(item) - .offset(y: draggingItem == item ? dragOffset.height : 0) - .opacity(draggingItem == item ? 0.75 : 1) - .zIndex(draggingItem == item ? 1 : 0) - .contentShape(Rectangle()) - .gesture( - DragGesture(minimumDistance: 10, coordinateSpace: .global) - .onChanged { value in - if draggingItem == nil { - draggingItem = item - } - dragOffset = value.translation - } - .onEnded { value in - if let draggingItem = draggingItem { - moveItem(draggedItem: draggingItem, with: value) - } - withAnimation { - draggingItem = nil - dragOffset = .zero - } - } - ) - - if item.id != items.last?.id { - Rectangle() - .fill(Color.white.opacity(0.2)) - .frame(height: 1) - } - } - } - } - - private func moveItem(draggedItem: Item, with value: DragGesture.Value) { - guard let fromIndex = items.firstIndex(of: draggedItem) else { return } - - let rowHeight: CGFloat = 61.0 - let verticalTranslation = value.translation.height - let moveOffset = Int((verticalTranslation / rowHeight).rounded()) - - var toIndex = fromIndex + moveOffset - toIndex = max(0, min(items.count - 1, toIndex)) - - if fromIndex != toIndex { - withAnimation(.spring()) { - let itemToMove = items.remove(at: fromIndex) - items.insert(itemToMove, at: toIndex) - } - } - } -} - -struct CustomBatterySlider: View { - @Binding var value: Double - let range: ClosedRange - - private let horizontalPadding: CGFloat = 8 - - var body: some View { - GeometryReader { geometry in - let totalWidth = geometry.size.width - let thumbSize: CGFloat = 40 - - let trackUsableWidth = totalWidth - (2 * horizontalPadding) - let thumbUsableWidth = trackUsableWidth - thumbSize - - let progress = (value - range.lowerBound) / (range.upperBound - range.lowerBound) - - let clampedProgress = max(0.0, min(1.0, progress)) - - let thumbX = (clampedProgress * thumbUsableWidth) + horizontalPadding + (thumbSize / 2) - - ZStack(alignment: .leading) { - Capsule() - .fill(Color.black.opacity(0.4)) - .padding(.horizontal, horizontalPadding) - - Circle() - .fill(Color(white: 0.8)) - .frame(width: thumbSize, height: thumbSize) - .overlay( - Text("\(Int(value.rounded()))") - .font(.system(size: 14, weight: .bold)) - .foregroundColor(.black) - ) - .position(x: thumbX, y: geometry.size.height / 2) - } - .gesture( - DragGesture(minimumDistance: 0) - .onChanged { gestureValue in - let newX = min(max(gestureValue.location.x, horizontalPadding), totalWidth - horizontalPadding) - let newProgress = (newX - horizontalPadding) / thumbUsableWidth - var newValue = (range.upperBound - range.lowerBound) * Double(newProgress) + range.lowerBound - - newValue = max(range.lowerBound, min(range.upperBound, newValue)) - - self.value = newValue - } - ) - } - } -} - -struct CustomSliderRowView: View { - let label: String - @Binding var value: Double - let range: ClosedRange - let specifier: String - - var body: some View { - VStack(alignment: .leading, spacing: 8) { - HStack { - Text(label) - Spacer() - Text(String(format: specifier, value)) - } - Slider(value: $value, in: range) - } - .padding() - } -} - - -struct SettingsContainerModifier: ViewModifier { - func body(content: Content) -> some View { - content - .background(Color.black.opacity(0.15)) - .clipShape(RoundedRectangle(cornerRadius: 24, style: .continuous)) - .overlay( - RoundedRectangle(cornerRadius: 24, style: .continuous) - .stroke(Color.white.opacity(0.1), lineWidth: 1) - ) - } -} - -struct SettingsGroup: View { - let content: Content - init(@ViewBuilder content: () -> Content) { self.content = content() } - - var body: some View { - VStack(spacing: 0) { content } - .padding(.horizontal) - .background( - RoundedRectangle(cornerRadius: 10, style: .continuous) - .fill(.background.opacity(0.15)) - ) - } -} - -struct SettingsDetailRow: View { - let title: String - let content: Content - init(title: String, @ViewBuilder content: () -> Content) { - self.title = title - self.content = content() - } - - var body: some View { - HStack { - Text(title) - Spacer() - HStack { content }.foregroundStyle(.secondary) - }.padding(.vertical, 10) - } -} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsModel.swift b/submissions/sapphire/Sapphire/App Settings/SettingsModel.swift deleted file mode 100644 index 2cd76851..00000000 --- a/submissions/sapphire/Sapphire/App Settings/SettingsModel.swift +++ /dev/null @@ -1,211 +0,0 @@ -// -// SettingsModel.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI -import AppKit -import IOBluetooth -import Combine - - -class SettingsModel: ObservableObject { - let settingsPublisher = PassthroughSubject() - @UserDefault(key: "appSettings", defaultValue: Settings()) - var settings: Settings { - willSet { settingsPublisher.send(newValue); objectWillChange.send() } - } -} - - -struct Settings: Codable, Equatable { - var liveActivityOrder: [LiveActivityType] = LiveActivityType.allCases - var musicLiveActivityEnabled: Bool = true, weatherLiveActivityEnabled: Bool = true, calendarLiveActivityEnabled: Bool = true, timersLiveActivityEnabled: Bool = true, batteryLiveActivityEnabled: Bool = true, eyeBreakLiveActivityEnabled: Bool = true, desktopLiveActivityEnabled: Bool = true, focusLiveActivityEnabled: Bool = true - var musicWaveformIsVolumeSensitive: Bool = true, dropboxIconEnabled: Bool = true, batteryEstimatorEnabled: Bool = true, geminiEnabled: Bool = true, pinEnabled: Bool = true - var widgetOrder: [WidgetType] = [.music, .weather, .calendar, .shortcuts] - var musicWidgetEnabled: Bool = true, weatherWidgetEnabled: Bool = true, calendarWidgetEnabled: Bool = true, shortcutsWidgetEnabled: Bool = true - var bluetoothNotifyLowBattery: Bool = true, bluetoothNotifySound: Bool = true, masterNotificationsEnabled: Bool = true, iMessageNotificationsEnabled: Bool = true, airDropNotificationsEnabled: Bool = true, faceTimeNotificationsEnabled: Bool = true, systemNotificationsEnabled: Bool = true - var appNotificationStates: [String: Bool] = [:] - var neardropEnabled: Bool = true, neardropDeviceDisplayName: String = "My Mac", neardropDownloadLocationPath: String = FileManager.default.urls( - for: .downloadsDirectory, - in: .userDomainMask - ).first!.path, neardropOpenOnClick: Bool = true - var showNowPlayingInMenuBar: Bool = true, spotifyClientId: String = "", spotifyClientSecret: String = "", defaultMusicPlayer: DefaultMusicPlayer = .appleMusic, showLyricsInLiveActivity: Bool = false - var musicAppStates: [String: Bool] = [:] - var musicOpenOnClick: Bool = true, weatherDefaultLocation: String = "New York, NY", weatherUseCelsius: Bool = false, weatherOpenOnClick: Bool = false - var calendarShowAllDayEvents: Bool = true, calendarStartOfWeek: Day = .sunday - var eyeBreakWorkInterval: Double = 20, eyeBreakBreakDuration: Double = 20, eyeBreakSoundAlerts: Bool = true - var enableVolumeHUD: Bool = true, volumeHUDStyle: HUDStyle = .default, volumeHUDSoundEnabled: Bool = true - var enableBrightnessHUD: Bool = true, brightnessHUDStyle: HUDStyle = .default - var batteryNotifyForLowBattery: Bool = true, batteryNotifyWithSound: Bool = true, batteryNotifyChargingState: Bool = true - var geminiApiKey: String = "" -} - - -enum WidgetType: String, Codable, CaseIterable, Identifiable, Equatable { - case weather, - calendar, - shortcuts, - music; var id: String { self.rawValue }; var displayName: String { - self.rawValue.prefix(1).uppercased() + self.rawValue.dropFirst() - } -} -enum LiveActivityType: String, Codable, CaseIterable, Identifiable, Equatable { - case eyeBreak, - focus, - desktop, - battery, - timers, - calendar, - weather, - music; var id: String { self.rawValue }; var displayName: String { - switch self { - case .music: "Music"; case .weather: "Weather"; case .calendar: "Calendar"; case .timers: "Timers"; case .battery: "Battery"; case .eyeBreak: "Eye Break"; case .desktop: "Desktop"; case .focus: "Focus" - } - } -} -enum NotificationSource: String, CaseIterable, Identifiable { - case iMessage, - faceTime, - airDrop; var id: String { rawValue }; var displayName: String { switch self { case .iMessage: "iMessage"; case .faceTime: "FaceTime"; case .airDrop: "AirDrop" } }; var systemImage: String { switch self { case .iMessage: "message.fill"; case .faceTime: "video.fill"; case .airDrop: "shareplay" } }; var iconColor: Color { - switch self { - case .iMessage, - .faceTime: .green; case .airDrop: .blue - } - } -} -enum GeneralSettingType: String, CaseIterable, Identifiable, Equatable { - case dropboxIcon, - batteryEstimator, - gemini, - pin; var id: String { self.rawValue }; var displayName: String { switch self { case .dropboxIcon: "Dropbox Icon"; case .batteryEstimator: "Battery Estimator"; case .gemini: "Gemini Integration"; case .pin: "Pin Widgets" } }; var systemImage: String { switch self { case .dropboxIcon: "cloud.fill"; case .batteryEstimator: "gauge.high"; case .gemini: "sparkles"; case .pin: "pin.fill" } }; var iconColor: Color { - switch self { - case .dropboxIcon: .blue; case .batteryEstimator: .green; case .gemini: .purple; case .pin: .gray - } - } -} -struct SystemApp: Identifiable, Equatable { - let id: String, - name: String, - icon: NSImage, - isBrowser: Bool -} -enum Day: String, Codable, CaseIterable, Identifiable { - case sunday, - monday; var id: String { self.rawValue.capitalized } -} -enum DefaultMusicPlayer: String, Codable, CaseIterable, Identifiable { - case appleMusic, - spotify; var id: String { self.rawValue }; var displayName: String { - switch self { - case .appleMusic: "Apple Music"; case .spotify: "Spotify" - } - } -} -enum HUDStyle: String, Codable, CaseIterable, Identifiable { - case `default`, - thin; var id: String { self.rawValue.capitalized } -} -enum SettingsSection: String, CaseIterable, Identifiable { - case general, - widgets, - liveActivities, - battery, - bluetooth, - hud, - notifications, - neardrop, - music, - weather, - calendar, - eyeBreak, - gemini, - about; var id: String { self.rawValue }; var label: String { switch self { case .general: "General"; case .widgets: "Widgets"; case .liveActivities: "Live Activities"; case .battery: "Battery"; case .bluetooth: "Bluetooth"; case .hud: "HUD"; case .notifications: "Notifications"; case .neardrop: "Nearby Share"; case .music: "Music"; case .weather: "Weather"; case .calendar: "Calendar"; case .eyeBreak: "Eye Break"; case .gemini: "Gemini"; case .about: "About" } }; var systemImage: String { switch self { case .general: "gear"; case .widgets: "square.grid.2x2.fill"; case .liveActivities: "bolt.badge.a.fill"; case .battery: "battery.100"; case .bluetooth: "bolt.horizontal.circle.fill"; case .hud: "macwindow.on.rectangle"; case .notifications: "bell"; case .neardrop: "shareplay"; case .music: "music.note"; case .weather: "cloud.sun.fill"; case .calendar: "calendar"; case .eyeBreak: "eye.fill"; case .gemini: "sparkles"; case .about: "info.circle" } }; var iconBackgroundColor: Color { - switch self { - case .general: .gray; case .widgets: .purple; case .liveActivities: .cyan; case .battery: .green; case .bluetooth: .blue; case .hud: .indigo; case .notifications: .red; case .neardrop: .blue; case .music: .pink; case .weather: .blue; case .calendar: .red; case .eyeBreak: .teal; case .gemini: .purple; case .about: .blue - } - } -} - -@MainActor -class SystemAppFetcher: ObservableObject { - @Published var apps: [SystemApp] = [] - @Published var foundBundleIDs: Set = [] - - func fetchApps() { - DispatchQueue.global(qos: .userInitiated).async { - var fetchedApps: [SystemApp] = [] - - var seenBundleIDs = Set() - - let fileManager = FileManager.default - let searchPaths = ["/System/Applications", "/Applications", NSSearchPathForDirectoriesInDomains(.applicationDirectory, .userDomainMask, true).first].compactMap { - $0 - } - - for path in searchPaths { - do { - let appURLs = try fileManager.contentsOfDirectory( - at: URL(fileURLWithPath: path), - includingPropertiesForKeys: [.isApplicationKey], - options: .skipsHiddenFiles - ) - for url in appURLs where url.pathExtension == "app" { - guard let bundle = Bundle(url: url), let bundleId = bundle.bundleIdentifier else { - continue - } - - - - if !seenBundleIDs.contains(bundleId) { - let name = fileManager.displayName(atPath: url.path) - let icon = NSWorkspace.shared.icon( - forFile: url.path - ) - let isBrowser = self.isBrowser(bundle: bundle) - let app = SystemApp( - id: bundleId, - name: name, - icon: icon, - isBrowser: isBrowser - ) - - fetchedApps.append(app) - - seenBundleIDs.insert(bundleId) - } - } - } catch { - - } - } - - DispatchQueue.main.async { - self.apps = fetchedApps - .sorted { - $0.name - .localizedCaseInsensitiveCompare( - $1.name - ) == .orderedAscending - } - self.foundBundleIDs = seenBundleIDs - } - } - } - - private func isBrowser(bundle: Bundle?) -> Bool { - guard let bundle = bundle, let urlTypes = bundle.infoDictionary?["CFBundleURLTypes"] as? [[String: Any]] else { - return false - } - for type in urlTypes { - if let schemes = type["CFBundleURLSchemes"] as? [String], schemes - .contains("http") || schemes - .contains("https") { - return true - } - } - return false - } -} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift b/submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift deleted file mode 100644 index f8b0ff3d..00000000 --- a/submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift +++ /dev/null @@ -1,886 +0,0 @@ -// -// SettingsPanes.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI - - -struct SettingsDetailView: View { - var selectedSection: SettingsSection? - var body: some View { - ZStack { - GeneralSettingsView().opacity(selectedSection == .general ? 1 : 0) - WidgetsSettingsView().opacity(selectedSection == .widgets ? 1 : 0) - LiveActivitiesSettingsView().opacity(selectedSection == .liveActivities ? 1 : 0) - BatterySettingsView().opacity(selectedSection == .battery ? 1 : 0) - BluetoothSettingsView().opacity(selectedSection == .bluetooth ? 1 : 0) - HUDSettingsView().opacity(selectedSection == .hud ? 1 : 0) - NotificationsSettingsView().opacity(selectedSection == .notifications ? 1 : 0) - NeardropSettingsView().opacity(selectedSection == .neardrop ? 1 : 0) - MusicSettingsView().opacity(selectedSection == .music ? 1 : 0) - WeatherSettingsView().opacity(selectedSection == .weather ? 1 : 0) - CalendarSettingsView().opacity(selectedSection == .calendar ? 1 : 0) - EyeBreakSettingsView().opacity(selectedSection == .eyeBreak ? 1 : 0) - GeminiSettingsView().opacity(selectedSection == .gemini ? 1 : 0) - AboutSettingsView().opacity(selectedSection == .about ? 1 : 0) - - if selectedSection == nil { - VStack { Image(systemName: "sidebar.left").font(.system(size: 50)).foregroundStyle(.tertiary); Text("Select a category").font(.title).foregroundStyle(.secondary) }.frame(maxWidth: .infinity, maxHeight: .infinity) - } - }.animation(.easeOut(duration: 0.15), value: selectedSection) - } -} - - - -struct GeneralSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("General") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(spacing: 0) { - ForEach(GeneralSettingType.allCases) { setting in - GeneralSettingToggleRowView(setting: setting, isEnabled: binding(for: setting)) - if setting != GeneralSettingType.allCases.last { - Rectangle() - .fill(Color.white.opacity(0.2)) - .frame(height: 1) - .padding(.leading, 60) - } - } - } - .modifier(SettingsContainerModifier()) - } - .padding(25) - } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - - private func binding(for setting: GeneralSettingType) -> Binding { - switch setting { - case .dropboxIcon: return $settings.settings.dropboxIconEnabled - case .batteryEstimator: return $settings.settings.batteryEstimatorEnabled - case .gemini: return $settings.settings.geminiEnabled - case .pin: return $settings.settings.pinEnabled - } - } -} - -struct WidgetsSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Widgets").font(.largeTitle.bold()).padding(.bottom) - - ReorderableVStack(items: $settings.settings.widgetOrder) { widget in - WidgetRowView(widgetType: widget) - } - .modifier(SettingsContainerModifier()) - } - .padding(25) - } - } -} - -struct LiveActivitiesSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Live Activities").font(.largeTitle.bold()).padding(.bottom) - - ReorderableVStack(items: $settings.settings.liveActivityOrder) { activity in - LiveActivityRowView(activityType: activity) - } - .modifier(SettingsContainerModifier()) - } - .padding(25) - } - } -} - -struct NotificationsSettingsView: View { - @StateObject private var appFetcher = SystemAppFetcher() - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Notifications") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(spacing: 0) { - HStack { - Text("Enable Notifications") - .font(.system(size: 14, weight: .medium)) - Spacer() - Toggle("", isOn: $settings.settings.masterNotificationsEnabled) - .labelsHidden() - .toggleStyle(.switch) - .animation(.default, value: settings.settings.masterNotificationsEnabled) - } - .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) - } - .modifier(SettingsContainerModifier()) - - VStack(spacing: 20) { - VStack(spacing: 0) { - ForEach(NotificationSource.allCases) { source in - NotificationToggleRowView(source: source) - if source != NotificationSource.allCases.last { - Rectangle() - .fill(Color.white.opacity(0.2)) - .frame(height: 1) - .padding(.leading, 60) - } - } - } - - VStack(alignment: .leading, spacing: 10) { - HStack { - Text("System Notifications") - .font(.system(size: 14, weight: .medium)) - Spacer() - Toggle("", isOn: $settings.settings.systemNotificationsEnabled) - .labelsHidden() - .toggleStyle(.switch) - .animation(.default, value: settings.settings.systemNotificationsEnabled) - } - .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 60) - - Text("Allow Notifications From:") - .font(.headline) - .padding(.horizontal, 20) - .padding(.vertical, 10) - - ScrollView { - VStack(spacing: 0) { - ForEach(appFetcher.apps) { app in - SystemAppRowView(app: app, isEnabled: binding(for: app)) - if app.id != appFetcher.apps.last?.id { - Rectangle() - .fill(Color.white.opacity(0.2)) - .frame(height: 1) - .padding(.leading, 50) - } - } - } - } - .frame(maxHeight: 360) - } - .disabled(!settings.settings.systemNotificationsEnabled) - .opacity(settings.settings.systemNotificationsEnabled ? 1.0 : 0.5) - } - .modifier(SettingsContainerModifier()) - .disabled(!settings.settings.masterNotificationsEnabled) - .opacity(settings.settings.masterNotificationsEnabled ? 1.0 : 0.5) - .animation(.easeInOut, value: settings.settings.masterNotificationsEnabled) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .onAppear { - appFetcher.fetchApps() - } - } - } - - private func binding(for app: SystemApp) -> Binding { - return .init( - get: { settings.settings.appNotificationStates[app.id, default: true] }, - set: { settings.settings.appNotificationStates[app.id] = $0 } - ) - } -} - - -struct BatterySettingsView: View { - @EnvironmentObject var settings: SettingsModel - @State private var batteryLimit: Double = 80.0 - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Battery") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(alignment: .leading, spacing: 0) { - HStack { - Text("Notify on Charging State Change") - Spacer() - Toggle("", isOn: $settings.settings.batteryNotifyChargingState) - .labelsHidden().toggleStyle(.switch) - } - .padding() - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Notify for Low Battery") - Spacer() - Toggle("", isOn: $settings.settings.batteryNotifyForLowBattery) - .labelsHidden().toggleStyle(.switch) - } - .padding() - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Notify with Sound") - Spacer() - Toggle("", isOn: $settings.settings.batteryNotifyWithSound) - .labelsHidden().toggleStyle(.switch) - } - .padding() - .disabled(!settings.settings.batteryNotifyForLowBattery) - .opacity(settings.settings.batteryNotifyForLowBattery ? 1.0 : 0.5) - .animation(.easeInOut, value: settings.settings.batteryNotifyForLowBattery) - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - VStack(alignment: .leading, spacing: 16) { - Text("Battery Limit: \(Int(batteryLimit))%") - .font(.system(size: 16, weight: .medium)) - .foregroundStyle(.white.opacity(0.9)) - - CustomBatterySlider(value: $batteryLimit, range: 20...100) - .frame(height: 50) - } - .padding() - } - .modifier(SettingsContainerModifier()) - - if batteryLimit < 50 { - InfoContainer( - text: "Setting the battery limit to lower than 50% isn't recommended as it can cause your battery to die quickly.", - iconName: "exclamationmark.triangle.fill", - color: .yellow - ) - .transition(.opacity.combined(with: .move(edge: .top))) - } - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .animation(.easeInOut, value: batteryLimit < 50) - } - } -} - - -struct GeminiSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading) { - Text("Gemini") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(alignment: .leading, spacing: 8) { - Text("Gemini API Key") - .font(.system(size: 14, weight: .medium)) - - SecureField("Enter your API key", text: $settings.settings.geminiApiKey) - .textFieldStyle(.plain) - .padding(8) - .background(Color.black.opacity(0.2)) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) - } - .padding(25) - .modifier(SettingsContainerModifier()) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - } -} - -struct HUDSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("HUD") - .font(.largeTitle.bold()) - .padding(.bottom) - - - VStack(alignment: .leading, spacing: 10) { - HStack { - Text("Volume HUD") - .font(.headline) - Spacer() - Toggle("", isOn: $settings.settings.enableVolumeHUD) - .labelsHidden().toggleStyle(.switch) - } - - Divider() - - HStack { - Text("View Style") - Spacer() - Picker("", selection: $settings.settings.volumeHUDStyle) { - ForEach(HUDStyle.allCases) { style in - Text(style.id).tag(style) - } - } - .labelsHidden() - .frame(width: 120) - } - .disabled(!settings.settings.enableVolumeHUD) - .opacity(settings.settings.enableVolumeHUD ? 1.0 : 0.5) - - Divider() - - HStack { - Text("Sound on Change") - Spacer() - Toggle("", isOn: $settings.settings.volumeHUDSoundEnabled) - .labelsHidden().toggleStyle(.switch) - } - .disabled(!settings.settings.enableVolumeHUD) - .opacity(settings.settings.enableVolumeHUD ? 1.0 : 0.5) - } - .padding() - .modifier(SettingsContainerModifier()) - .animation(.easeInOut, value: settings.settings.enableVolumeHUD) - - - VStack(alignment: .leading, spacing: 10) { - HStack { - Text("Brightness HUD") - .font(.headline) - Spacer() - Toggle("", isOn: $settings.settings.enableBrightnessHUD) - .labelsHidden().toggleStyle(.switch) - } - - Divider() - - HStack { - Text("View Style") - Spacer() - Picker("", selection: $settings.settings.brightnessHUDStyle) { - ForEach(HUDStyle.allCases) { style in - Text(style.id).tag(style) - } - } - .labelsHidden() - .frame(width: 120) - } - .disabled(!settings.settings.enableBrightnessHUD) - .opacity(settings.settings.enableBrightnessHUD ? 1.0 : 0.5) - } - .padding() - .modifier(SettingsContainerModifier()) - .animation(.easeInOut, value: settings.settings.enableBrightnessHUD) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - } -} - -struct MusicSettingsView: View { - @EnvironmentObject var settings: SettingsModel - @StateObject private var appFetcher = SystemAppFetcher() - - private var browserApps: [SystemApp] { appFetcher.apps.filter { $0.isBrowser } } - private var otherApps: [SystemApp] { appFetcher.apps.filter { !$0.isBrowser } } - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Music").font(.largeTitle.bold()).padding(.bottom) - VStack(spacing: 0) { - HStack { Text("Show Now Playing in Menu Bar"); Spacer(); Toggle("", isOn: $settings.settings.showNowPlayingInMenuBar).labelsHidden().toggleStyle(.switch) }.padding() - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - HStack { Text("Waveform is volume sensitive"); Spacer(); Toggle("", isOn: $settings.settings.musicWaveformIsVolumeSensitive).labelsHidden().toggleStyle(.switch) }.padding() - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - HStack { Text("Default Music App"); Spacer(); Picker("", selection: $settings.settings.defaultMusicPlayer) { Text("Apple Music").tag(DefaultMusicPlayer.appleMusic); if appFetcher.foundBundleIDs.contains("com.spotify.client") { Text("Spotify").tag(DefaultMusicPlayer.spotify) } }.labelsHidden().frame(width: 150) }.padding() - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - - VStack(alignment: .leading, spacing: 8) { - Text("Spotify API Credentials") - .font(.system(size: 14, weight: .medium)) - Text("Register your app at developer.spotify.com and copy these values here. The redirect URI is: sapphire://callback") - .font(.caption) - .foregroundColor(.secondary) - .padding(.bottom, 4) - - Text("Client ID") - .font(.system(size: 13, weight: .medium)) - .foregroundStyle(.white.opacity(0.8)) - SecureField("Enter your Client ID", text: $settings.settings.spotifyClientId) - .textFieldStyle(.plain) - .padding(8) - .background(Color.black.opacity(0.2)) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) - - Text("Client Secret") - .font(.system(size: 13, weight: .medium)) - .foregroundStyle(.white.opacity(0.8)) - .padding(.top, 5) - SecureField("Enter your Client Secret", text: $settings.settings.spotifyClientSecret) - .textFieldStyle(.plain) - .padding(8) - .background(Color.black.opacity(0.2)) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) - }.padding().padding(.top, 5) - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Open detailed Music widget on live activity click"); Spacer(); Toggle("", isOn: $settings.settings.musicOpenOnClick).labelsHidden().toggleStyle(.switch) }.padding() - }.modifier(SettingsContainerModifier()) - - VStack(spacing: 0) { - HStack { Text("Show Lyrics in Live Activity"); Spacer(); Toggle("", isOn: $settings.settings.showLyricsInLiveActivity).labelsHidden().toggleStyle(.switch) }.padding() - }.modifier(SettingsContainerModifier()).animation(.default, value: settings.settings.showLyricsInLiveActivity) - - if settings.settings.showLyricsInLiveActivity { - VStack(alignment: .leading, spacing: 10) { - Text("Allow Lyrics From:").font(.headline).padding([.horizontal, .top]) - ScrollView { - VStack(spacing: 0) { - Text("Browsers (Disabled by Default)").font(.caption).foregroundStyle(.secondary).padding(.vertical, 5) - ForEach(browserApps) { app in SystemAppRowView(app: app, isEnabled: binding(for: app, isBrowser: true)) } - Text("Other Apps").font(.caption).foregroundStyle(.secondary).padding(.vertical, 5) - ForEach(otherApps) { app in SystemAppRowView(app: app, isEnabled: binding(for: app, isBrowser: false)) } - } - }.frame(maxHeight: 360) - }.modifier(SettingsContainerModifier()).transition(.opacity.combined(with: .move(edge: .top))) - } - }.padding(25).frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top).onAppear { appFetcher.fetchApps() } - } - } - - private func binding(for app: SystemApp, isBrowser: Bool) -> Binding { - .init( - get: { settings.settings.musicAppStates[app.id, default: !isBrowser] }, - set: { settings.settings.musicAppStates[app.id] = $0 } - ) - } -} - -struct WeatherSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Weather") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(spacing: 0) { - VStack(alignment: .leading, spacing: 8) { - Text("Default Location") - TextField("e.g., New York, NY", text: $settings.settings.weatherDefaultLocation) - .textFieldStyle(.plain) - .padding(8) - .background(Color.black.opacity(0.2)) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) - } - .padding() - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Use Celsius") - Spacer() - Toggle("", isOn: $settings.settings.weatherUseCelsius) - .labelsHidden().toggleStyle(.switch) - } - .padding() - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Open detailed Weather widget on live activity click") - Spacer() - Toggle("", isOn: $settings.settings.weatherOpenOnClick) - .labelsHidden().toggleStyle(.switch) - } - .padding() - } - .modifier(SettingsContainerModifier()) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - } -} - -struct CalendarSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Calendar") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(spacing: 0) { - HStack { - Text("Show All-Day Events") - Spacer() - Toggle("", isOn: $settings.settings.calendarShowAllDayEvents) - .labelsHidden().toggleStyle(.switch) - } - .padding() - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Start Week On") - Spacer() - Picker("", selection: $settings.settings.calendarStartOfWeek) { - ForEach(Day.allCases) { day in - Text(day.id).tag(day) - } - } - .labelsHidden() - .frame(width: 120) - } - .padding() - } - .modifier(SettingsContainerModifier()) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - } -} - -struct EyeBreakSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Eye Break") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(spacing: 0) { - CustomSliderRowView( - label: "Work Interval", - value: $settings.settings.eyeBreakWorkInterval, - range: 5...60, - specifier: "%.0f min" - ) - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - CustomSliderRowView( - label: "Break Duration", - value: $settings.settings.eyeBreakBreakDuration, - range: 10...60, - specifier: "%.0f sec" - ) - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Enable Sound Alerts") - Spacer() - Toggle("", isOn: $settings.settings.eyeBreakSoundAlerts) - .labelsHidden().toggleStyle(.switch) - } - .padding() - } - .modifier(SettingsContainerModifier()) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - } -} - -struct BluetoothSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("Bluetooth") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(spacing: 0) { - HStack { - Text("Notify for Low Battery") - Spacer() - Toggle("", isOn: $settings.settings.bluetoothNotifyLowBattery) - .labelsHidden() - .toggleStyle(.switch) - } - .padding() - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) - - HStack { - Text("Notify for Sound") - Spacer() - Toggle("", isOn: $settings.settings.bluetoothNotifySound) - .labelsHidden() - .toggleStyle(.switch) - } - .padding() - } - .modifier(SettingsContainerModifier()) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - } - } -} - -struct NeardropSettingsView: View { - @EnvironmentObject var settings: SettingsModel - - @State private var downloadPath: String = "" - @State private var isPathValid: Bool = true - - var body: some View { - ScrollView { - VStack(alignment: .leading) { - Text("Nearby Share") - .font(.largeTitle.bold()) - .padding(.bottom) - - VStack(spacing: 0) { - HStack { - Text("Enable Nearby Share") - .font(.system(size: 14, weight: .medium)) - Spacer() - Toggle("", isOn: $settings.settings.neardropEnabled) - .labelsHidden() - .toggleStyle(.switch) - } - .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.horizontal, 20) - - InfoContainer( - text: "Nearby Share allows you to share files from Android phones to your Mac using Android's native file sharing (Nearby Share / Quick Share). It's recommended to keep this feature enabled for convenient sharing from family and friends.", - iconName: "info.circle.fill", - color: .blue - ) - .padding() - - VStack(alignment: .leading, spacing: 15) { - VStack(alignment: .leading, spacing: 8) { - Text("Device Display Name") - .font(.system(size: 14, weight: .medium)) - .foregroundStyle(.white) - - TextField("My Mac", text: $settings.settings.neardropDeviceDisplayName) - .textFieldStyle(.plain) - .padding(.vertical, 8) - .padding(.horizontal, 12) - .background(Color.black.opacity(0.2)) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2), lineWidth: 1)) - .foregroundStyle(.white) - .font(.system(size: 13)) - .disabled(!settings.settings.neardropEnabled) - } - - VStack(alignment: .leading, spacing: 8) { - Text("Download Location") - .font(.system(size: 14, weight: .medium)) - .foregroundStyle(.white) - - HStack { - TextField("Path", text: $downloadPath, onCommit: validateAndSavePath) - .textFieldStyle(.plain) - .foregroundStyle(.white) - .font(.system(size: 13)) - .disabled(!settings.settings.neardropEnabled) - - Image(systemName: isPathValid ? "checkmark.circle.fill" : "xmark.circle.fill") - .foregroundColor(isPathValid ? .green : .red) - } - .padding(.vertical, 8) - .padding(.horizontal, 12) - .background(Color.black.opacity(0.2)) - .clipShape(RoundedRectangle(cornerRadius: 8)) - .overlay(RoundedRectangle(cornerRadius: 8).stroke(isPathValid ? Color.white.opacity(0.2) : Color.red, lineWidth: 1)) - - if !isPathValid { - Text("A valid directory is required.") - .font(.caption) - .foregroundColor(.red) - } - } - } - .padding([.horizontal, .bottom], 20) - .opacity(settings.settings.neardropEnabled ? 1.0 : 0.5) - - Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.horizontal, 20) - - HStack { - Text("Open detailed AirDrop widget on live activity click") - Spacer() - Toggle("", isOn: $settings.settings.neardropOpenOnClick) - .labelsHidden().toggleStyle(.switch) - } - .padding() - .disabled(!settings.settings.neardropEnabled) - .opacity(settings.settings.neardropEnabled ? 1.0 : 0.5) - - } - .modifier(SettingsContainerModifier()) - .animation(.easeInOut, value: settings.settings.neardropEnabled) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .onAppear { - self.downloadPath = settings.settings.neardropDownloadLocationPath - } - .onChange(of: downloadPath) { newValue in - self.isPathValid = validate(path: newValue) - } - } - } - - private func validateAndSavePath() { - if validate(path: downloadPath) { - settings.settings.neardropDownloadLocationPath = downloadPath - } - } - - private func validate(path: String) -> Bool { - var isDirectory: ObjCBool = false - let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory) - return exists && isDirectory.boolValue - } -} - -struct AboutSettingsView: View { - @StateObject private var updateChecker = UpdateChecker() - - var body: some View { - ScrollView { - VStack(alignment: .leading, spacing: 20) { - Text("About") - .font(.largeTitle.bold()) - .padding(.bottom) - - HStack { - Image(nsImage: NSApp.applicationIconImage) - .resizable() - .frame(width: 80, height: 80) - .clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous)) - .padding(.trailing, 10) - - VStack(alignment: .leading, spacing: 4) { - Text("Sapphire") - .font(.largeTitle.weight(.bold)) - Text("Version \(currentAppVersion)") - .foregroundStyle(.secondary) - .textSelection(.enabled) - } - Spacer() - } - - VStack { - switch updateChecker.status { - case .checking: - HStack { - ProgressView().scaleEffect(0.5) - Text("Checking for updates...").foregroundStyle(.secondary) - } - case .upToDate: - HStack { - Image(systemName: "checkmark.circle.fill").foregroundColor(.green) - Text("You are up to date!").foregroundStyle(.secondary) - } - case .available(let version, let asset): - VStack(alignment: .leading, spacing: 10) { - HStack { - Image(systemName: "arrow.down.circle.fill").foregroundColor(.accentColor) - Text("Version \(version) is available!").font(.headline) - } - Button("Download and Install") { - updateChecker.downloadAndUpdate(asset: asset) - } - .buttonStyle(.plain) - .foregroundColor(.accentColor) - } - case .downloading(let progress): - ProgressView("Downloading...", value: progress, total: 1.0) - .progressViewStyle(.linear) - case .downloaded(let path): - HStack { - Image(systemName: "checkmark.circle.fill").foregroundColor(.green) - Text("Download complete!").foregroundStyle(.secondary) - Button("Show in Finder") { - NSWorkspace.shared.activateFileViewerSelecting([path]) - } - .buttonStyle(.plain).font(.caption) - } - case .error(let message): - HStack { - Image(systemName: "xmark.octagon.fill").foregroundColor(.red) - Text("Error: \(message)").foregroundStyle(.secondary) - } - } - - Button("Check for Updates") { - updateChecker.checkForUpdates() - } - .buttonStyle(.plain) - .font(.system(size: 12)) - .foregroundColor(.accentColor.opacity(0.8)) - .padding(.top, 5) - .disabled(isCheckingOrDownloading()) - } - .frame(maxWidth: .infinity, minHeight: 60) - .padding() - .modifier(SettingsContainerModifier()) - - Text("© 2025 Shariq Charolia. All rights reserved.") - .font(.caption) - .foregroundStyle(.tertiary) - .frame(maxWidth: .infinity, alignment: .center) - .padding(.top, 20) - } - .padding(25) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) - .onAppear { - updateChecker.checkForUpdates() - } - } - } - - private func isCheckingOrDownloading() -> Bool { - if case .checking = updateChecker.status { return true } - if case .downloading = updateChecker.status { return true } - return false - } -} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift b/submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift deleted file mode 100644 index f49a3786..00000000 --- a/submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift +++ /dev/null @@ -1,87 +0,0 @@ -// -// SettingsSidebar.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI - -struct SettingsSidebarView: View { - @Binding var selectedSection: SettingsSection? - @State private var searchText = "" - - var body: some View { - VStack(alignment: .leading, spacing: 0) { - Spacer().frame(height: 35) - - List(selection: $selectedSection) { - Section { - ForEach(SettingsSection.allCases) { section in - SidebarRowView(section: section).tag(section) - } - } - } - .listStyle(.sidebar).scrollContentBackground(.hidden) - - Spacer() - - - Button(action: { - NSApp.terminate(nil) - }) { - HStack { - Image(systemName: "power.circle.fill") - .font(.system(size: 15, weight: .bold)) - .foregroundStyle(.red) - .frame(width: 30, height: 30) - .background(Color.red.opacity(0.15)) - .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) - Text("Quit") - .font(.system(size: 15, weight: .medium)) - .foregroundStyle(.white) - } - .padding(.vertical, 3) - .padding(.leading, 12) - } - .buttonStyle(.plain) - .padding(.bottom, 15) - } - } -} - -struct CustomTrafficLightButtons: View { - @Environment(\.window) private var window: NSWindow? - @State private var isHovering = false - var body: some View { - HStack(spacing: 8) { - Button(action: { window?.close() }) { - Image(systemName: "xmark").font(.system(size: 7, weight: .bold, design: .rounded)) - }.buttonStyle(TrafficLightButtonStyle(color: .red, isHovering: isHovering)) - Button(action: { window?.miniaturize(nil) }) { - Image(systemName: "minus").font(.system(size: 7, weight: .bold, design: .rounded)) - }.buttonStyle(TrafficLightButtonStyle(color: .yellow, isHovering: isHovering)) - Button(action: { window?.zoom(nil) }) { - Image(systemName: "plus").font(.system(size: 7, weight: .bold, design: .rounded)) - }.buttonStyle(TrafficLightButtonStyle(color: .green, isHovering: isHovering)) - }.onHover { hovering in withAnimation(.easeInOut(duration: 0.1)) { isHovering = hovering } } - } -} - -struct TrafficLightButtonStyle: ButtonStyle { - let color: Color; let isHovering: Bool - func makeBody(configuration: Configuration) -> some View { - ZStack { Circle().fill(color); configuration.label.foregroundStyle(.black.opacity(0.6)).opacity(isHovering ? 1 : 0) }.frame(width: 12, height: 12) - } -} - -fileprivate struct SidebarRowView: View { - let section: SettingsSection - var body: some View { - HStack(spacing: 12) { - Image(systemName: section.systemImage).font(.system(size: 11, weight: .bold)).foregroundStyle(.white).frame(width: 22, height: 22).background(section.iconBackgroundColor.opacity(0.8).gradient).clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) - Text(section.label).font(.system(size: 13, weight: .medium)).foregroundStyle(.white) - Spacer() - }.padding(.vertical, 3) - } -} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsView.swift b/submissions/sapphire/Sapphire/App Settings/SettingsView.swift deleted file mode 100644 index c78b77ed..00000000 --- a/submissions/sapphire/Sapphire/App Settings/SettingsView.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// SettingsView.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI - - -private struct WindowKey: EnvironmentKey { - static let defaultValue: NSWindow? = nil -} - -extension EnvironmentValues { - var window: NSWindow? { - get { self[WindowKey.self] } - set { self[WindowKey.self] = newValue } - } -} - - -struct SettingsView: View { - @StateObject private var settings = SettingsModel() - @State private var selectedSection: SettingsSection? = .widgets - - var body: some View { - - ZStack { - HStack(spacing: 0) { - SettingsSidebarView(selectedSection: $selectedSection) - .frame(width: 190) - - SettingsDetailView(selectedSection: selectedSection) - } - - WindowDragHandle() - - CustomTrafficLightButtons() - .padding(.horizontal, 16) - .padding(.top, 16) - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) - .zIndex(2) - } - .frame(maxWidth: .infinity, maxHeight: .infinity) - .environmentObject(settings) - .background(.ultraThinMaterial) - .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous)) - } -} - - -struct WindowDragHandle: View { - @Environment(\.window) private var window - - var body: some View { - VStack { - Color.clear - .frame(height: 50) - .contentShape(Rectangle()) - .gesture( - DragGesture(minimumDistance: 0) - .onChanged { value in - if let window = window { - let startPoint = window.frame.origin - let newPoint = NSPoint( - x: startPoint.x + value.translation.width, - y: startPoint.y - value.translation.height - ) - window.setFrameOrigin(newPoint) - } - } - ) - Spacer() - } - .zIndex(1) - } -} diff --git a/submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift b/submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift deleted file mode 100644 index 48dae2e1..00000000 --- a/submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift +++ /dev/null @@ -1,122 +0,0 @@ -// -// UpdateChecker.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI - - - -let currentAppVersion = "Pre-Release" - -struct GitHubReleaseAsset: Codable { - let name: String - let browserDownloadUrl: URL - enum CodingKeys: String, CodingKey { - case name - case browserDownloadUrl = "browser_download_url" - } -} - -struct GitHubRelease: Codable { - let tagName: String - let assets: [GitHubReleaseAsset] - enum CodingKeys: String, CodingKey { - case tagName = "tag_name" - case assets - } -} - -enum UpdateStatus { - case checking - case upToDate - case available(version: String, asset: GitHubReleaseAsset) - case downloading(progress: Double) - case downloaded(path: URL) - case error(String) -} - -@MainActor -class UpdateChecker: NSObject, ObservableObject, URLSessionDownloadDelegate { - @Published var status: UpdateStatus = .checking - private var downloadTask: URLSessionDownloadTask? - - func checkForUpdates() { - self.status = .checking - guard let url = URL(string: "https://api.github.com/repos/cshariq/sapphire/releases/latest") else { - self.status = .error("Invalid URL") - return - } - - URLSession.shared.dataTask(with: url) { data, response, error in - DispatchQueue.main.async { - if let error = error { - self.status = .error(error.localizedDescription) - return - } - guard let data = data else { - self.status = .error("No data received.") - return - } - do { - let release = try JSONDecoder().decode(GitHubRelease.self, from: data) - let latestVersion = release.tagName.trimmingCharacters(in: CharacterSet(charactersIn: "v")) - - if latestVersion.compare(currentAppVersion, options: .numeric) == .orderedDescending { - - if let asset = release.assets.first(where: { $0.name.hasSuffix(".dmg") || $0.name.hasSuffix(".zip") }) { - self.status = .available(version: latestVersion, asset: asset) - } else { - self.status = .error("No suitable asset found.") - } - } else { - self.status = .upToDate - } - } catch { - self.status = .error("Failed to decode response.") - } - } - }.resume() - } - - func downloadAndUpdate(asset: GitHubReleaseAsset) { - let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil) - downloadTask = session.downloadTask(with: asset.browserDownloadUrl) - downloadTask?.resume() - self.status = .downloading(progress: 0) - } - - - func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { - let fileManager = FileManager.default - guard let downloadsURL = fileManager.urls(for: .downloadsDirectory, in: .userDomainMask).first else { - DispatchQueue.main.async { self.status = .error("Could not find Downloads folder.") } - return - } - - let destinationURL = downloadsURL.appendingPathComponent(downloadTask.originalRequest!.url!.lastPathComponent) - - - try? fileManager.removeItem(at: destinationURL) - - do { - try fileManager.copyItem(at: location, to: destinationURL) - DispatchQueue.main.async { - self.status = .downloaded(path: destinationURL) - NSWorkspace.shared.open(destinationURL) - } - } catch { - DispatchQueue.main.async { self.status = .error("Failed to move update to Downloads.") } - } - } - - - func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { - let progress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite) - DispatchQueue.main.async { - self.status = .downloading(progress: progress) - } - } -} diff --git a/submissions/sapphire/Sapphire/App Settings/UserDefault.swift b/submissions/sapphire/Sapphire/App Settings/UserDefault.swift deleted file mode 100644 index 9c993058..00000000 --- a/submissions/sapphire/Sapphire/App Settings/UserDefault.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// UserDefault.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-10. -// - -import SwiftUI -import Combine - - -private let appGroupSuite = UserDefaults(suiteName: "group.com.shariq.sapphire") - -@propertyWrapper -struct UserDefault { - let key: String - let defaultValue: Value - - var wrappedValue: Value { - get { - - guard let data = appGroupSuite?.data(forKey: key) else { - return defaultValue - } - do { - let value = try JSONDecoder().decode(Value.self, from: data) - return value - } catch { - if let encodedDefault = try? JSONEncoder().encode(defaultValue) { - appGroupSuite?.set(encodedDefault, forKey: key) - } - return defaultValue - } - } - set { - do { - let data = try JSONEncoder().encode(newValue) - - appGroupSuite?.set(data, forKey: key) - } catch { - } - } - } -} diff --git a/submissions/sapphire/Sapphire/App/AppDelegate.swift b/submissions/sapphire/Sapphire/App/AppDelegate.swift deleted file mode 100644 index 559a1170..00000000 --- a/submissions/sapphire/Sapphire/App/AppDelegate.swift +++ /dev/null @@ -1,245 +0,0 @@ -// -// AppDelegate.swift -// Sapphire -// -// Created by Shariq Charolia on 2025-07-04. -// - -import Cocoa -import SwiftUI -import Combine -import UserNotifications -import NearbyShare -import ApplicationServices -import IOBluetooth - -@MainActor -@NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate, MainAppDelegate { - - public var notchWindow: NSWindow? - private var cgsSpace: CGSSpace? - private var onboardingWindow: NSWindow? - private var settingsWindow: NSWindow? - - - private var settingsDelegate: SettingsWindowDelegate? - - var spotifyAPIManager: SpotifyAPIManager? - var systemHUDManager: SystemHUDManager? - var notificationManager: NotificationManager? - var desktopManager: DesktopManager? - var focusModeManager: FocusModeManager? - var musicWidget: MusicWidget? - var calendarService: CalendarService? - var batteryMonitor: BatteryMonitor? - var bluetoothManager: BluetoothManager? - var audioDeviceManager: AudioDeviceManager? - var eyeBreakManager: EyeBreakManager? - var timerManager: TimerManager? - var weatherActivityViewModel: WeatherActivityViewModel? - var contentPickerHelper: ContentPickerHelper? - var geminiLiveManager: GeminiLiveManager? - var settingsModel: SettingsModel? - var activeAppMonitor: ActiveAppMonitor? - var liveActivityManager: LiveActivityManager? - - func applicationDidFinishLaunching(_ aNotification: Notification) { - - if UserDefaults.standard.bool(forKey: "hasCompletedOnboarding") { - startMainApp() - } else { - showOnboardingWindow() - } - } - - func showOnboardingWindow() { - if onboardingWindow == nil { - let window = NSWindow( - contentRect: NSRect(x: 0, y: 0, width: 900, height: 700), - styleMask: [.borderless], - backing: .buffered, defer: false - ) - - window.center() - window.title = "Welcome to Sapphire" - window.isMovableByWindowBackground = true - window.titlebarAppearsTransparent = true - - - window.isOpaque = false - window.backgroundColor = .clear - - - let hostingView = NSHostingView(rootView: OnboardingView(onComplete: { self.onboardingDidComplete() })) - hostingView.wantsLayer = true - hostingView.layer?.backgroundColor = NSColor.clear.cgColor - - window.contentView = hostingView - onboardingWindow = window - } - - - onboardingWindow?.makeKeyAndOrderFront(nil) - onboardingWindow?.level = .modalPanel - - - NSApp.activate(ignoringOtherApps: true) - } - - - func onboardingDidComplete() { - UserDefaults.standard.set(true, forKey: "hasCompletedOnboarding") - - self.onboardingWindow?.orderOut(nil) - self.onboardingWindow = nil - - startMainApp() - } - - func startMainApp() { - self.spotifyAPIManager = .shared; self.systemHUDManager = .shared; self.notificationManager = NotificationManager() - self.desktopManager = DesktopManager(); self.focusModeManager = FocusModeManager(); self.musicWidget = MusicWidget() - self.calendarService = CalendarService(); self.batteryMonitor = BatteryMonitor(); self.bluetoothManager = BluetoothManager() - self.audioDeviceManager = AudioDeviceManager(); self.eyeBreakManager = EyeBreakManager(); self.timerManager = TimerManager() - self.weatherActivityViewModel = WeatherActivityViewModel(); self.contentPickerHelper = ContentPickerHelper() - self.geminiLiveManager = GeminiLiveManager(); self.settingsModel = SettingsModel(); self.activeAppMonitor = .shared - - self.liveActivityManager = LiveActivityManager( - systemHUDManager: systemHUDManager!, notificationManager: notificationManager!, desktopManager: desktopManager!, - focusModeManager: focusModeManager!, musicWidget: musicWidget!, calendarService: calendarService!, - batteryMonitor: batteryMonitor!, bluetoothManager: bluetoothManager!, audioDeviceManager: audioDeviceManager!, - eyeBreakManager: eyeBreakManager!, timerManager: timerManager!, weatherActivityViewModel: weatherActivityViewModel!, - geminiLiveManager: geminiLiveManager!, settingsModel: settingsModel!, activeAppMonitor: activeAppMonitor! - ) - - OSDManager.disableSystemHUD() - _ = IOBluetoothDevice.pairedDevices() - NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(handleGetURL), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL)) - - createNotchWindow() - - NotificationCenter.default.addObserver(self, selector: #selector(screenParametersChanged), name: NSApplication.didChangeScreenParametersNotification, object: nil) - UNUserNotificationCenter.current().delegate = self - NearbyConnectionManager.shared.mainAppDelegate = self - NearbyConnectionManager.shared.becomeVisible() - - - transitionToAgentApp() - } - - private func transitionToAgentApp() { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - if NSApp.activationPolicy() != .accessory { - NSApp.setActivationPolicy(.accessory) - } - } - } - - func applicationWillTerminate(_ aNotification: Notification) { - OSDManager.enableSystemHUD() - NSAppleEventManager.shared().removeEventHandler(forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL)) - cgsSpace = nil - NotificationCenter.default.removeObserver(self, name: NSApplication.didChangeScreenParametersNotification, object: nil) - } - - @objc func handleGetURL(event: NSAppleEventDescriptor!, withReplyEvent: NSAppleEventDescriptor!) { - guard let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue, let url = URL(string: urlString) else { return } - if url.scheme == "dynamicnotch" { spotifyAPIManager?.handleRedirect(url: url) } - } - - func createNotchWindow() { - notchWindow?.orderOut(nil); notchWindow?.close() - guard let mainScreen = NSScreen.main else { return } - let screenFrame = mainScreen.frame - let paddedWindowWidth: CGFloat = 1200, paddedWindowHeight: CGFloat = 600 - let windowOriginX = (screenFrame.width - paddedWindowWidth) / 2, windowOriginY = screenFrame.maxY - paddedWindowHeight - let windowRect = NSRect(x: windowOriginX, y: windowOriginY, width: paddedWindowWidth, height: paddedWindowHeight) - let newWindow = NSWindow(contentRect: windowRect, styleMask: .borderless, backing: .buffered, defer: false) - self.notchWindow = newWindow - guard let window = self.notchWindow else { return } - window.isOpaque = false; window.backgroundColor = .clear; window.hasShadow = false; window.level = .statusBar - window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary, .stationary] - window.ignoresMouseEvents = true - if self.cgsSpace == nil { self.cgsSpace = CGSSpace() }; self.cgsSpace?.windows.removeAll(); self.cgsSpace?.windows.insert(window) - - let notchControllerView = NotchController(notchWindow: window) - let rootViewContainer = VStack(spacing: 0) { notchControllerView; Spacer() }.frame(width: paddedWindowWidth, height: paddedWindowHeight) - - let hostingView = NSHostingView( - rootView: rootViewContainer - .environmentObject(systemHUDManager!).environmentObject(musicWidget!).environmentObject(spotifyAPIManager!) - .environmentObject(liveActivityManager!).environmentObject(audioDeviceManager!).environmentObject(bluetoothManager!) - .environmentObject(notificationManager!).environmentObject(desktopManager!).environmentObject(focusModeManager!) - .environmentObject(eyeBreakManager!).environmentObject(timerManager!).environmentObject(contentPickerHelper!) - .environmentObject(geminiLiveManager!).environmentObject(settingsModel!).environmentObject(activeAppMonitor!) - ) - hostingView.frame = NSRect(origin: .zero, size: windowRect.size) - hostingView.autoresizingMask = [.width, .height] - hostingView.wantsLayer = true; hostingView.layer?.backgroundColor = NSColor.clear.cgColor - window.contentView = hostingView; window.makeKeyAndOrderFront(nil) - } - - func openSettingsWindow() { - if let window = settingsWindow { - NSApp.setActivationPolicy(.regular) - window.makeKeyAndOrderFront(nil) - NSApp.activate(ignoringOtherApps: true) - return - } - let newWindow = NSWindow( - contentRect: NSRect(x: 0, y: 0, width: 950, height: 650), - styleMask: [.titled, .closable, .miniaturizable, .resizable], - backing: .buffered, defer: false - ) - newWindow.center(); newWindow.isMovableByWindowBackground = true - newWindow.title = "Sapphire Settings" - - let settingsView = SettingsView() - let hostingView = NSHostingView(rootView: settingsView.environment(\.window, newWindow).environmentObject(settingsModel!)) - newWindow.contentView = hostingView - - - self.settingsDelegate = SettingsWindowDelegate { - NSApp.setActivationPolicy(.accessory) - self.settingsWindow = nil - } - newWindow.delegate = self.settingsDelegate - - self.settingsWindow = newWindow - NSApp.setActivationPolicy(.regular) - newWindow.makeKeyAndOrderFront(nil) - NSApp.activate(ignoringOtherApps: true) - } - - @objc func screenParametersChanged(notification: Notification) { - guard let window = self.notchWindow, let mainScreen = NSScreen.main else { createNotchWindow(); return } - let screenFrame = mainScreen.frame, windowSize = window.frame.size - let newOriginX = (screenFrame.width - windowSize.width) / 2, newOriginY = screenFrame.maxY - windowSize.height - window.setFrame(NSRect(x: newOriginX, y: newOriginY, width: windowSize.width, height: windowSize.height), display: true, animate: false) - } - - func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, fileURLs: [URL]) { - DispatchQueue.main.async { self.liveActivityManager?.startNearDropActivity(transfer: transfer, device: device, fileURLs: fileURLs) } - } - func incomingTransfer(id: String, didUpdateProgress progress: Double) { - DispatchQueue.main.async { self.liveActivityManager?.updateNearDropProgress(id: id, progress: progress) } - } - func incomingTransfer(id: String, didFinishWith error: Error?) { - DispatchQueue.main.async { self.liveActivityManager?.finishNearDropTransfer(id: id, error: error) } - } - func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { - if let transferID = response.notification.request.content.userInfo["transferID"] as? String { - let accepted = response.actionIdentifier == "ACCEPT" - NearbyConnectionManager.shared.submitUserConsent(transferID: transferID, accept: accepted) - if accepted { liveActivityManager?.updateNearDropState(to: .inProgress) } else { liveActivityManager?.clearNearDropActivity() } - } - completionHandler() - } -} - -fileprivate class SettingsWindowDelegate: NSObject, NSWindowDelegate { - var onClose: () -> Void - init(onClose: @escaping () -> Void) { self.onClose = onClose } - func windowWillClose(_ notification: Notification) { onClose() } -} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1.png deleted file mode 100644 index d79f61f43dc7cfc071994fd9c162097f205f0b27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 118918 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 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x 1.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x 1.png deleted file mode 100644 index 37b36f1579225e5619147545a7d808bb4dd71cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32336 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 z 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 00000000..a0186a00 --- /dev/null +++ b/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist b/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..d4823260 --- /dev/null +++ b/submissions/sapphire/Sapphire.xcodeproj/xcuserdata/Shariq.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,42 @@ + + + + + SchemeUserState + + DynamicNotch.xcscheme_^#shared#^_ + + orderHint + 0 + + NearbyShare.xcscheme_^#shared#^_ + + orderHint + 1 + + Sapphire.xcscheme_^#shared#^_ + + orderHint + 0 + + + SuppressBuildableAutocreation + + DA46CF752DCBCA0000F00EC5 + + primary + + + DA46CF862DCBCA0100F00EC5 + + primary + + + DA46CF902DCBCA0100F00EC5 + + primary + + + + + diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift b/submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift new file mode 100644 index 00000000..e35ea4c2 --- /dev/null +++ b/submissions/sapphire/Sapphire/App Settings/SettingsComponents.swift @@ -0,0 +1,380 @@ +// +// SettingsComponents.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI + + + +struct InfoContainer: View { + let text: String + let iconName: String + let color: Color + + var body: some View { + HStack(alignment: .top, spacing: 12) { + Image(systemName: iconName) + .font(.title3) + .foregroundColor(color) + .padding(.top, 2) + + Text(text) + .font(.system(size: 13)) + .foregroundStyle(.white.opacity(0.8)) + .lineSpacing(4) + } + .padding() + .background(color.opacity(0.15)) + .clipShape(RoundedRectangle(cornerRadius: 16, style: .continuous)) + .overlay( + RoundedRectangle(cornerRadius: 16, style: .continuous) + .stroke(color.opacity(0.5), lineWidth: 1) + ) + } +} + +struct GeneralSettingToggleRowView: View { + let setting: GeneralSettingType + @Binding var isEnabled: Bool + + var body: some View { + HStack(spacing: 15) { + Image(systemName: setting.systemImage) + .font(.system(size: 18, weight: .medium)) + .foregroundColor(setting.iconColor) + .frame(width: 36, height: 36) + .background(setting.iconColor.opacity(0.15)) + .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) + + Text(setting.displayName) + .font(.system(size: 14, weight: .medium)) + .foregroundStyle(.white) + + Spacer() + + Toggle("", isOn: $isEnabled) + .labelsHidden() + .toggleStyle(.switch) + } + .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) + } +} + +struct WidgetRowView: View { + let widgetType: WidgetType + @EnvironmentObject var settings: SettingsModel + + private var isEnabledBinding: Binding { + switch widgetType { + case .weather: return $settings.settings.weatherWidgetEnabled + case .calendar: return $settings.settings.calendarWidgetEnabled + case .shortcuts: return $settings.settings.shortcutsWidgetEnabled + case .music: return $settings.settings.musicWidgetEnabled + } + } + + var body: some View { + HStack { + Text(widgetType.displayName) + .font(.system(size: 14, weight: .medium)) + .foregroundStyle(.white) + + Spacer() + + Toggle("", isOn: isEnabledBinding) + .labelsHidden() + .toggleStyle(.switch) + + Image(systemName: "line.3.horizontal") + .font(.system(size: 16, weight: .medium)) + .foregroundStyle(.white.opacity(0.6)) + .padding(.leading, 8) + } + .padding(EdgeInsets(top: 18, leading: 20, bottom: 18, trailing: 20)) + } +} + +struct LiveActivityRowView: View { + let activityType: LiveActivityType + @EnvironmentObject var settings: SettingsModel + + private var isEnabledBinding: Binding { + switch activityType { + case .music: return $settings.settings.musicLiveActivityEnabled + case .weather: return $settings.settings.weatherLiveActivityEnabled + case .calendar: return $settings.settings.calendarLiveActivityEnabled + case .timers: return $settings.settings.timersLiveActivityEnabled + case .battery: return $settings.settings.batteryLiveActivityEnabled + case .eyeBreak: return $settings.settings.eyeBreakLiveActivityEnabled + case .desktop: return $settings.settings.desktopLiveActivityEnabled + + case .focus: return $settings.settings.focusLiveActivityEnabled + } + } + + var body: some View { + HStack { + Text(activityType.displayName) + .font(.system(size: 14, weight: .medium)) + .foregroundStyle(.white) + + Spacer() + + Toggle("", isOn: isEnabledBinding) + .labelsHidden() + .toggleStyle(.switch) + + Image(systemName: "line.3.horizontal") + .font(.system(size: 16, weight: .medium)) + .foregroundStyle(.white.opacity(0.6)) + .padding(.leading, 8) + } + .padding(EdgeInsets(top: 18, leading: 20, bottom: 18, trailing: 20)) + } +} + + +struct NotificationToggleRowView: View { + let source: NotificationSource + @EnvironmentObject var settings: SettingsModel + + private var isEnabledBinding: Binding { + switch source { + case .iMessage: return $settings.settings.iMessageNotificationsEnabled + case .faceTime: return $settings.settings.faceTimeNotificationsEnabled + case .airDrop: return $settings.settings.airDropNotificationsEnabled + } + } + + var body: some View { + HStack(spacing: 15) { + Image(systemName: source.systemImage) + .font(.system(size: 18, weight: .medium)) + .foregroundColor(source.iconColor) + .frame(width: 36, height: 36) + .background(source.iconColor.opacity(0.15)) + .clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous)) + + Text(source.displayName) + .font(.system(size: 14, weight: .medium)) + .foregroundStyle(.white) + + Spacer() + + Toggle("", isOn: isEnabledBinding) + .labelsHidden() + .toggleStyle(.switch) + } + .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) + } +} + +struct SystemAppRowView: View { + let app: SystemApp + @Binding var isEnabled: Bool + + var body: some View { + HStack(spacing: 12) { + Image(nsImage: app.icon) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 28, height: 28) + .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) + + Text(app.name) + .font(.system(size: 13)) + .foregroundStyle(.white) + + Spacer() + + Toggle("", isOn: $isEnabled) + .labelsHidden() + .toggleStyle(.switch) + } + .padding(EdgeInsets(top: 8, leading: 20, bottom: 8, trailing: 20)) + } +} + +struct ReorderableVStack: View { + @Binding var items: [Item] + @ViewBuilder var content: (Item) -> Content + + @State private var draggingItem: Item? + @State private var dragOffset: CGSize = .zero + + init(items: Binding<[Item]>, @ViewBuilder content: @escaping (Item) -> Content) { + self._items = items + self.content = content + } + + var body: some View { + VStack(spacing: 0) { + ForEach(items) { item in + content(item) + .offset(y: draggingItem == item ? dragOffset.height : 0) + .opacity(draggingItem == item ? 0.75 : 1) + .zIndex(draggingItem == item ? 1 : 0) + .contentShape(Rectangle()) + .gesture( + DragGesture(minimumDistance: 10, coordinateSpace: .global) + .onChanged { value in + if draggingItem == nil { + draggingItem = item + } + dragOffset = value.translation + } + .onEnded { value in + if let draggingItem = draggingItem { + moveItem(draggedItem: draggingItem, with: value) + } + withAnimation { + draggingItem = nil + dragOffset = .zero + } + } + ) + + if item.id != items.last?.id { + Rectangle() + .fill(Color.white.opacity(0.2)) + .frame(height: 1) + } + } + } + } + + private func moveItem(draggedItem: Item, with value: DragGesture.Value) { + guard let fromIndex = items.firstIndex(of: draggedItem) else { return } + + let rowHeight: CGFloat = 61.0 + let verticalTranslation = value.translation.height + let moveOffset = Int((verticalTranslation / rowHeight).rounded()) + + var toIndex = fromIndex + moveOffset + toIndex = max(0, min(items.count - 1, toIndex)) + + if fromIndex != toIndex { + withAnimation(.spring()) { + let itemToMove = items.remove(at: fromIndex) + items.insert(itemToMove, at: toIndex) + } + } + } +} + +struct CustomBatterySlider: View { + @Binding var value: Double + let range: ClosedRange + + private let horizontalPadding: CGFloat = 8 + + var body: some View { + GeometryReader { geometry in + let totalWidth = geometry.size.width + let thumbSize: CGFloat = 40 + + let trackUsableWidth = totalWidth - (2 * horizontalPadding) + let thumbUsableWidth = trackUsableWidth - thumbSize + + let progress = (value - range.lowerBound) / (range.upperBound - range.lowerBound) + + let clampedProgress = max(0.0, min(1.0, progress)) + + let thumbX = (clampedProgress * thumbUsableWidth) + horizontalPadding + (thumbSize / 2) + + ZStack(alignment: .leading) { + Capsule() + .fill(Color.black.opacity(0.4)) + .padding(.horizontal, horizontalPadding) + + Circle() + .fill(Color(white: 0.8)) + .frame(width: thumbSize, height: thumbSize) + .overlay( + Text("\(Int(value.rounded()))") + .font(.system(size: 14, weight: .bold)) + .foregroundColor(.black) + ) + .position(x: thumbX, y: geometry.size.height / 2) + } + .gesture( + DragGesture(minimumDistance: 0) + .onChanged { gestureValue in + let newX = min(max(gestureValue.location.x, horizontalPadding), totalWidth - horizontalPadding) + let newProgress = (newX - horizontalPadding) / thumbUsableWidth + var newValue = (range.upperBound - range.lowerBound) * Double(newProgress) + range.lowerBound + + newValue = max(range.lowerBound, min(range.upperBound, newValue)) + + self.value = newValue + } + ) + } + } +} + +struct CustomSliderRowView: View { + let label: String + @Binding var value: Double + let range: ClosedRange + let specifier: String + + var body: some View { + VStack(alignment: .leading, spacing: 8) { + HStack { + Text(label) + Spacer() + Text(String(format: specifier, value)) + } + Slider(value: $value, in: range) + } + .padding() + } +} + + +struct SettingsContainerModifier: ViewModifier { + func body(content: Content) -> some View { + content + .background(Color.black.opacity(0.15)) + .clipShape(RoundedRectangle(cornerRadius: 24, style: .continuous)) + .overlay( + RoundedRectangle(cornerRadius: 24, style: .continuous) + .stroke(Color.white.opacity(0.1), lineWidth: 1) + ) + } +} + +struct SettingsGroup: View { + let content: Content + init(@ViewBuilder content: () -> Content) { self.content = content() } + + var body: some View { + VStack(spacing: 0) { content } + .padding(.horizontal) + .background( + RoundedRectangle(cornerRadius: 10, style: .continuous) + .fill(.background.opacity(0.15)) + ) + } +} + +struct SettingsDetailRow: View { + let title: String + let content: Content + init(title: String, @ViewBuilder content: () -> Content) { + self.title = title + self.content = content() + } + + var body: some View { + HStack { + Text(title) + Spacer() + HStack { content }.foregroundStyle(.secondary) + }.padding(.vertical, 10) + } +} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsModel.swift b/submissions/sapphire/Sapphire/App Settings/SettingsModel.swift new file mode 100644 index 00000000..2cd76851 --- /dev/null +++ b/submissions/sapphire/Sapphire/App Settings/SettingsModel.swift @@ -0,0 +1,211 @@ +// +// SettingsModel.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI +import AppKit +import IOBluetooth +import Combine + + +class SettingsModel: ObservableObject { + let settingsPublisher = PassthroughSubject() + @UserDefault(key: "appSettings", defaultValue: Settings()) + var settings: Settings { + willSet { settingsPublisher.send(newValue); objectWillChange.send() } + } +} + + +struct Settings: Codable, Equatable { + var liveActivityOrder: [LiveActivityType] = LiveActivityType.allCases + var musicLiveActivityEnabled: Bool = true, weatherLiveActivityEnabled: Bool = true, calendarLiveActivityEnabled: Bool = true, timersLiveActivityEnabled: Bool = true, batteryLiveActivityEnabled: Bool = true, eyeBreakLiveActivityEnabled: Bool = true, desktopLiveActivityEnabled: Bool = true, focusLiveActivityEnabled: Bool = true + var musicWaveformIsVolumeSensitive: Bool = true, dropboxIconEnabled: Bool = true, batteryEstimatorEnabled: Bool = true, geminiEnabled: Bool = true, pinEnabled: Bool = true + var widgetOrder: [WidgetType] = [.music, .weather, .calendar, .shortcuts] + var musicWidgetEnabled: Bool = true, weatherWidgetEnabled: Bool = true, calendarWidgetEnabled: Bool = true, shortcutsWidgetEnabled: Bool = true + var bluetoothNotifyLowBattery: Bool = true, bluetoothNotifySound: Bool = true, masterNotificationsEnabled: Bool = true, iMessageNotificationsEnabled: Bool = true, airDropNotificationsEnabled: Bool = true, faceTimeNotificationsEnabled: Bool = true, systemNotificationsEnabled: Bool = true + var appNotificationStates: [String: Bool] = [:] + var neardropEnabled: Bool = true, neardropDeviceDisplayName: String = "My Mac", neardropDownloadLocationPath: String = FileManager.default.urls( + for: .downloadsDirectory, + in: .userDomainMask + ).first!.path, neardropOpenOnClick: Bool = true + var showNowPlayingInMenuBar: Bool = true, spotifyClientId: String = "", spotifyClientSecret: String = "", defaultMusicPlayer: DefaultMusicPlayer = .appleMusic, showLyricsInLiveActivity: Bool = false + var musicAppStates: [String: Bool] = [:] + var musicOpenOnClick: Bool = true, weatherDefaultLocation: String = "New York, NY", weatherUseCelsius: Bool = false, weatherOpenOnClick: Bool = false + var calendarShowAllDayEvents: Bool = true, calendarStartOfWeek: Day = .sunday + var eyeBreakWorkInterval: Double = 20, eyeBreakBreakDuration: Double = 20, eyeBreakSoundAlerts: Bool = true + var enableVolumeHUD: Bool = true, volumeHUDStyle: HUDStyle = .default, volumeHUDSoundEnabled: Bool = true + var enableBrightnessHUD: Bool = true, brightnessHUDStyle: HUDStyle = .default + var batteryNotifyForLowBattery: Bool = true, batteryNotifyWithSound: Bool = true, batteryNotifyChargingState: Bool = true + var geminiApiKey: String = "" +} + + +enum WidgetType: String, Codable, CaseIterable, Identifiable, Equatable { + case weather, + calendar, + shortcuts, + music; var id: String { self.rawValue }; var displayName: String { + self.rawValue.prefix(1).uppercased() + self.rawValue.dropFirst() + } +} +enum LiveActivityType: String, Codable, CaseIterable, Identifiable, Equatable { + case eyeBreak, + focus, + desktop, + battery, + timers, + calendar, + weather, + music; var id: String { self.rawValue }; var displayName: String { + switch self { + case .music: "Music"; case .weather: "Weather"; case .calendar: "Calendar"; case .timers: "Timers"; case .battery: "Battery"; case .eyeBreak: "Eye Break"; case .desktop: "Desktop"; case .focus: "Focus" + } + } +} +enum NotificationSource: String, CaseIterable, Identifiable { + case iMessage, + faceTime, + airDrop; var id: String { rawValue }; var displayName: String { switch self { case .iMessage: "iMessage"; case .faceTime: "FaceTime"; case .airDrop: "AirDrop" } }; var systemImage: String { switch self { case .iMessage: "message.fill"; case .faceTime: "video.fill"; case .airDrop: "shareplay" } }; var iconColor: Color { + switch self { + case .iMessage, + .faceTime: .green; case .airDrop: .blue + } + } +} +enum GeneralSettingType: String, CaseIterable, Identifiable, Equatable { + case dropboxIcon, + batteryEstimator, + gemini, + pin; var id: String { self.rawValue }; var displayName: String { switch self { case .dropboxIcon: "Dropbox Icon"; case .batteryEstimator: "Battery Estimator"; case .gemini: "Gemini Integration"; case .pin: "Pin Widgets" } }; var systemImage: String { switch self { case .dropboxIcon: "cloud.fill"; case .batteryEstimator: "gauge.high"; case .gemini: "sparkles"; case .pin: "pin.fill" } }; var iconColor: Color { + switch self { + case .dropboxIcon: .blue; case .batteryEstimator: .green; case .gemini: .purple; case .pin: .gray + } + } +} +struct SystemApp: Identifiable, Equatable { + let id: String, + name: String, + icon: NSImage, + isBrowser: Bool +} +enum Day: String, Codable, CaseIterable, Identifiable { + case sunday, + monday; var id: String { self.rawValue.capitalized } +} +enum DefaultMusicPlayer: String, Codable, CaseIterable, Identifiable { + case appleMusic, + spotify; var id: String { self.rawValue }; var displayName: String { + switch self { + case .appleMusic: "Apple Music"; case .spotify: "Spotify" + } + } +} +enum HUDStyle: String, Codable, CaseIterable, Identifiable { + case `default`, + thin; var id: String { self.rawValue.capitalized } +} +enum SettingsSection: String, CaseIterable, Identifiable { + case general, + widgets, + liveActivities, + battery, + bluetooth, + hud, + notifications, + neardrop, + music, + weather, + calendar, + eyeBreak, + gemini, + about; var id: String { self.rawValue }; var label: String { switch self { case .general: "General"; case .widgets: "Widgets"; case .liveActivities: "Live Activities"; case .battery: "Battery"; case .bluetooth: "Bluetooth"; case .hud: "HUD"; case .notifications: "Notifications"; case .neardrop: "Nearby Share"; case .music: "Music"; case .weather: "Weather"; case .calendar: "Calendar"; case .eyeBreak: "Eye Break"; case .gemini: "Gemini"; case .about: "About" } }; var systemImage: String { switch self { case .general: "gear"; case .widgets: "square.grid.2x2.fill"; case .liveActivities: "bolt.badge.a.fill"; case .battery: "battery.100"; case .bluetooth: "bolt.horizontal.circle.fill"; case .hud: "macwindow.on.rectangle"; case .notifications: "bell"; case .neardrop: "shareplay"; case .music: "music.note"; case .weather: "cloud.sun.fill"; case .calendar: "calendar"; case .eyeBreak: "eye.fill"; case .gemini: "sparkles"; case .about: "info.circle" } }; var iconBackgroundColor: Color { + switch self { + case .general: .gray; case .widgets: .purple; case .liveActivities: .cyan; case .battery: .green; case .bluetooth: .blue; case .hud: .indigo; case .notifications: .red; case .neardrop: .blue; case .music: .pink; case .weather: .blue; case .calendar: .red; case .eyeBreak: .teal; case .gemini: .purple; case .about: .blue + } + } +} + +@MainActor +class SystemAppFetcher: ObservableObject { + @Published var apps: [SystemApp] = [] + @Published var foundBundleIDs: Set = [] + + func fetchApps() { + DispatchQueue.global(qos: .userInitiated).async { + var fetchedApps: [SystemApp] = [] + + var seenBundleIDs = Set() + + let fileManager = FileManager.default + let searchPaths = ["/System/Applications", "/Applications", NSSearchPathForDirectoriesInDomains(.applicationDirectory, .userDomainMask, true).first].compactMap { + $0 + } + + for path in searchPaths { + do { + let appURLs = try fileManager.contentsOfDirectory( + at: URL(fileURLWithPath: path), + includingPropertiesForKeys: [.isApplicationKey], + options: .skipsHiddenFiles + ) + for url in appURLs where url.pathExtension == "app" { + guard let bundle = Bundle(url: url), let bundleId = bundle.bundleIdentifier else { + continue + } + + + + if !seenBundleIDs.contains(bundleId) { + let name = fileManager.displayName(atPath: url.path) + let icon = NSWorkspace.shared.icon( + forFile: url.path + ) + let isBrowser = self.isBrowser(bundle: bundle) + let app = SystemApp( + id: bundleId, + name: name, + icon: icon, + isBrowser: isBrowser + ) + + fetchedApps.append(app) + + seenBundleIDs.insert(bundleId) + } + } + } catch { + + } + } + + DispatchQueue.main.async { + self.apps = fetchedApps + .sorted { + $0.name + .localizedCaseInsensitiveCompare( + $1.name + ) == .orderedAscending + } + self.foundBundleIDs = seenBundleIDs + } + } + } + + private func isBrowser(bundle: Bundle?) -> Bool { + guard let bundle = bundle, let urlTypes = bundle.infoDictionary?["CFBundleURLTypes"] as? [[String: Any]] else { + return false + } + for type in urlTypes { + if let schemes = type["CFBundleURLSchemes"] as? [String], schemes + .contains("http") || schemes + .contains("https") { + return true + } + } + return false + } +} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift b/submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift new file mode 100644 index 00000000..f8b0ff3d --- /dev/null +++ b/submissions/sapphire/Sapphire/App Settings/SettingsPanes.swift @@ -0,0 +1,886 @@ +// +// SettingsPanes.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI + + +struct SettingsDetailView: View { + var selectedSection: SettingsSection? + var body: some View { + ZStack { + GeneralSettingsView().opacity(selectedSection == .general ? 1 : 0) + WidgetsSettingsView().opacity(selectedSection == .widgets ? 1 : 0) + LiveActivitiesSettingsView().opacity(selectedSection == .liveActivities ? 1 : 0) + BatterySettingsView().opacity(selectedSection == .battery ? 1 : 0) + BluetoothSettingsView().opacity(selectedSection == .bluetooth ? 1 : 0) + HUDSettingsView().opacity(selectedSection == .hud ? 1 : 0) + NotificationsSettingsView().opacity(selectedSection == .notifications ? 1 : 0) + NeardropSettingsView().opacity(selectedSection == .neardrop ? 1 : 0) + MusicSettingsView().opacity(selectedSection == .music ? 1 : 0) + WeatherSettingsView().opacity(selectedSection == .weather ? 1 : 0) + CalendarSettingsView().opacity(selectedSection == .calendar ? 1 : 0) + EyeBreakSettingsView().opacity(selectedSection == .eyeBreak ? 1 : 0) + GeminiSettingsView().opacity(selectedSection == .gemini ? 1 : 0) + AboutSettingsView().opacity(selectedSection == .about ? 1 : 0) + + if selectedSection == nil { + VStack { Image(systemName: "sidebar.left").font(.system(size: 50)).foregroundStyle(.tertiary); Text("Select a category").font(.title).foregroundStyle(.secondary) }.frame(maxWidth: .infinity, maxHeight: .infinity) + } + }.animation(.easeOut(duration: 0.15), value: selectedSection) + } +} + + + +struct GeneralSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("General") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(spacing: 0) { + ForEach(GeneralSettingType.allCases) { setting in + GeneralSettingToggleRowView(setting: setting, isEnabled: binding(for: setting)) + if setting != GeneralSettingType.allCases.last { + Rectangle() + .fill(Color.white.opacity(0.2)) + .frame(height: 1) + .padding(.leading, 60) + } + } + } + .modifier(SettingsContainerModifier()) + } + .padding(25) + } + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + } + + private func binding(for setting: GeneralSettingType) -> Binding { + switch setting { + case .dropboxIcon: return $settings.settings.dropboxIconEnabled + case .batteryEstimator: return $settings.settings.batteryEstimatorEnabled + case .gemini: return $settings.settings.geminiEnabled + case .pin: return $settings.settings.pinEnabled + } + } +} + +struct WidgetsSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Widgets").font(.largeTitle.bold()).padding(.bottom) + + ReorderableVStack(items: $settings.settings.widgetOrder) { widget in + WidgetRowView(widgetType: widget) + } + .modifier(SettingsContainerModifier()) + } + .padding(25) + } + } +} + +struct LiveActivitiesSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Live Activities").font(.largeTitle.bold()).padding(.bottom) + + ReorderableVStack(items: $settings.settings.liveActivityOrder) { activity in + LiveActivityRowView(activityType: activity) + } + .modifier(SettingsContainerModifier()) + } + .padding(25) + } + } +} + +struct NotificationsSettingsView: View { + @StateObject private var appFetcher = SystemAppFetcher() + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Notifications") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(spacing: 0) { + HStack { + Text("Enable Notifications") + .font(.system(size: 14, weight: .medium)) + Spacer() + Toggle("", isOn: $settings.settings.masterNotificationsEnabled) + .labelsHidden() + .toggleStyle(.switch) + .animation(.default, value: settings.settings.masterNotificationsEnabled) + } + .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) + } + .modifier(SettingsContainerModifier()) + + VStack(spacing: 20) { + VStack(spacing: 0) { + ForEach(NotificationSource.allCases) { source in + NotificationToggleRowView(source: source) + if source != NotificationSource.allCases.last { + Rectangle() + .fill(Color.white.opacity(0.2)) + .frame(height: 1) + .padding(.leading, 60) + } + } + } + + VStack(alignment: .leading, spacing: 10) { + HStack { + Text("System Notifications") + .font(.system(size: 14, weight: .medium)) + Spacer() + Toggle("", isOn: $settings.settings.systemNotificationsEnabled) + .labelsHidden() + .toggleStyle(.switch) + .animation(.default, value: settings.settings.systemNotificationsEnabled) + } + .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 60) + + Text("Allow Notifications From:") + .font(.headline) + .padding(.horizontal, 20) + .padding(.vertical, 10) + + ScrollView { + VStack(spacing: 0) { + ForEach(appFetcher.apps) { app in + SystemAppRowView(app: app, isEnabled: binding(for: app)) + if app.id != appFetcher.apps.last?.id { + Rectangle() + .fill(Color.white.opacity(0.2)) + .frame(height: 1) + .padding(.leading, 50) + } + } + } + } + .frame(maxHeight: 360) + } + .disabled(!settings.settings.systemNotificationsEnabled) + .opacity(settings.settings.systemNotificationsEnabled ? 1.0 : 0.5) + } + .modifier(SettingsContainerModifier()) + .disabled(!settings.settings.masterNotificationsEnabled) + .opacity(settings.settings.masterNotificationsEnabled ? 1.0 : 0.5) + .animation(.easeInOut, value: settings.settings.masterNotificationsEnabled) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .onAppear { + appFetcher.fetchApps() + } + } + } + + private func binding(for app: SystemApp) -> Binding { + return .init( + get: { settings.settings.appNotificationStates[app.id, default: true] }, + set: { settings.settings.appNotificationStates[app.id] = $0 } + ) + } +} + + +struct BatterySettingsView: View { + @EnvironmentObject var settings: SettingsModel + @State private var batteryLimit: Double = 80.0 + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Battery") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(alignment: .leading, spacing: 0) { + HStack { + Text("Notify on Charging State Change") + Spacer() + Toggle("", isOn: $settings.settings.batteryNotifyChargingState) + .labelsHidden().toggleStyle(.switch) + } + .padding() + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Notify for Low Battery") + Spacer() + Toggle("", isOn: $settings.settings.batteryNotifyForLowBattery) + .labelsHidden().toggleStyle(.switch) + } + .padding() + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Notify with Sound") + Spacer() + Toggle("", isOn: $settings.settings.batteryNotifyWithSound) + .labelsHidden().toggleStyle(.switch) + } + .padding() + .disabled(!settings.settings.batteryNotifyForLowBattery) + .opacity(settings.settings.batteryNotifyForLowBattery ? 1.0 : 0.5) + .animation(.easeInOut, value: settings.settings.batteryNotifyForLowBattery) + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + VStack(alignment: .leading, spacing: 16) { + Text("Battery Limit: \(Int(batteryLimit))%") + .font(.system(size: 16, weight: .medium)) + .foregroundStyle(.white.opacity(0.9)) + + CustomBatterySlider(value: $batteryLimit, range: 20...100) + .frame(height: 50) + } + .padding() + } + .modifier(SettingsContainerModifier()) + + if batteryLimit < 50 { + InfoContainer( + text: "Setting the battery limit to lower than 50% isn't recommended as it can cause your battery to die quickly.", + iconName: "exclamationmark.triangle.fill", + color: .yellow + ) + .transition(.opacity.combined(with: .move(edge: .top))) + } + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .animation(.easeInOut, value: batteryLimit < 50) + } + } +} + + +struct GeminiSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading) { + Text("Gemini") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(alignment: .leading, spacing: 8) { + Text("Gemini API Key") + .font(.system(size: 14, weight: .medium)) + + SecureField("Enter your API key", text: $settings.settings.geminiApiKey) + .textFieldStyle(.plain) + .padding(8) + .background(Color.black.opacity(0.2)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) + } + .padding(25) + .modifier(SettingsContainerModifier()) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + } + } +} + +struct HUDSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("HUD") + .font(.largeTitle.bold()) + .padding(.bottom) + + + VStack(alignment: .leading, spacing: 10) { + HStack { + Text("Volume HUD") + .font(.headline) + Spacer() + Toggle("", isOn: $settings.settings.enableVolumeHUD) + .labelsHidden().toggleStyle(.switch) + } + + Divider() + + HStack { + Text("View Style") + Spacer() + Picker("", selection: $settings.settings.volumeHUDStyle) { + ForEach(HUDStyle.allCases) { style in + Text(style.id).tag(style) + } + } + .labelsHidden() + .frame(width: 120) + } + .disabled(!settings.settings.enableVolumeHUD) + .opacity(settings.settings.enableVolumeHUD ? 1.0 : 0.5) + + Divider() + + HStack { + Text("Sound on Change") + Spacer() + Toggle("", isOn: $settings.settings.volumeHUDSoundEnabled) + .labelsHidden().toggleStyle(.switch) + } + .disabled(!settings.settings.enableVolumeHUD) + .opacity(settings.settings.enableVolumeHUD ? 1.0 : 0.5) + } + .padding() + .modifier(SettingsContainerModifier()) + .animation(.easeInOut, value: settings.settings.enableVolumeHUD) + + + VStack(alignment: .leading, spacing: 10) { + HStack { + Text("Brightness HUD") + .font(.headline) + Spacer() + Toggle("", isOn: $settings.settings.enableBrightnessHUD) + .labelsHidden().toggleStyle(.switch) + } + + Divider() + + HStack { + Text("View Style") + Spacer() + Picker("", selection: $settings.settings.brightnessHUDStyle) { + ForEach(HUDStyle.allCases) { style in + Text(style.id).tag(style) + } + } + .labelsHidden() + .frame(width: 120) + } + .disabled(!settings.settings.enableBrightnessHUD) + .opacity(settings.settings.enableBrightnessHUD ? 1.0 : 0.5) + } + .padding() + .modifier(SettingsContainerModifier()) + .animation(.easeInOut, value: settings.settings.enableBrightnessHUD) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + } + } +} + +struct MusicSettingsView: View { + @EnvironmentObject var settings: SettingsModel + @StateObject private var appFetcher = SystemAppFetcher() + + private var browserApps: [SystemApp] { appFetcher.apps.filter { $0.isBrowser } } + private var otherApps: [SystemApp] { appFetcher.apps.filter { !$0.isBrowser } } + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Music").font(.largeTitle.bold()).padding(.bottom) + VStack(spacing: 0) { + HStack { Text("Show Now Playing in Menu Bar"); Spacer(); Toggle("", isOn: $settings.settings.showNowPlayingInMenuBar).labelsHidden().toggleStyle(.switch) }.padding() + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + HStack { Text("Waveform is volume sensitive"); Spacer(); Toggle("", isOn: $settings.settings.musicWaveformIsVolumeSensitive).labelsHidden().toggleStyle(.switch) }.padding() + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + HStack { Text("Default Music App"); Spacer(); Picker("", selection: $settings.settings.defaultMusicPlayer) { Text("Apple Music").tag(DefaultMusicPlayer.appleMusic); if appFetcher.foundBundleIDs.contains("com.spotify.client") { Text("Spotify").tag(DefaultMusicPlayer.spotify) } }.labelsHidden().frame(width: 150) }.padding() + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + + VStack(alignment: .leading, spacing: 8) { + Text("Spotify API Credentials") + .font(.system(size: 14, weight: .medium)) + Text("Register your app at developer.spotify.com and copy these values here. The redirect URI is: sapphire://callback") + .font(.caption) + .foregroundColor(.secondary) + .padding(.bottom, 4) + + Text("Client ID") + .font(.system(size: 13, weight: .medium)) + .foregroundStyle(.white.opacity(0.8)) + SecureField("Enter your Client ID", text: $settings.settings.spotifyClientId) + .textFieldStyle(.plain) + .padding(8) + .background(Color.black.opacity(0.2)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) + + Text("Client Secret") + .font(.system(size: 13, weight: .medium)) + .foregroundStyle(.white.opacity(0.8)) + .padding(.top, 5) + SecureField("Enter your Client Secret", text: $settings.settings.spotifyClientSecret) + .textFieldStyle(.plain) + .padding(8) + .background(Color.black.opacity(0.2)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) + }.padding().padding(.top, 5) + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Open detailed Music widget on live activity click"); Spacer(); Toggle("", isOn: $settings.settings.musicOpenOnClick).labelsHidden().toggleStyle(.switch) }.padding() + }.modifier(SettingsContainerModifier()) + + VStack(spacing: 0) { + HStack { Text("Show Lyrics in Live Activity"); Spacer(); Toggle("", isOn: $settings.settings.showLyricsInLiveActivity).labelsHidden().toggleStyle(.switch) }.padding() + }.modifier(SettingsContainerModifier()).animation(.default, value: settings.settings.showLyricsInLiveActivity) + + if settings.settings.showLyricsInLiveActivity { + VStack(alignment: .leading, spacing: 10) { + Text("Allow Lyrics From:").font(.headline).padding([.horizontal, .top]) + ScrollView { + VStack(spacing: 0) { + Text("Browsers (Disabled by Default)").font(.caption).foregroundStyle(.secondary).padding(.vertical, 5) + ForEach(browserApps) { app in SystemAppRowView(app: app, isEnabled: binding(for: app, isBrowser: true)) } + Text("Other Apps").font(.caption).foregroundStyle(.secondary).padding(.vertical, 5) + ForEach(otherApps) { app in SystemAppRowView(app: app, isEnabled: binding(for: app, isBrowser: false)) } + } + }.frame(maxHeight: 360) + }.modifier(SettingsContainerModifier()).transition(.opacity.combined(with: .move(edge: .top))) + } + }.padding(25).frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top).onAppear { appFetcher.fetchApps() } + } + } + + private func binding(for app: SystemApp, isBrowser: Bool) -> Binding { + .init( + get: { settings.settings.musicAppStates[app.id, default: !isBrowser] }, + set: { settings.settings.musicAppStates[app.id] = $0 } + ) + } +} + +struct WeatherSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Weather") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(spacing: 0) { + VStack(alignment: .leading, spacing: 8) { + Text("Default Location") + TextField("e.g., New York, NY", text: $settings.settings.weatherDefaultLocation) + .textFieldStyle(.plain) + .padding(8) + .background(Color.black.opacity(0.2)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2))) + } + .padding() + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Use Celsius") + Spacer() + Toggle("", isOn: $settings.settings.weatherUseCelsius) + .labelsHidden().toggleStyle(.switch) + } + .padding() + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Open detailed Weather widget on live activity click") + Spacer() + Toggle("", isOn: $settings.settings.weatherOpenOnClick) + .labelsHidden().toggleStyle(.switch) + } + .padding() + } + .modifier(SettingsContainerModifier()) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + } + } +} + +struct CalendarSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Calendar") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(spacing: 0) { + HStack { + Text("Show All-Day Events") + Spacer() + Toggle("", isOn: $settings.settings.calendarShowAllDayEvents) + .labelsHidden().toggleStyle(.switch) + } + .padding() + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Start Week On") + Spacer() + Picker("", selection: $settings.settings.calendarStartOfWeek) { + ForEach(Day.allCases) { day in + Text(day.id).tag(day) + } + } + .labelsHidden() + .frame(width: 120) + } + .padding() + } + .modifier(SettingsContainerModifier()) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + } + } +} + +struct EyeBreakSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Eye Break") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(spacing: 0) { + CustomSliderRowView( + label: "Work Interval", + value: $settings.settings.eyeBreakWorkInterval, + range: 5...60, + specifier: "%.0f min" + ) + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + CustomSliderRowView( + label: "Break Duration", + value: $settings.settings.eyeBreakBreakDuration, + range: 10...60, + specifier: "%.0f sec" + ) + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Enable Sound Alerts") + Spacer() + Toggle("", isOn: $settings.settings.eyeBreakSoundAlerts) + .labelsHidden().toggleStyle(.switch) + } + .padding() + } + .modifier(SettingsContainerModifier()) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + } + } +} + +struct BluetoothSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("Bluetooth") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(spacing: 0) { + HStack { + Text("Notify for Low Battery") + Spacer() + Toggle("", isOn: $settings.settings.bluetoothNotifyLowBattery) + .labelsHidden() + .toggleStyle(.switch) + } + .padding() + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.leading, 20) + + HStack { + Text("Notify for Sound") + Spacer() + Toggle("", isOn: $settings.settings.bluetoothNotifySound) + .labelsHidden() + .toggleStyle(.switch) + } + .padding() + } + .modifier(SettingsContainerModifier()) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + } + } +} + +struct NeardropSettingsView: View { + @EnvironmentObject var settings: SettingsModel + + @State private var downloadPath: String = "" + @State private var isPathValid: Bool = true + + var body: some View { + ScrollView { + VStack(alignment: .leading) { + Text("Nearby Share") + .font(.largeTitle.bold()) + .padding(.bottom) + + VStack(spacing: 0) { + HStack { + Text("Enable Nearby Share") + .font(.system(size: 14, weight: .medium)) + Spacer() + Toggle("", isOn: $settings.settings.neardropEnabled) + .labelsHidden() + .toggleStyle(.switch) + } + .padding(EdgeInsets(top: 12, leading: 20, bottom: 12, trailing: 20)) + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.horizontal, 20) + + InfoContainer( + text: "Nearby Share allows you to share files from Android phones to your Mac using Android's native file sharing (Nearby Share / Quick Share). It's recommended to keep this feature enabled for convenient sharing from family and friends.", + iconName: "info.circle.fill", + color: .blue + ) + .padding() + + VStack(alignment: .leading, spacing: 15) { + VStack(alignment: .leading, spacing: 8) { + Text("Device Display Name") + .font(.system(size: 14, weight: .medium)) + .foregroundStyle(.white) + + TextField("My Mac", text: $settings.settings.neardropDeviceDisplayName) + .textFieldStyle(.plain) + .padding(.vertical, 8) + .padding(.horizontal, 12) + .background(Color.black.opacity(0.2)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(Color.white.opacity(0.2), lineWidth: 1)) + .foregroundStyle(.white) + .font(.system(size: 13)) + .disabled(!settings.settings.neardropEnabled) + } + + VStack(alignment: .leading, spacing: 8) { + Text("Download Location") + .font(.system(size: 14, weight: .medium)) + .foregroundStyle(.white) + + HStack { + TextField("Path", text: $downloadPath, onCommit: validateAndSavePath) + .textFieldStyle(.plain) + .foregroundStyle(.white) + .font(.system(size: 13)) + .disabled(!settings.settings.neardropEnabled) + + Image(systemName: isPathValid ? "checkmark.circle.fill" : "xmark.circle.fill") + .foregroundColor(isPathValid ? .green : .red) + } + .padding(.vertical, 8) + .padding(.horizontal, 12) + .background(Color.black.opacity(0.2)) + .clipShape(RoundedRectangle(cornerRadius: 8)) + .overlay(RoundedRectangle(cornerRadius: 8).stroke(isPathValid ? Color.white.opacity(0.2) : Color.red, lineWidth: 1)) + + if !isPathValid { + Text("A valid directory is required.") + .font(.caption) + .foregroundColor(.red) + } + } + } + .padding([.horizontal, .bottom], 20) + .opacity(settings.settings.neardropEnabled ? 1.0 : 0.5) + + Rectangle().fill(Color.white.opacity(0.2)).frame(height: 1).padding(.horizontal, 20) + + HStack { + Text("Open detailed AirDrop widget on live activity click") + Spacer() + Toggle("", isOn: $settings.settings.neardropOpenOnClick) + .labelsHidden().toggleStyle(.switch) + } + .padding() + .disabled(!settings.settings.neardropEnabled) + .opacity(settings.settings.neardropEnabled ? 1.0 : 0.5) + + } + .modifier(SettingsContainerModifier()) + .animation(.easeInOut, value: settings.settings.neardropEnabled) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .onAppear { + self.downloadPath = settings.settings.neardropDownloadLocationPath + } + .onChange(of: downloadPath) { newValue in + self.isPathValid = validate(path: newValue) + } + } + } + + private func validateAndSavePath() { + if validate(path: downloadPath) { + settings.settings.neardropDownloadLocationPath = downloadPath + } + } + + private func validate(path: String) -> Bool { + var isDirectory: ObjCBool = false + let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory) + return exists && isDirectory.boolValue + } +} + +struct AboutSettingsView: View { + @StateObject private var updateChecker = UpdateChecker() + + var body: some View { + ScrollView { + VStack(alignment: .leading, spacing: 20) { + Text("About") + .font(.largeTitle.bold()) + .padding(.bottom) + + HStack { + Image(nsImage: NSApp.applicationIconImage) + .resizable() + .frame(width: 80, height: 80) + .clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous)) + .padding(.trailing, 10) + + VStack(alignment: .leading, spacing: 4) { + Text("Sapphire") + .font(.largeTitle.weight(.bold)) + Text("Version \(currentAppVersion)") + .foregroundStyle(.secondary) + .textSelection(.enabled) + } + Spacer() + } + + VStack { + switch updateChecker.status { + case .checking: + HStack { + ProgressView().scaleEffect(0.5) + Text("Checking for updates...").foregroundStyle(.secondary) + } + case .upToDate: + HStack { + Image(systemName: "checkmark.circle.fill").foregroundColor(.green) + Text("You are up to date!").foregroundStyle(.secondary) + } + case .available(let version, let asset): + VStack(alignment: .leading, spacing: 10) { + HStack { + Image(systemName: "arrow.down.circle.fill").foregroundColor(.accentColor) + Text("Version \(version) is available!").font(.headline) + } + Button("Download and Install") { + updateChecker.downloadAndUpdate(asset: asset) + } + .buttonStyle(.plain) + .foregroundColor(.accentColor) + } + case .downloading(let progress): + ProgressView("Downloading...", value: progress, total: 1.0) + .progressViewStyle(.linear) + case .downloaded(let path): + HStack { + Image(systemName: "checkmark.circle.fill").foregroundColor(.green) + Text("Download complete!").foregroundStyle(.secondary) + Button("Show in Finder") { + NSWorkspace.shared.activateFileViewerSelecting([path]) + } + .buttonStyle(.plain).font(.caption) + } + case .error(let message): + HStack { + Image(systemName: "xmark.octagon.fill").foregroundColor(.red) + Text("Error: \(message)").foregroundStyle(.secondary) + } + } + + Button("Check for Updates") { + updateChecker.checkForUpdates() + } + .buttonStyle(.plain) + .font(.system(size: 12)) + .foregroundColor(.accentColor.opacity(0.8)) + .padding(.top, 5) + .disabled(isCheckingOrDownloading()) + } + .frame(maxWidth: .infinity, minHeight: 60) + .padding() + .modifier(SettingsContainerModifier()) + + Text("© 2025 Shariq Charolia. All rights reserved.") + .font(.caption) + .foregroundStyle(.tertiary) + .frame(maxWidth: .infinity, alignment: .center) + .padding(.top, 20) + } + .padding(25) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top) + .onAppear { + updateChecker.checkForUpdates() + } + } + } + + private func isCheckingOrDownloading() -> Bool { + if case .checking = updateChecker.status { return true } + if case .downloading = updateChecker.status { return true } + return false + } +} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift b/submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift new file mode 100644 index 00000000..f49a3786 --- /dev/null +++ b/submissions/sapphire/Sapphire/App Settings/SettingsSidebar.swift @@ -0,0 +1,87 @@ +// +// SettingsSidebar.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI + +struct SettingsSidebarView: View { + @Binding var selectedSection: SettingsSection? + @State private var searchText = "" + + var body: some View { + VStack(alignment: .leading, spacing: 0) { + Spacer().frame(height: 35) + + List(selection: $selectedSection) { + Section { + ForEach(SettingsSection.allCases) { section in + SidebarRowView(section: section).tag(section) + } + } + } + .listStyle(.sidebar).scrollContentBackground(.hidden) + + Spacer() + + + Button(action: { + NSApp.terminate(nil) + }) { + HStack { + Image(systemName: "power.circle.fill") + .font(.system(size: 15, weight: .bold)) + .foregroundStyle(.red) + .frame(width: 30, height: 30) + .background(Color.red.opacity(0.15)) + .clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) + Text("Quit") + .font(.system(size: 15, weight: .medium)) + .foregroundStyle(.white) + } + .padding(.vertical, 3) + .padding(.leading, 12) + } + .buttonStyle(.plain) + .padding(.bottom, 15) + } + } +} + +struct CustomTrafficLightButtons: View { + @Environment(\.window) private var window: NSWindow? + @State private var isHovering = false + var body: some View { + HStack(spacing: 8) { + Button(action: { window?.close() }) { + Image(systemName: "xmark").font(.system(size: 7, weight: .bold, design: .rounded)) + }.buttonStyle(TrafficLightButtonStyle(color: .red, isHovering: isHovering)) + Button(action: { window?.miniaturize(nil) }) { + Image(systemName: "minus").font(.system(size: 7, weight: .bold, design: .rounded)) + }.buttonStyle(TrafficLightButtonStyle(color: .yellow, isHovering: isHovering)) + Button(action: { window?.zoom(nil) }) { + Image(systemName: "plus").font(.system(size: 7, weight: .bold, design: .rounded)) + }.buttonStyle(TrafficLightButtonStyle(color: .green, isHovering: isHovering)) + }.onHover { hovering in withAnimation(.easeInOut(duration: 0.1)) { isHovering = hovering } } + } +} + +struct TrafficLightButtonStyle: ButtonStyle { + let color: Color; let isHovering: Bool + func makeBody(configuration: Configuration) -> some View { + ZStack { Circle().fill(color); configuration.label.foregroundStyle(.black.opacity(0.6)).opacity(isHovering ? 1 : 0) }.frame(width: 12, height: 12) + } +} + +fileprivate struct SidebarRowView: View { + let section: SettingsSection + var body: some View { + HStack(spacing: 12) { + Image(systemName: section.systemImage).font(.system(size: 11, weight: .bold)).foregroundStyle(.white).frame(width: 22, height: 22).background(section.iconBackgroundColor.opacity(0.8).gradient).clipShape(RoundedRectangle(cornerRadius: 6, style: .continuous)) + Text(section.label).font(.system(size: 13, weight: .medium)).foregroundStyle(.white) + Spacer() + }.padding(.vertical, 3) + } +} diff --git a/submissions/sapphire/Sapphire/App Settings/SettingsView.swift b/submissions/sapphire/Sapphire/App Settings/SettingsView.swift new file mode 100644 index 00000000..c78b77ed --- /dev/null +++ b/submissions/sapphire/Sapphire/App Settings/SettingsView.swift @@ -0,0 +1,78 @@ +// +// SettingsView.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI + + +private struct WindowKey: EnvironmentKey { + static let defaultValue: NSWindow? = nil +} + +extension EnvironmentValues { + var window: NSWindow? { + get { self[WindowKey.self] } + set { self[WindowKey.self] = newValue } + } +} + + +struct SettingsView: View { + @StateObject private var settings = SettingsModel() + @State private var selectedSection: SettingsSection? = .widgets + + var body: some View { + + ZStack { + HStack(spacing: 0) { + SettingsSidebarView(selectedSection: $selectedSection) + .frame(width: 190) + + SettingsDetailView(selectedSection: selectedSection) + } + + WindowDragHandle() + + CustomTrafficLightButtons() + .padding(.horizontal, 16) + .padding(.top, 16) + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) + .zIndex(2) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .environmentObject(settings) + .background(.ultraThinMaterial) + .clipShape(RoundedRectangle(cornerRadius: 20, style: .continuous)) + } +} + + +struct WindowDragHandle: View { + @Environment(\.window) private var window + + var body: some View { + VStack { + Color.clear + .frame(height: 50) + .contentShape(Rectangle()) + .gesture( + DragGesture(minimumDistance: 0) + .onChanged { value in + if let window = window { + let startPoint = window.frame.origin + let newPoint = NSPoint( + x: startPoint.x + value.translation.width, + y: startPoint.y - value.translation.height + ) + window.setFrameOrigin(newPoint) + } + } + ) + Spacer() + } + .zIndex(1) + } +} diff --git a/submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift b/submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift new file mode 100644 index 00000000..48dae2e1 --- /dev/null +++ b/submissions/sapphire/Sapphire/App Settings/UpdateChecker.swift @@ -0,0 +1,122 @@ +// +// UpdateChecker.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI + + + +let currentAppVersion = "Pre-Release" + +struct GitHubReleaseAsset: Codable { + let name: String + let browserDownloadUrl: URL + enum CodingKeys: String, CodingKey { + case name + case browserDownloadUrl = "browser_download_url" + } +} + +struct GitHubRelease: Codable { + let tagName: String + let assets: [GitHubReleaseAsset] + enum CodingKeys: String, CodingKey { + case tagName = "tag_name" + case assets + } +} + +enum UpdateStatus { + case checking + case upToDate + case available(version: String, asset: GitHubReleaseAsset) + case downloading(progress: Double) + case downloaded(path: URL) + case error(String) +} + +@MainActor +class UpdateChecker: NSObject, ObservableObject, URLSessionDownloadDelegate { + @Published var status: UpdateStatus = .checking + private var downloadTask: URLSessionDownloadTask? + + func checkForUpdates() { + self.status = .checking + guard let url = URL(string: "https://api.github.com/repos/cshariq/sapphire/releases/latest") else { + self.status = .error("Invalid URL") + return + } + + URLSession.shared.dataTask(with: url) { data, response, error in + DispatchQueue.main.async { + if let error = error { + self.status = .error(error.localizedDescription) + return + } + guard let data = data else { + self.status = .error("No data received.") + return + } + do { + let release = try JSONDecoder().decode(GitHubRelease.self, from: data) + let latestVersion = release.tagName.trimmingCharacters(in: CharacterSet(charactersIn: "v")) + + if latestVersion.compare(currentAppVersion, options: .numeric) == .orderedDescending { + + if let asset = release.assets.first(where: { $0.name.hasSuffix(".dmg") || $0.name.hasSuffix(".zip") }) { + self.status = .available(version: latestVersion, asset: asset) + } else { + self.status = .error("No suitable asset found.") + } + } else { + self.status = .upToDate + } + } catch { + self.status = .error("Failed to decode response.") + } + } + }.resume() + } + + func downloadAndUpdate(asset: GitHubReleaseAsset) { + let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil) + downloadTask = session.downloadTask(with: asset.browserDownloadUrl) + downloadTask?.resume() + self.status = .downloading(progress: 0) + } + + + func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { + let fileManager = FileManager.default + guard let downloadsURL = fileManager.urls(for: .downloadsDirectory, in: .userDomainMask).first else { + DispatchQueue.main.async { self.status = .error("Could not find Downloads folder.") } + return + } + + let destinationURL = downloadsURL.appendingPathComponent(downloadTask.originalRequest!.url!.lastPathComponent) + + + try? fileManager.removeItem(at: destinationURL) + + do { + try fileManager.copyItem(at: location, to: destinationURL) + DispatchQueue.main.async { + self.status = .downloaded(path: destinationURL) + NSWorkspace.shared.open(destinationURL) + } + } catch { + DispatchQueue.main.async { self.status = .error("Failed to move update to Downloads.") } + } + } + + + func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { + let progress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite) + DispatchQueue.main.async { + self.status = .downloading(progress: progress) + } + } +} diff --git a/submissions/sapphire/Sapphire/App Settings/UserDefault.swift b/submissions/sapphire/Sapphire/App Settings/UserDefault.swift new file mode 100644 index 00000000..9c993058 --- /dev/null +++ b/submissions/sapphire/Sapphire/App Settings/UserDefault.swift @@ -0,0 +1,44 @@ +// +// UserDefault.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-10. +// + +import SwiftUI +import Combine + + +private let appGroupSuite = UserDefaults(suiteName: "group.com.shariq.sapphire") + +@propertyWrapper +struct UserDefault { + let key: String + let defaultValue: Value + + var wrappedValue: Value { + get { + + guard let data = appGroupSuite?.data(forKey: key) else { + return defaultValue + } + do { + let value = try JSONDecoder().decode(Value.self, from: data) + return value + } catch { + if let encodedDefault = try? JSONEncoder().encode(defaultValue) { + appGroupSuite?.set(encodedDefault, forKey: key) + } + return defaultValue + } + } + set { + do { + let data = try JSONEncoder().encode(newValue) + + appGroupSuite?.set(data, forKey: key) + } catch { + } + } + } +} diff --git a/submissions/sapphire/Sapphire/App/AppDelegate.swift b/submissions/sapphire/Sapphire/App/AppDelegate.swift new file mode 100644 index 00000000..559a1170 --- /dev/null +++ b/submissions/sapphire/Sapphire/App/AppDelegate.swift @@ -0,0 +1,245 @@ +// +// AppDelegate.swift +// Sapphire +// +// Created by Shariq Charolia on 2025-07-04. +// + +import Cocoa +import SwiftUI +import Combine +import UserNotifications +import NearbyShare +import ApplicationServices +import IOBluetooth + +@MainActor +@NSApplicationMain +class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate, MainAppDelegate { + + public var notchWindow: NSWindow? + private var cgsSpace: CGSSpace? + private var onboardingWindow: NSWindow? + private var settingsWindow: NSWindow? + + + private var settingsDelegate: SettingsWindowDelegate? + + var spotifyAPIManager: SpotifyAPIManager? + var systemHUDManager: SystemHUDManager? + var notificationManager: NotificationManager? + var desktopManager: DesktopManager? + var focusModeManager: FocusModeManager? + var musicWidget: MusicWidget? + var calendarService: CalendarService? + var batteryMonitor: BatteryMonitor? + var bluetoothManager: BluetoothManager? + var audioDeviceManager: AudioDeviceManager? + var eyeBreakManager: EyeBreakManager? + var timerManager: TimerManager? + var weatherActivityViewModel: WeatherActivityViewModel? + var contentPickerHelper: ContentPickerHelper? + var geminiLiveManager: GeminiLiveManager? + var settingsModel: SettingsModel? + var activeAppMonitor: ActiveAppMonitor? + var liveActivityManager: LiveActivityManager? + + func applicationDidFinishLaunching(_ aNotification: Notification) { + + if UserDefaults.standard.bool(forKey: "hasCompletedOnboarding") { + startMainApp() + } else { + showOnboardingWindow() + } + } + + func showOnboardingWindow() { + if onboardingWindow == nil { + let window = NSWindow( + contentRect: NSRect(x: 0, y: 0, width: 900, height: 700), + styleMask: [.borderless], + backing: .buffered, defer: false + ) + + window.center() + window.title = "Welcome to Sapphire" + window.isMovableByWindowBackground = true + window.titlebarAppearsTransparent = true + + + window.isOpaque = false + window.backgroundColor = .clear + + + let hostingView = NSHostingView(rootView: OnboardingView(onComplete: { self.onboardingDidComplete() })) + hostingView.wantsLayer = true + hostingView.layer?.backgroundColor = NSColor.clear.cgColor + + window.contentView = hostingView + onboardingWindow = window + } + + + onboardingWindow?.makeKeyAndOrderFront(nil) + onboardingWindow?.level = .modalPanel + + + NSApp.activate(ignoringOtherApps: true) + } + + + func onboardingDidComplete() { + UserDefaults.standard.set(true, forKey: "hasCompletedOnboarding") + + self.onboardingWindow?.orderOut(nil) + self.onboardingWindow = nil + + startMainApp() + } + + func startMainApp() { + self.spotifyAPIManager = .shared; self.systemHUDManager = .shared; self.notificationManager = NotificationManager() + self.desktopManager = DesktopManager(); self.focusModeManager = FocusModeManager(); self.musicWidget = MusicWidget() + self.calendarService = CalendarService(); self.batteryMonitor = BatteryMonitor(); self.bluetoothManager = BluetoothManager() + self.audioDeviceManager = AudioDeviceManager(); self.eyeBreakManager = EyeBreakManager(); self.timerManager = TimerManager() + self.weatherActivityViewModel = WeatherActivityViewModel(); self.contentPickerHelper = ContentPickerHelper() + self.geminiLiveManager = GeminiLiveManager(); self.settingsModel = SettingsModel(); self.activeAppMonitor = .shared + + self.liveActivityManager = LiveActivityManager( + systemHUDManager: systemHUDManager!, notificationManager: notificationManager!, desktopManager: desktopManager!, + focusModeManager: focusModeManager!, musicWidget: musicWidget!, calendarService: calendarService!, + batteryMonitor: batteryMonitor!, bluetoothManager: bluetoothManager!, audioDeviceManager: audioDeviceManager!, + eyeBreakManager: eyeBreakManager!, timerManager: timerManager!, weatherActivityViewModel: weatherActivityViewModel!, + geminiLiveManager: geminiLiveManager!, settingsModel: settingsModel!, activeAppMonitor: activeAppMonitor! + ) + + OSDManager.disableSystemHUD() + _ = IOBluetoothDevice.pairedDevices() + NSAppleEventManager.shared().setEventHandler(self, andSelector: #selector(handleGetURL), forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL)) + + createNotchWindow() + + NotificationCenter.default.addObserver(self, selector: #selector(screenParametersChanged), name: NSApplication.didChangeScreenParametersNotification, object: nil) + UNUserNotificationCenter.current().delegate = self + NearbyConnectionManager.shared.mainAppDelegate = self + NearbyConnectionManager.shared.becomeVisible() + + + transitionToAgentApp() + } + + private func transitionToAgentApp() { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + if NSApp.activationPolicy() != .accessory { + NSApp.setActivationPolicy(.accessory) + } + } + } + + func applicationWillTerminate(_ aNotification: Notification) { + OSDManager.enableSystemHUD() + NSAppleEventManager.shared().removeEventHandler(forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL)) + cgsSpace = nil + NotificationCenter.default.removeObserver(self, name: NSApplication.didChangeScreenParametersNotification, object: nil) + } + + @objc func handleGetURL(event: NSAppleEventDescriptor!, withReplyEvent: NSAppleEventDescriptor!) { + guard let urlString = event.paramDescriptor(forKeyword: AEKeyword(keyDirectObject))?.stringValue, let url = URL(string: urlString) else { return } + if url.scheme == "dynamicnotch" { spotifyAPIManager?.handleRedirect(url: url) } + } + + func createNotchWindow() { + notchWindow?.orderOut(nil); notchWindow?.close() + guard let mainScreen = NSScreen.main else { return } + let screenFrame = mainScreen.frame + let paddedWindowWidth: CGFloat = 1200, paddedWindowHeight: CGFloat = 600 + let windowOriginX = (screenFrame.width - paddedWindowWidth) / 2, windowOriginY = screenFrame.maxY - paddedWindowHeight + let windowRect = NSRect(x: windowOriginX, y: windowOriginY, width: paddedWindowWidth, height: paddedWindowHeight) + let newWindow = NSWindow(contentRect: windowRect, styleMask: .borderless, backing: .buffered, defer: false) + self.notchWindow = newWindow + guard let window = self.notchWindow else { return } + window.isOpaque = false; window.backgroundColor = .clear; window.hasShadow = false; window.level = .statusBar + window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary, .stationary] + window.ignoresMouseEvents = true + if self.cgsSpace == nil { self.cgsSpace = CGSSpace() }; self.cgsSpace?.windows.removeAll(); self.cgsSpace?.windows.insert(window) + + let notchControllerView = NotchController(notchWindow: window) + let rootViewContainer = VStack(spacing: 0) { notchControllerView; Spacer() }.frame(width: paddedWindowWidth, height: paddedWindowHeight) + + let hostingView = NSHostingView( + rootView: rootViewContainer + .environmentObject(systemHUDManager!).environmentObject(musicWidget!).environmentObject(spotifyAPIManager!) + .environmentObject(liveActivityManager!).environmentObject(audioDeviceManager!).environmentObject(bluetoothManager!) + .environmentObject(notificationManager!).environmentObject(desktopManager!).environmentObject(focusModeManager!) + .environmentObject(eyeBreakManager!).environmentObject(timerManager!).environmentObject(contentPickerHelper!) + .environmentObject(geminiLiveManager!).environmentObject(settingsModel!).environmentObject(activeAppMonitor!) + ) + hostingView.frame = NSRect(origin: .zero, size: windowRect.size) + hostingView.autoresizingMask = [.width, .height] + hostingView.wantsLayer = true; hostingView.layer?.backgroundColor = NSColor.clear.cgColor + window.contentView = hostingView; window.makeKeyAndOrderFront(nil) + } + + func openSettingsWindow() { + if let window = settingsWindow { + NSApp.setActivationPolicy(.regular) + window.makeKeyAndOrderFront(nil) + NSApp.activate(ignoringOtherApps: true) + return + } + let newWindow = NSWindow( + contentRect: NSRect(x: 0, y: 0, width: 950, height: 650), + styleMask: [.titled, .closable, .miniaturizable, .resizable], + backing: .buffered, defer: false + ) + newWindow.center(); newWindow.isMovableByWindowBackground = true + newWindow.title = "Sapphire Settings" + + let settingsView = SettingsView() + let hostingView = NSHostingView(rootView: settingsView.environment(\.window, newWindow).environmentObject(settingsModel!)) + newWindow.contentView = hostingView + + + self.settingsDelegate = SettingsWindowDelegate { + NSApp.setActivationPolicy(.accessory) + self.settingsWindow = nil + } + newWindow.delegate = self.settingsDelegate + + self.settingsWindow = newWindow + NSApp.setActivationPolicy(.regular) + newWindow.makeKeyAndOrderFront(nil) + NSApp.activate(ignoringOtherApps: true) + } + + @objc func screenParametersChanged(notification: Notification) { + guard let window = self.notchWindow, let mainScreen = NSScreen.main else { createNotchWindow(); return } + let screenFrame = mainScreen.frame, windowSize = window.frame.size + let newOriginX = (screenFrame.width - windowSize.width) / 2, newOriginY = screenFrame.maxY - windowSize.height + window.setFrame(NSRect(x: newOriginX, y: newOriginY, width: windowSize.width, height: windowSize.height), display: true, animate: false) + } + + func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, fileURLs: [URL]) { + DispatchQueue.main.async { self.liveActivityManager?.startNearDropActivity(transfer: transfer, device: device, fileURLs: fileURLs) } + } + func incomingTransfer(id: String, didUpdateProgress progress: Double) { + DispatchQueue.main.async { self.liveActivityManager?.updateNearDropProgress(id: id, progress: progress) } + } + func incomingTransfer(id: String, didFinishWith error: Error?) { + DispatchQueue.main.async { self.liveActivityManager?.finishNearDropTransfer(id: id, error: error) } + } + func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { + if let transferID = response.notification.request.content.userInfo["transferID"] as? String { + let accepted = response.actionIdentifier == "ACCEPT" + NearbyConnectionManager.shared.submitUserConsent(transferID: transferID, accept: accepted) + if accepted { liveActivityManager?.updateNearDropState(to: .inProgress) } else { liveActivityManager?.clearNearDropActivity() } + } + completionHandler() + } +} + +fileprivate class SettingsWindowDelegate: NSObject, NSWindowDelegate { + var onClose: () -> Void + init(onClose: @escaping () -> Void) { self.onClose = onClose } + func windowWillClose(_ notification: Notification) { onClose() } +} diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1.png new file mode 100644 index 0000000000000000000000000000000000000000..d79f61f43dc7cfc071994fd9c162097f205f0b27 GIT binary patch literal 118918 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 literal 0 HcmV?d00001 diff --git a/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x 1.png b/submissions/sapphire/Sapphire/App/Assets.xcassets/AppIcon.appiconset/Artboard 1@0.5x 1.png new file mode 100644 index 0000000000000000000000000000000000000000..37b36f1579225e5619147545a7d808bb4dd71cf4 GIT binary patch literal 32336 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