From ad0728cfaddf5ada6814a52cc68c5be8ecda669e Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Tue, 21 Apr 2026 10:07:52 +0200 Subject: [PATCH 1/2] Add example iOS Extension --- Example/HelloWorld/BUILD | 21 ++++++++++++++- .../NotificationService.swift | 27 +++++++++++++++++++ .../HelloWorld/Resources/IosExt-Info.plist | 27 +++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 Example/HelloWorld/IosExtension/HelloWorldNotificationExtension/NotificationService.swift create mode 100644 Example/HelloWorld/Resources/IosExt-Info.plist diff --git a/Example/HelloWorld/BUILD b/Example/HelloWorld/BUILD index 9b02b194..39ec47d2 100644 --- a/Example/HelloWorld/BUILD +++ b/Example/HelloWorld/BUILD @@ -1,5 +1,5 @@ load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template_rule") -load("@rules_apple//apple:ios.bzl", "ios_application", "ios_unit_test", "ios_build_test", "ios_ui_test") +load("@rules_apple//apple:ios.bzl", "ios_application", "ios_extension", "ios_unit_test", "ios_build_test", "ios_ui_test") load("@rules_apple//apple:macos.bzl", "macos_application", "macos_command_line_application", "macos_unit_test") load("@rules_apple//apple:watchos.bzl", "watchos_application", "watchos_extension", "watchos_unit_test") load("@rules_cc//cc:defs.bzl", "cc_library") @@ -180,6 +180,15 @@ swift_library( srcs = [":ExpandTemplateSwiftFile"], ) +## MARK: iOS extension targets + +swift_library( + name = "NotificationServiceExtensionLib", + module_name = "NotificationServiceExtensionLib", + srcs = glob(["HelloWorldNotificationExtension/Sources/*.swift"]), + deps = [":TodoModels"], +) + ## MARK: WatchOS targets swift_library( @@ -247,9 +256,19 @@ ios_application( infoplists = ["Resources/Info.plist"], minimum_os_version = IOS_MINIMUM_OS_VERSION, watch_application = ":HelloWorldWatchApp", + extensions = [":HelloWorldNotificationServiceExtension"], deps = [":HelloWorldLib"], ) +ios_extension( + name = "HelloWorldNotificationServiceExtension", + bundle_id = "com.example.HelloWorld.NotificationService", + families = ["iphone", "ipad"], + infoplists = ["Resources/IosExt-Info.plist"], + minimum_os_version = IOS_MINIMUM_OS_VERSION, + deps = [":NotificationServiceExtensionLib"], +) + watchos_application( name = "HelloWorldWatchApp", bundle_id = "com.example.HelloWorld.Watch", diff --git a/Example/HelloWorld/IosExtension/HelloWorldNotificationExtension/NotificationService.swift b/Example/HelloWorld/IosExtension/HelloWorldNotificationExtension/NotificationService.swift new file mode 100644 index 00000000..d7b0f7d8 --- /dev/null +++ b/Example/HelloWorld/IosExtension/HelloWorldNotificationExtension/NotificationService.swift @@ -0,0 +1,27 @@ +import TodoModels +import UserNotifications + +class NotificationService: UNNotificationServiceExtension { + var contentHandler: ((UNNotificationContent) -> Void)? + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive( + _ request: UNNotificationRequest, + withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void + ) { + self.contentHandler = contentHandler + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + if let bestAttemptContent = bestAttemptContent { + let manager = TodoListManager() + bestAttemptContent.title = "\(bestAttemptContent.title) [\(manager.todoItems.count) todos]" + contentHandler(bestAttemptContent) + } + } + + override func serviceExtensionTimeWillExpire() { + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + contentHandler(bestAttemptContent) + } + } +} diff --git a/Example/HelloWorld/Resources/IosExt-Info.plist b/Example/HelloWorld/Resources/IosExt-Info.plist new file mode 100644 index 00000000..ede40b39 --- /dev/null +++ b/Example/HelloWorld/Resources/IosExt-Info.plist @@ -0,0 +1,27 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + NotificationServiceExtensionLib.NotificationService + + + From 1dc4e6d173486634deb5d4b513926a97ac2a00d0 Mon Sep 17 00:00:00 2001 From: Bruno Rocha Date: Tue, 21 Apr 2026 10:23:33 +0200 Subject: [PATCH 2/2] Add consistent_labels to all queries --- Example/HelloWorld/BUILD | 1 + .../HelloWorldLib/Sources/AddTodoView.swift | 5 +- .../Sources}/NotificationService.swift | 0 Example/MODULE.bazel | 4 + .../BuildTargets/BazelTargetQuerier.swift | 13 +- .../BazelTargetQuerierParser.swift | 44 +- .../BuildTargets/BazelTargetStore.swift | 4 +- .../BuildTargets/IndexOutputPathBuilder.swift | 7 +- .../BazelTargetCompilerArgsExtractor.swift | 28 +- .../SharedUtils/BazelLabelSanitizer.swift | 33 +- .../Shell/ShellCommandRunner.swift | 7 +- .../SharedUtils/SplitLogMessage.swift | 36 +- ...azelTargetCompilerArgsExtractorTests.swift | 9 + .../BazelTargetQuerierParserImplTests.swift | 197 ++++--- .../BazelTargetQuerierTests.swift | 32 +- .../Fakes/BazelTargetQuerierParserFake.swift | 6 +- .../IsExternalBazelLabelTests.swift | 81 +++ .../Resources/aquery.pb | 533 ++++++++++-------- .../Resources/cquery.pb | Bin 147600 -> 169108 bytes .../Resources/cquery_added_files.pb | Bin 20882 -> 20762 bytes rules/setup_sourcekit_bsp.sh.tpl | 4 +- 21 files changed, 660 insertions(+), 384 deletions(-) rename Example/HelloWorld/{IosExtension/HelloWorldNotificationExtension => HelloWorldNotificationExtension/Sources}/NotificationService.swift (100%) create mode 100644 Tests/SourceKitBazelBSPTests/IsExternalBazelLabelTests.swift diff --git a/Example/HelloWorld/BUILD b/Example/HelloWorld/BUILD index 39ec47d2..c3c8db7c 100644 --- a/Example/HelloWorld/BUILD +++ b/Example/HelloWorld/BUILD @@ -115,6 +115,7 @@ swift_library( ":TodoModelsAlias", ":TodoObjCSupport", ":ExpandedTemplate", + "@yams//:Yams", # External dep to test bzlmod + version suffix in BSP URIs ] + select({ "//conditions:default": [], ":dbg_mode": [":GeneratedDummy"], diff --git a/Example/HelloWorld/HelloWorldLib/Sources/AddTodoView.swift b/Example/HelloWorld/HelloWorldLib/Sources/AddTodoView.swift index 75b5885b..b41b317b 100644 --- a/Example/HelloWorld/HelloWorldLib/Sources/AddTodoView.swift +++ b/Example/HelloWorld/HelloWorldLib/Sources/AddTodoView.swift @@ -19,6 +19,7 @@ import SwiftUI import TodoModels +import Yams struct AddTodoView: View { @@ -113,6 +114,8 @@ struct AddTodoView: View { todoTitle = "" isPresented = false - print("Added task: \(trimmedTitle)") + // Test Yams external dependency + let yaml = try? Yams.dump(object: ["task": trimmedTitle]) + print("Added task: \(trimmedTitle), yaml: \(yaml ?? "nil")") } } diff --git a/Example/HelloWorld/IosExtension/HelloWorldNotificationExtension/NotificationService.swift b/Example/HelloWorld/HelloWorldNotificationExtension/Sources/NotificationService.swift similarity index 100% rename from Example/HelloWorld/IosExtension/HelloWorldNotificationExtension/NotificationService.swift rename to Example/HelloWorld/HelloWorldNotificationExtension/Sources/NotificationService.swift diff --git a/Example/MODULE.bazel b/Example/MODULE.bazel index 561a6d8e..2e2e5328 100644 --- a/Example/MODULE.bazel +++ b/Example/MODULE.bazel @@ -28,6 +28,10 @@ archive_override( bazel_dep(name = "apple_support", version = "2.2.0") bazel_dep(name = "rules_cc", version = "0.2.16") + +# External Swift library to test the external repo case +bazel_dep(name = "yams", version = "5.0.6") + bazel_dep(name = "aspect_bazel_lib", version = "2.13.0") bazel_dep(name = "rules_multirun", version = "0.13.0") diff --git a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerier.swift b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerier.swift index 60de4dbd..0cdc3f31 100644 --- a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerier.swift +++ b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerier.swift @@ -120,7 +120,8 @@ final class BazelTargetQuerier { // We use cquery here because we are interested on what's actually compiled. // Also, this shares more analysis cache compared to the regular query. - let cmd = "cquery '\(topLevelTargetsQuery)' --noinclude_aspects --notool_deps --noimplicit_deps --output proto" + let cmd = + "cquery '\(topLevelTargetsQuery)' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto" let output: Data = try commandRunner.bazelIndexAction( baseConfig: config.baseConfig, outputBase: config.outputBase, @@ -139,7 +140,8 @@ final class BazelTargetQuerier { workspaceName: config.workspaceName, executionRoot: config.executionRoot, toolchainPath: config.devToolchainPath, - outputPath: config.outputPath + outputPath: config.outputPath, + outputBase: config.outputBase ) logger.debug("Cqueried \(processedCqueryResult.buildTargets.count, privacy: .public) targets") @@ -165,6 +167,7 @@ final class BazelTargetQuerier { let baseFlags = [ + "--consistent_labels", "--noinclude_artifacts", "--noinclude_aspects", ] + config.baseConfig.aqueryFlags @@ -265,7 +268,8 @@ final class BazelTargetQuerier { cmd: query, rootUri: config.rootUri, additionalFlags: [ - "--output=proto" + "--consistent_labels", + "--output=proto", ] ) @@ -277,7 +281,8 @@ final class BazelTargetQuerier { rootUri: config.rootUri, workspaceName: config.workspaceName, executionRoot: config.executionRoot, - outputPath: config.outputPath + outputPath: config.outputPath, + outputBase: config.outputBase ) } } diff --git a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerierParser.swift b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerierParser.swift index b2ae21ce..399aacfc 100644 --- a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerierParser.swift +++ b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetQuerierParser.swift @@ -81,7 +81,8 @@ protocol BazelTargetQuerierParser: AnyObject { workspaceName: String, executionRoot: String, toolchainPath: String, - outputPath: String + outputPath: String, + outputBase: String ) throws -> ProcessedCqueryResult func processAquery( @@ -95,7 +96,8 @@ protocol BazelTargetQuerierParser: AnyObject { rootUri: String, workspaceName: String, executionRoot: String, - outputPath: String + outputPath: String, + outputBase: String ) throws -> ProcessedCqueryAddedFilesResult } @@ -111,7 +113,8 @@ final class BazelTargetQuerierParserImpl: BazelTargetQuerierParser { workspaceName: String, executionRoot: String, toolchainPath: String, - outputPath: String + outputPath: String, + outputBase: String ) throws -> ProcessedCqueryResult { let cquery = try BazelProtobufBindings.parseCqueryResult(data: data) @@ -255,7 +258,7 @@ final class BazelTargetQuerierParserImpl: BazelTargetQuerierParser { let id = try label.toTargetId( rootUri: rootUri, workspaceName: workspaceName, - executionRoot: executionRoot, + outputBase: outputBase, configMnemonic: configuration ) bspUriToParentConfigMap[id] = configuration @@ -358,7 +361,7 @@ final class BazelTargetQuerierParserImpl: BazelTargetQuerierParser { canDebug: false ) - let isExternal = rule.name.hasPrefix("@") + let isExternal = rule.name.isExternalBazelLabel() let tags: [BuildTargetTag] = { var tags: [BuildTargetTag] = [.library] if isExternal { @@ -866,7 +869,8 @@ extension BazelTargetQuerierParserImpl { rootUri: String, workspaceName: String, executionRoot: String, - outputPath: String + outputPath: String, + outputBase: String ) throws -> ProcessedCqueryAddedFilesResult { let cquery = try BazelProtobufBindings.parseCqueryResult(data: data) @@ -914,7 +918,7 @@ extension BazelTargetQuerierParserImpl { let id = try displayName.toTargetId( rootUri: rootUri, workspaceName: workspaceName, - executionRoot: executionRoot, + outputBase: outputBase, configMnemonic: configMnemonic ) @@ -937,12 +941,12 @@ extension String { /// Converts a Bazel label into a URI and returns a unique target id. /// /// For local labels: bazel:///___ - /// For external labels: bazel:///external//___ + /// For external labels: bazel:///external//___ /// fileprivate func toTargetId( rootUri: String, workspaceName: String, - executionRoot: String, + outputBase: String, configMnemonic: String ) throws -> URI { let (repoName, packageName, targetName) = try splitTargetLabel(workspaceName: workspaceName) @@ -953,7 +957,7 @@ extension String { } else { // External repo: use execution root + external path path = - "bazel://" + executionRoot + "/external/" + repoName + packagePath + "/" + targetName + "_" + "bazel://" + outputBase + "/external/" + repoName + packagePath + "/" + targetName + "_" + configMnemonic } guard let uri = try? URI(string: path) else { @@ -980,17 +984,17 @@ extension String { let repoName: String let packageName: String - if repoAndPackage.hasPrefix("@//") { - // Alias for the main repo. - repoName = workspaceName - packageName = String(repoAndPackage.dropFirst(3)) - } else if repoAndPackage.hasPrefix("//") { - // Also the main repo. + var withoutAt = repoAndPackage + while withoutAt.first == "@" { + withoutAt = withoutAt.dropFirst() + } + + if withoutAt.hasPrefix("//") { + // Main repo label. repoName = workspaceName - packageName = String(repoAndPackage.dropFirst(2)) - } else if repoAndPackage.hasPrefix("@") && repoAndPackage.contains("//") { - // External label - let withoutAt = repoAndPackage.dropFirst() + packageName = String(withoutAt.dropFirst(2)) + } else if !withoutAt.isEmpty { + // External repo label. guard let slashIndex = withoutAt.firstIndex(of: "/") else { throw BazelTargetQuerierParserError.incorrectName(self) } diff --git a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetStore.swift b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetStore.swift index a89c218e..af489afc 100644 --- a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetStore.swift +++ b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/BazelTargetStore.swift @@ -395,7 +395,7 @@ extension BazelTargetStoreImpl { }() reportTopLevel.append( .init( - label: label, + label: label.removingLeadingAtForMainRepoBazelLabel(), launchType: launchType, configMnemonic: configMnemonic, testSources: testSources @@ -429,7 +429,7 @@ extension BazelTargetStoreImpl { } reportDependencies.append( .init( - label: label, + label: label.removingLeadingAtForMainRepoBazelLabel(), configMnemonic: configMnemonic, topLevelParent: topLevelParent, extraBuildArgs: extraBuildArgs diff --git a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/IndexOutputPathBuilder.swift b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/IndexOutputPathBuilder.swift index 817c2374..4a0cf670 100644 --- a/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/IndexOutputPathBuilder.swift +++ b/Sources/SourceKitBazelBSP/RequestHandlers/BuildTargets/IndexOutputPathBuilder.swift @@ -46,8 +46,11 @@ enum IndexOutputPathBuilder { // Extract external repo name if present (e.g., "@abseil-cpp" from "@abseil-cpp//absl/base") let externalRepoName: String? - if beforeColon.hasPrefix("@") { - let afterAt = beforeColon.dropFirst() // drop "@" + if beforeColon.isExternalBazelLabel() { + var afterAt = beforeColon.dropFirst() + while afterAt.first == "@" { + afterAt = afterAt.dropFirst() + } if let slashIdx = afterAt.firstIndex(of: "/") { externalRepoName = String(afterAt[.. Analysis_Action { - let bazelTarget: String = { - let base = platformInfo.label - guard base.hasPrefix("@") else { - return base - } - // External labels show up as `@@` in the aquery. - return "@\(base)" - }() - guard let target = aquery.targets[bazelTarget] else { + let bazelTarget: String = platformInfo.label + // The aquery protobuf uses labels without the @ prefix for main repo targets even when + // --consistent_labels is used, but cquery returns labels with @@ or @ prefix. + // External repos keep their @@ prefix in both. Normalize labels for lookup. + // Older Bazel versions may return single @ for external repos, so try both formats. + let normalizedTarget: String + if bazelTarget.hasPrefix("@@//") { + normalizedTarget = String(bazelTarget.dropFirst(2)) + } else if bazelTarget.hasPrefix("@//") { + normalizedTarget = String(bazelTarget.dropFirst(1)) + } else if bazelTarget.hasPrefix("@") && !bazelTarget.hasPrefix("@@") { + // External repo with single @ - convert to @@ for lookup + normalizedTarget = "@" + bazelTarget + } else { + normalizedTarget = bazelTarget + } + // Try normalized target first, then fall back to original for compatibility + let targetToLookup = aquery.targets[normalizedTarget] ?? aquery.targets[bazelTarget] + guard let target = targetToLookup else { throw BazelTargetCompilerArgsExtractorError.targetNotFound(bazelTarget) } guard let actions = aquery.actions[target.id] else { diff --git a/Sources/SourceKitBazelBSP/SharedUtils/BazelLabelSanitizer.swift b/Sources/SourceKitBazelBSP/SharedUtils/BazelLabelSanitizer.swift index 428c446e..8d9a836e 100644 --- a/Sources/SourceKitBazelBSP/SharedUtils/BazelLabelSanitizer.swift +++ b/Sources/SourceKitBazelBSP/SharedUtils/BazelLabelSanitizer.swift @@ -20,11 +20,13 @@ /// Sanitizes Bazel labels into safe identifiers for use as output group names or target names. enum BazelLabelSanitizer { /// Sanitizes a Bazel label with the given prefix. - /// Strips leading `//`, replaces `/`, `:`, `-`, `.` with `_`. + /// Strips all leading `@` and `/` characters, replaces `/`, `:`, `-`, `.`, `+` with `_`. + /// This must match the `_sanitize_label` function in `setup_sourcekit_bsp.sh.tpl`. static func sanitize(_ label: String, prefix: String) -> String { var sanitized = label - if sanitized.hasPrefix("//") { - sanitized = String(sanitized.dropFirst(2)) + // Strip all leading @ and / characters (matches Bazel-side _strip_leading_chars) + while let first = sanitized.first, first == "@" || first == "/" { + sanitized = String(sanitized.dropFirst()) } return prefix + sanitized @@ -32,6 +34,7 @@ enum BazelLabelSanitizer { .replacingOccurrences(of: ":", with: "_") .replacingOccurrences(of: "-", with: "_") .replacingOccurrences(of: ".", with: "_") + .replacingOccurrences(of: "+", with: "_") } /// Converts a Bazel label to a wrapper target name. @@ -40,3 +43,27 @@ enum BazelLabelSanitizer { return sanitize(label, prefix: "wrapper_") } } + +extension String { + func isExternalBazelLabel() -> Bool { + guard hasPrefix("@") else { + return false + } + var rest = self.dropFirst() + while rest.first == "@" { + rest = rest.dropFirst() + } + return !rest.isEmpty && !rest.hasPrefix("//") + } + + func removingLeadingAtForMainRepoBazelLabel() -> String { + guard !isExternalBazelLabel() else { + return self + } + var rest = self.dropFirst() + while rest.first == "@" { + rest = rest.dropFirst() + } + return String(rest) + } +} diff --git a/Sources/SourceKitBazelBSP/SharedUtils/Shell/ShellCommandRunner.swift b/Sources/SourceKitBazelBSP/SharedUtils/Shell/ShellCommandRunner.swift index 81b748e7..283aad4c 100644 --- a/Sources/SourceKitBazelBSP/SharedUtils/Shell/ShellCommandRunner.swift +++ b/Sources/SourceKitBazelBSP/SharedUtils/Shell/ShellCommandRunner.swift @@ -62,7 +62,12 @@ struct ShellCommandRunner: CommandRunner { runningProcess.attachPipes() - logger.logFullObjectInMultipleLogMessages(level: .debug, header: "Running shell", cmd) + logger.logFullObjectInMultipleLogMessages( + level: .debug, + header: "Running shell", + cmd, + splitByCharacterCount: true + ) try process.run() diff --git a/Sources/SourceKitBazelBSP/SharedUtils/SplitLogMessage.swift b/Sources/SourceKitBazelBSP/SharedUtils/SplitLogMessage.swift index a801bef4..56563454 100644 --- a/Sources/SourceKitBazelBSP/SharedUtils/SplitLogMessage.swift +++ b/Sources/SourceKitBazelBSP/SharedUtils/SplitLogMessage.swift @@ -22,16 +22,36 @@ import OSLog -/// Splits `message` on newline characters such that each chunk is at most `maxChunkSize` bytes long. +/// Splits `message` such that each chunk is at most `maxChunkSize` bytes long. /// /// The intended use case for this is to split compiler arguments and a file's contents into multiple chunks so /// that each chunk doesn't exceed the maximum message length of `os_log` and thus won't get truncated. /// -/// - Note: This will only split along newline boundary. If a single line is longer than `maxChunkSize`, it won't be -/// split. This is fine for compiler argument splitting since a single argument is rarely longer than 800 characters. -package func splitLongMultilineMessage(message: String) -> [String] { +/// When `splitByCharacterCount` is true, the message is split purely by character count, ignoring any +/// separator logic. Otherwise, splits along newline boundaries (a single line longer than `maxChunkSize` +/// won't be split in that mode). +package func splitLongMultilineMessage( + message: String, + splitByCharacterCount: Bool = false +) -> [String] { let maxChunkSize = 800 var chunks: [String] = [] + + if splitByCharacterCount { + var remaining = message + while !remaining.isEmpty { + if remaining.utf8.count > maxChunkSize { + let endIndex = remaining.utf8.index(remaining.utf8.startIndex, offsetBy: maxChunkSize) + chunks.append(String(remaining[.. HelloWorldLib -> TodoModelsAlias -> TodoModels // HelloWorldTests -> HelloWorldTestsLib -> HelloWorldLib -> ... + // HelloWorldNotificationServiceExtension -> NotificationServiceExtensionLib -> TodoModels // Note: HelloWorldE2ETests is NOT included because test_host is not a dep // macOS: HelloWorldMacApp -> MacAppLib -> TodoModels // HelloWorldMacTests -> MacAppTestsLib -> MacAppLib -> ... @@ -298,58 +315,59 @@ struct BazelTargetQuerierParserImplTests { // HelloWorldWatchTests -> WatchAppTestsLib -> WatchAppLib -> ... // Note: HelloWorldWatchApp is NOT included because extension is not a dep #expect( - getParentLabels(forLabel: "//HelloWorld:TodoModels") + getParentLabels(forLabel: "@@//HelloWorld:TodoModels") == Set([ - "//HelloWorld:HelloWorldMacTests", - "//HelloWorld:HelloWorldMacCLIApp", - "//HelloWorld:HelloWorldMacApp", - "//HelloWorld:HelloWorldWatchTests", - "//HelloWorld:HelloWorldWatchExtension", - "//HelloWorld:HelloWorldTests", - "//HelloWorld:HelloWorld", + "@@//HelloWorld:HelloWorldMacTests", + "@@//HelloWorld:HelloWorldMacCLIApp", + "@@//HelloWorld:HelloWorldMacApp", + "@@//HelloWorld:HelloWorldWatchTests", + "@@//HelloWorld:HelloWorldWatchExtension", + "@@//HelloWorld:HelloWorldTests", + "@@//HelloWorld:HelloWorld", + "@@//HelloWorld:HelloWorldNotificationServiceExtension", ]) ) // TodoObjCSupport is a dep of HelloWorldLib (iOS only) // Note: HelloWorldE2ETests is NOT included because test_host is not a dep #expect( - getParentLabels(forLabel: "//HelloWorld:TodoObjCSupport") + getParentLabels(forLabel: "@@//HelloWorld:TodoObjCSupport") == Set([ - "//HelloWorld:HelloWorldTests", - "//HelloWorld:HelloWorld", + "@@//HelloWorld:HelloWorldTests", + "@@//HelloWorld:HelloWorld", ]) ) // HelloWorldE2ETestsLib is ONLY a dep of HelloWorldE2ETests #expect( - getParentLabels(forLabel: "//HelloWorld:HelloWorldE2ETestsLib") + getParentLabels(forLabel: "@@//HelloWorld:HelloWorldE2ETestsLib") == Set([ - "//HelloWorld:HelloWorldE2ETests" + "@@//HelloWorld:HelloWorldE2ETests" ]) ) // watchOS targets - WatchAppLib is dep of HelloWorldWatchExtension // HelloWorldWatchTests deps on WatchAppTestsLib which deps on WatchAppLib // Note: HelloWorldWatchApp is NOT included because it uses extension attribute, not deps #expect( - getParentLabels(forLabel: "//HelloWorld:WatchAppLib") + getParentLabels(forLabel: "@@//HelloWorld:WatchAppLib") == Set([ - "//HelloWorld:HelloWorldWatchExtension", - "//HelloWorld:HelloWorldWatchTests", + "@@//HelloWorld:HelloWorldWatchExtension", + "@@//HelloWorld:HelloWorldWatchTests", ]) ) // WatchAppTestsLib is ONLY a dep of HelloWorldWatchTests #expect( - getParentLabels(forLabel: "//HelloWorld:WatchAppTestsLib") + getParentLabels(forLabel: "@@//HelloWorld:WatchAppTestsLib") == Set([ - "//HelloWorld:HelloWorldWatchTests" + "@@//HelloWorld:HelloWorldWatchTests" ]) ) // Verify testTargetToBundleTargetMap - maps test targets to their bundle target URIs // These are the test bundle targets that should have their bundle URIs mapped let expectedTestTargets = Set([ - "//HelloWorld:HelloWorldTests", - "//HelloWorld:HelloWorldE2ETests", - "//HelloWorld:HelloWorldMacTests", - "//HelloWorld:HelloWorldWatchTests", + "@@//HelloWorld:HelloWorldTests", + "@@//HelloWorld:HelloWorldE2ETests", + "@@//HelloWorld:HelloWorldMacTests", + "@@//HelloWorld:HelloWorldWatchTests", ]) let actualTestTargets = Set(result.testTargetToBundleTargetMap.keys) #expect( @@ -372,12 +390,12 @@ struct BazelTargetQuerierParserImplTests { // Verify specific bundle target mappings // HelloWorldTests should map to a bundle target containing test sources - let unitTestBundleUri = try #require(result.testTargetToBundleTargetMap["//HelloWorld:HelloWorldTests"]) + let unitTestBundleUri = try #require(result.testTargetToBundleTargetMap["@@//HelloWorld:HelloWorldTests"]) let unitTestSources = try #require(result.bspURIsToSrcsMap[unitTestBundleUri]) #expect(unitTestSources.sources.contains { $0.uri.stringValue.contains("HelloWorldTests/") }) // HelloWorldE2ETests should map to a bundle target containing E2E test sources - let e2eTestBundleUri = try #require(result.testTargetToBundleTargetMap["//HelloWorld:HelloWorldE2ETests"]) + let e2eTestBundleUri = try #require(result.testTargetToBundleTargetMap["@@//HelloWorld:HelloWorldE2ETests"]) let e2eTestSources = try #require(result.bspURIsToSrcsMap[e2eTestBundleUri]) #expect(e2eTestSources.sources.contains { $0.uri.stringValue.contains("HelloWorldE2ETests/") }) } @@ -392,14 +410,14 @@ struct BazelTargetQuerierParserImplTests { let macOsMnemonic = "darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6" let watchOsMnemonic = "watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed" let topLevelTargets: [(String, TopLevelRuleType, String)] = [ - ("//HelloWorld:HelloWorld", .iosApplication, iosMnemonic), - ("//HelloWorld:HelloWorldMacApp", .macosApplication, macOsMnemonic), - ("//HelloWorld:HelloWorldMacCLIApp", .macosCommandLineApplication, macOsMnemonic), - ("//HelloWorld:HelloWorldMacTests", .macosUnitTest, macOsMnemonic), - ("//HelloWorld:HelloWorldTests", .iosUnitTest, iosMnemonic), - ("//HelloWorld:HelloWorldWatchApp", .watchosApplication, watchOsMnemonic), - ("//HelloWorld:HelloWorldWatchExtension", .watchosExtension, watchOsMnemonic), - ("//HelloWorld:HelloWorldWatchTests", .watchosUnitTest, watchOsMnemonic), + ("@@//HelloWorld:HelloWorld", .iosApplication, iosMnemonic), + ("@@//HelloWorld:HelloWorldMacApp", .macosApplication, macOsMnemonic), + ("@@//HelloWorld:HelloWorldMacCLIApp", .macosCommandLineApplication, macOsMnemonic), + ("@@//HelloWorld:HelloWorldMacTests", .macosUnitTest, macOsMnemonic), + ("@@//HelloWorld:HelloWorldTests", .iosUnitTest, iosMnemonic), + ("@@//HelloWorld:HelloWorldWatchApp", .watchosApplication, watchOsMnemonic), + ("@@//HelloWorld:HelloWorldWatchExtension", .watchosExtension, watchOsMnemonic), + ("@@//HelloWorld:HelloWorldWatchTests", .watchosUnitTest, watchOsMnemonic), ] let result = try parser.processAquery( @@ -457,7 +475,8 @@ struct BazelTargetQuerierParserImplTests { rootUri: Self.mockRootUri, workspaceName: Self.mockWorkspaceName, executionRoot: Self.mockExecutionRoot, - outputPath: Self.mockOutputPath + outputPath: Self.mockOutputPath, + outputBase: Self.mockOutputBase ) let targetUri = try URI( diff --git a/Tests/SourceKitBazelBSPTests/BazelTargetQuerierTests.swift b/Tests/SourceKitBazelBSPTests/BazelTargetQuerierTests.swift index 20a59017..f68cd02f 100644 --- a/Tests/SourceKitBazelBSPTests/BazelTargetQuerierTests.swift +++ b/Tests/SourceKitBazelBSPTests/BazelTargetQuerierTests.swift @@ -103,7 +103,7 @@ struct BazelTargetQuerierTests { let config = Self.makeInitializedConfig() let expectedCommand = - "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)))\' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" + "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)))\' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleCqueryOutput) _ = try querier.cqueryTargets( @@ -126,7 +126,7 @@ struct BazelTargetQuerierTests { let config = Self.makeInitializedConfig(targets: ["//HelloWorld", "//Tests"]) let expectedCommand = - "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld) union deps(//Tests)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)))\' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" + "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld) union deps(//Tests)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)))\' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleCqueryOutput) _ = try querier.cqueryTargets( @@ -149,7 +149,7 @@ struct BazelTargetQuerierTests { let config = Self.makeInitializedConfig() let expectedCommand = - "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application|watchos_unit_test\", deps(//HelloWorld)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file|_watchos_internal_unit_test_bundle\", deps($topLevelTargets)))\' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" + "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application|watchos_unit_test\", deps(//HelloWorld)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file|_watchos_internal_unit_test_bundle\", deps($topLevelTargets)))\' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleCqueryOutput) _ = try querier.cqueryTargets( @@ -174,7 +174,7 @@ struct BazelTargetQuerierTests { ) let expectedCommand = - "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) except set(//HelloWorld:Excluded) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)))\' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" + "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) except set(//HelloWorld:Excluded) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)))\' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleCqueryOutput) _ = try querier.cqueryTargets( @@ -199,7 +199,7 @@ struct BazelTargetQuerierTests { ) let expectedCommand = - "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)) except set(//Libs/ExcludedLib:ExcludedLib))\' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" + "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)) except set(//Libs/ExcludedLib:ExcludedLib))\' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleCqueryOutput) _ = try querier.cqueryTargets( @@ -225,7 +225,7 @@ struct BazelTargetQuerierTests { ) let expectedCommand = - "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) except set(//HelloWorld:Excluded //HelloWorld:AlsoExcluded) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)) except set(//Libs/ExcludedLib:ExcludedLib))\' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" + "bazelisk --output_base=/path/to/output/base cquery \'let topLevelTargets = kind(\"ios_application\", deps(//HelloWorld)) except set(//HelloWorld:Excluded //HelloWorld:AlsoExcluded) in $topLevelTargets union (kind(\"swift_library|objc_library|cc_library|alias|filegroup|source file\", deps($topLevelTargets)) except set(//Libs/ExcludedLib:ExcludedLib))\' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleCqueryOutput) _ = try querier.cqueryTargets( @@ -250,7 +250,7 @@ struct BazelTargetQuerierTests { let config = Self.makeInitializedConfig() let expectedCommand = - "bazelisk --output_base=/path/to/output/base aquery \"mnemonic('SwiftCompile', deps(//HelloWorld:HelloWorld))\" --noinclude_artifacts --noinclude_aspects --output proto --config=test" + "bazelisk --output_base=/path/to/output/base aquery \"mnemonic('SwiftCompile', deps(//HelloWorld:HelloWorld))\" --consistent_labels --noinclude_artifacts --noinclude_aspects --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleAqueryOutput) _ = try querier.aquery( @@ -273,7 +273,7 @@ struct BazelTargetQuerierTests { let config = Self.makeInitializedConfig(targets: ["//HelloWorld", "//Tests"]) let expectedCommand = - "bazelisk --output_base=/path/to/output/base aquery \"mnemonic('SwiftCompile|ObjcCompile', deps(//HelloWorld:HelloWorld) union deps(//Tests:Tests))\" --noinclude_artifacts --noinclude_aspects --output proto --config=test" + "bazelisk --output_base=/path/to/output/base aquery \"mnemonic('SwiftCompile|ObjcCompile', deps(//HelloWorld:HelloWorld) union deps(//Tests:Tests))\" --consistent_labels --noinclude_artifacts --noinclude_aspects --output proto --config=test" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleAqueryOutput) _ = try querier.aquery( @@ -302,7 +302,7 @@ struct BazelTargetQuerierTests { ) let expectedCommand = - "bazelisk --output_base=/path/to/output/base aquery \"mnemonic('SwiftCompile', deps(//HelloWorld:HelloWorld))\" --noinclude_artifacts --noinclude_aspects --features=-compiler_param_file --output proto" + "bazelisk --output_base=/path/to/output/base aquery \"mnemonic('SwiftCompile', deps(//HelloWorld:HelloWorld))\" --consistent_labels --noinclude_artifacts --noinclude_aspects --features=-compiler_param_file --output proto" runnerMock.setResponse(for: expectedCommand, cwd: Self.mockRootUri, response: exampleAqueryOutput) _ = try querier.aquery( @@ -337,7 +337,7 @@ struct BazelTargetQuerierTests { // Second cquery: find owning targets let expectedCquery = - "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/File.swift'))\" --output=proto" + "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/File.swift'))\" --consistent_labels --output=proto" runnerMock.setResponse(for: expectedCquery, cwd: Self.mockRootUri, response: exampleCqueryAddedFilesOutput) parserMock.mockCqueryAddedFilesResult = ProcessedCqueryAddedFilesResult( @@ -379,7 +379,7 @@ struct BazelTargetQuerierTests { ) let expectedCquery = - "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/File.swift'))\" --output=proto" + "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/File.swift'))\" --consistent_labels --output=proto" runnerMock.setResponse(for: expectedCquery, cwd: Self.mockRootUri, response: exampleCqueryAddedFilesOutput) parserMock.mockCqueryAddedFilesResult = ProcessedCqueryAddedFilesResult( @@ -442,7 +442,7 @@ struct BazelTargetQuerierTests { ) let expectedCquery = - "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/File.swift'))\" --output=proto" + "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/File.swift'))\" --consistent_labels --output=proto" runnerMock.setResponse(for: expectedCquery, cwd: Self.mockRootUri, response: exampleCqueryAddedFilesOutput) parserMock.mockCqueryAddedFilesResult = ProcessedCqueryAddedFilesResult( @@ -485,7 +485,7 @@ struct BazelTargetQuerierTests { // Second cquery only includes the valid file let expectedCquery = - "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/Valid.swift'))\" --output=proto" + "bazelisk --output_base=/path/to/output/base cquery \"kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorld, '//HelloWorld:HelloWorld/Sources/Valid.swift'))\" --consistent_labels --output=proto" runnerMock.setResponse(for: expectedCquery, cwd: Self.mockRootUri, response: exampleCqueryAddedFilesOutput) parserMock.mockCqueryAddedFilesResult = ProcessedCqueryAddedFilesResult( @@ -540,7 +540,7 @@ struct BazelTargetQuerierTests { } /// Example aquery output for the example app shipped with this repo. -/// bazelisk aquery "mnemonic('CppCompile|ObjcCompile|SwiftCompile|BundleTreeApp|SignBinary|TestRunner', deps(//HelloWorld:HelloWorldMacTests) union deps(//HelloWorld:HelloWorldTests) union deps(//HelloWorld:HelloWorldLibBuildTest) union deps(//HelloWorld:HelloWorld) union deps(//HelloWorld:HelloWorldWatchExtension) union deps(//HelloWorld:HelloWorldWatchTests) union deps(//HelloWorld:HelloWorldMacCLIApp) union deps(//HelloWorld:HelloWorldMacApp) union deps(//HelloWorld:HelloWorldE2ETests) union deps(//HelloWorld:HelloWorldWatchApp))" --noinclude_artifacts --noinclude_aspects --features=-compiler_param_file --output proto --config=index_build > ../Tests/SourceKitBazelBSPTests/Resources/aquery.pb +/// bazelisk aquery "mnemonic('CppCompile|ObjcCompile|SwiftCompile|BundleTreeApp|SignBinary|TestRunner', deps(//HelloWorld:HelloWorldMacTests) union deps(//HelloWorld:HelloWorldTests) union deps(//HelloWorld:HelloWorldLibBuildTest) union deps(//HelloWorld:HelloWorld) union deps(//HelloWorld:HelloWorldWatchExtension) union deps(//HelloWorld:HelloWorldWatchTests) union deps(//HelloWorld:HelloWorldMacCLIApp) union deps(//HelloWorld:HelloWorldMacApp) union deps(//HelloWorld:HelloWorldE2ETests) union deps(//HelloWorld:HelloWorldWatchApp))" --consistent_labels --noinclude_artifacts --noinclude_aspects --features=-compiler_param_file --output proto --config=index_build > ../Tests/SourceKitBazelBSPTests/Resources/aquery.pb let exampleAqueryOutput: Data = { guard let url = Bundle.module.url(forResource: "aquery", withExtension: "pb"), let data = try? Data.init(contentsOf: url) @@ -549,7 +549,7 @@ let exampleAqueryOutput: Data = { }() /// Example cquery output for the example app shipped with this repo. -/// bazelisk cquery 'let topLevelTargets = kind("ios_application|ios_unit_test|macos_application|ios_ui_test|macos_command_line_application|macos_unit_test|watchos_application|watchos_extension|watchos_unit_test", deps(//HelloWorld/...)) in $topLevelTargets union (kind("swift_library|objc_library|cc_library|alias|filegroup|source file|_ios_internal_unit_test_bundle|_ios_internal_ui_test_bundle|_watchos_internal_unit_test_bundle|_watchos_internal_ui_test_bundle|_macos_internal_unit_test_bundle|_macos_internal_ui_test_bundle|_tvos_internal_unit_test_bundle|_tvos_internal_ui_test_bundle|_visionos_internal_unit_test_bundle|_visionos_internal_ui_test_bundle", deps($topLevelTargets)))' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=index_build > ../Tests/SourceKitBazelBSPTests/Resources/cquery.pb +/// bazelisk cquery 'let topLevelTargets = kind("ios_application|ios_extension|ios_unit_test|macos_application|ios_ui_test|macos_command_line_application|macos_unit_test|watchos_application|watchos_extension|watchos_unit_test", deps(//HelloWorld/...)) in $topLevelTargets union (kind("swift_library|objc_library|cc_library|alias|filegroup|source file|_ios_internal_unit_test_bundle|_ios_internal_ui_test_bundle|_watchos_internal_unit_test_bundle|_watchos_internal_ui_test_bundle|_macos_internal_unit_test_bundle|_macos_internal_ui_test_bundle|_tvos_internal_unit_test_bundle|_tvos_internal_ui_test_bundle|_visionos_internal_unit_test_bundle|_visionos_internal_ui_test_bundle", deps($topLevelTargets)))' --consistent_labels --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=index_build > ../Tests/SourceKitBazelBSPTests/Resources/cquery.pb let exampleCqueryOutput: Data = { guard let url = Bundle.module.url(forResource: "cquery", withExtension: "pb"), let data = try? Data.init(contentsOf: url) @@ -558,7 +558,7 @@ let exampleCqueryOutput: Data = { }() /// Example cquery output for an added file event, for the example app shipped with this repo. -/// bazelisk cquery "kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorldLibBuildTest, '//HelloWorld:HelloWorldLib/Sources/TodoItemRow.swift'))" --output=proto --config=index_build > cquery_added_files.pb +/// bazelisk cquery "kind('swift_library|objc_library|cc_library|source file', rdeps(//HelloWorld:HelloWorldLibBuildTest, '//HelloWorld:HelloWorldLib/Sources/TodoItemRow.swift'))" --consistent_labels --output=proto --config=index_build > ../Tests/SourceKitBazelBSPTests/Resources/cquery_added_files.pb let exampleCqueryAddedFilesOutput: Data = { guard let url = Bundle.module.url(forResource: "cquery_added_files", withExtension: "pb"), let data = try? Data.init(contentsOf: url) diff --git a/Tests/SourceKitBazelBSPTests/Fakes/BazelTargetQuerierParserFake.swift b/Tests/SourceKitBazelBSPTests/Fakes/BazelTargetQuerierParserFake.swift index 94b6047b..9308118b 100644 --- a/Tests/SourceKitBazelBSPTests/Fakes/BazelTargetQuerierParserFake.swift +++ b/Tests/SourceKitBazelBSPTests/Fakes/BazelTargetQuerierParserFake.swift @@ -35,7 +35,8 @@ final class BazelTargetQuerierParserFake: BazelTargetQuerierParser { workspaceName: String, executionRoot: String, toolchainPath: String, - outputPath: String + outputPath: String, + outputBase: String ) throws -> ProcessedCqueryResult { guard let mockCqueryResult else { unimplemented() @@ -59,7 +60,8 @@ final class BazelTargetQuerierParserFake: BazelTargetQuerierParser { rootUri: String, workspaceName: String, executionRoot: String, - outputPath: String + outputPath: String, + outputBase: String ) throws -> ProcessedCqueryAddedFilesResult { guard let mockCqueryAddedFilesResult else { unimplemented() diff --git a/Tests/SourceKitBazelBSPTests/IsExternalBazelLabelTests.swift b/Tests/SourceKitBazelBSPTests/IsExternalBazelLabelTests.swift new file mode 100644 index 00000000..44bfa66f --- /dev/null +++ b/Tests/SourceKitBazelBSPTests/IsExternalBazelLabelTests.swift @@ -0,0 +1,81 @@ +// Copyright (c) 2025 Spotify AB. +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 +// +// http://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 Testing + +@testable import SourceKitBazelBSP + +@Suite +struct IsExternalBazelLabelTests { + @Test + func internalLabelWithoutAtPrefix() { + #expect("//foo/bar:target".isExternalBazelLabel() == false) + } + + @Test + func internalLabelWithSingleAtPrefix() { + #expect("@//foo/bar:target".isExternalBazelLabel() == false) + } + + @Test + func internalLabelWithDoubleAtPrefix() { + #expect("@@//foo/bar:target".isExternalBazelLabel() == false) + } + + @Test + func relativeLabel() { + #expect(":target".isExternalBazelLabel() == false) + } + + @Test + func externalRepoLabel() { + #expect("@external_repo//foo:bar".isExternalBazelLabel() == true) + } + + @Test + func bzlmodExternalRepoLabel() { + #expect("@@external_repo//foo:bar".isExternalBazelLabel() == true) + } + + @Test + func externalRepoWithoutPath() { + #expect("@external_repo".isExternalBazelLabel() == true) + } + + @Test + func emptyString() { + #expect("".isExternalBazelLabel() == false) + } + + @Test + func singleAtOnly() { + #expect("@".isExternalBazelLabel() == false) + } + + @Test + func doubleAtOnly() { + #expect("@@".isExternalBazelLabel() == false) + } + + @Test + func tripleAtExternalLabel() { + #expect("@@@repo//foo:bar".isExternalBazelLabel() == true) + } +} diff --git a/Tests/SourceKitBazelBSPTests/Resources/aquery.pb b/Tests/SourceKitBazelBSPTests/Resources/aquery.pb index 89859257..d38a9861 100644 --- a/Tests/SourceKitBazelBSPTests/Resources/aquery.pb +++ b/Tests/SourceKitBazelBSPTests/Resources/aquery.pb @@ -1,51 +1,34 @@ -:macos_unit_test%//HelloWorld:HelloWorldMacTests*ddarwin_arm64-dbg darwin_arm64"@8ca5719d3aebee816bfbdd62eebb094f9da7c732ea68a510daa94c71b5755dfa@7b0fa2f5f5281dece03101911f9e8c1767cc826c6fc7702a48c93b264fe4a482" +:macos_unit_test%//HelloWorld:HelloWorldMacTests:$ _macos_internal_unit_test_bundle@://HelloWorld:HelloWorldMacTests.__internal__.__test_bundle*ddarwin_arm64-dbg darwin_arm64"@8f8065ccdaf2ad454bef6a50ad79bd342ec9e30167243d1ba692d949137105ce*4darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6 darwin_arm64"@dbb22fcdc944be2a78ad10c439902582f287080907077da05b721220f629e229@7b0fa2f5f5281dece03101911f9e8c1767cc826c6fc7702a48c93b264fe4a482" TestRunner(2-external/bazel_tools/tools/test/test-setup.sh2HelloWorld/HelloWorldMacTestsZ -requires-darwinr@@platforms//host:host: objc_libraryB<@@apple_support+//lib:swizzle_absolute_xcttestsourcelocation: swift_library//HelloWorld:MacAppLib//HelloWorld:TodoModels!//HelloWorld:MacAppTestsLib:  cc_binary60@@bazel_tools//src/tools/launcher:launcher_maker:$ _macos_internal_unit_test_bundle@://HelloWorld:HelloWorldMacTests.__internal__.__test_bundle)#@@rules_swift+//tools/worker:worker*4darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6 darwin_arm64"@621a57d318bdd1dc251eb99951e606d2bb8cc4132aa1df6bd16a0528636c3de8@305881d93402e66176a8b465ebe2619556af3ab1502a9c1e063e4e6352b827d2" SwiftCompile(2]bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/worker2swiftc2-target2arm64-apple-macos15.02-sdk2__BAZEL_XCODE_SDKROOT__2-file-prefix-map28__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2=-Xwrapped-swift=-bazel-target-label=@@//HelloWorld:TodoModels2 -emit-object2-output-file-map2mbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.output_file_map.json2 --Xfrontend2-no-clang-module-breadcrumbs2-emit-module-path2dbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.swiftmodule2-enforce-exclusivity=checked2-emit-const-values-path2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels_objs/TodoModels/Sources/TodoItem.swift.swiftconstvalues2 --Xfrontend2-const-gather-protocols-file2 --Xfrontend2Lexternal/rules_swift+/swift/toolchains/config/const_protocols_to_gather.json2-DDEBUG2-Onone2 --Xfrontend2-internalize-at-link2 --Xfrontend2-no-serialize-debugging-options2-enable-testing2-disable-sandbox2-g2'-Xwrapped-swift=-file-prefix-pwd-is-dot2%-Xwrapped-swift=-emit-swiftsourceinfo2-file-compilation-dir2.2-module-cache-path2Vbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/_swift_module_cache2-Xwrapped-swift=-macro-expansion-dir=bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.macro-expansions2-Xcc2-iquote.2-Xcc2I-iquotebazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin2 --Xfrontend2-color-diagnostics2-enable-batch-mode2 -module-name2 -TodoModels2-index-store-path2cbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.indexstore2-index-ignore-system-modules2-enable-bare-slash-regex2 --Xfrontend2-disable-clang-spi2-enable-experimental-feature2AccessLevelOnImport2-parse-as-library2-static2-Xcc2-O02-Xcc2 -DDEBUG=12-Xcc2-fstack-protector2-Xcc2-fstack-protector-all2 --Xfrontend2-checked-async-objc-bridging=on2,HelloWorld/TodoModels/Sources/TodoItem.swift23HelloWorld/TodoModels/Sources/TodoListManager.swift:' -XCODE_VERSION_OVERRIDE 26.1.1.17B100: -APPLE_SDK_PLATFORMMacOSX:" -APPLE_SDK_VERSION_OVERRIDE26.1Z -requires-darwinZ -requires-worker-protocoljsonZ -supports-workers1Z! -supports-xcode-requirements-setr@@platforms//host:host@3b41d77e3680170ba4ab7e371e7be938acf1e3327abd7fc52966e6e9d3745f90" SwiftCompile(2]bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/worker2swiftc2-target2arm64-apple-macos15.02-sdk2__BAZEL_XCODE_SDKROOT__2-file-prefix-map28__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2<-Xwrapped-swift=-bazel-target-label=@@//HelloWorld:MacAppLib2 -emit-object2-output-file-map2lbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppLib.output_file_map.json2 --Xfrontend2-no-clang-module-breadcrumbs2-emit-module-path2cbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppLib.swiftmodule2-enforce-exclusivity=checked2-emit-const-values-path2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppLib_objs/MacApp/MacAppLib/Sources/MacApp.swift.swiftconstvalues2 --Xfrontend2-const-gather-protocols-file2 --Xfrontend2Lexternal/rules_swift+/swift/toolchains/config/const_protocols_to_gather.json2-DDEBUG2-Onone2 --Xfrontend2-internalize-at-link2 --Xfrontend2-no-serialize-debugging-options2-enable-testing2-disable-sandbox2-g2'-Xwrapped-swift=-file-prefix-pwd-is-dot2%-Xwrapped-swift=-emit-swiftsourceinfo2-file-compilation-dir2.2-module-cache-path2Vbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/_swift_module_cache2O-Ibazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld2-Xwrapped-swift=-macro-expansion-dir=bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppLib.macro-expansions2-Xcc2-iquote.2-Xcc2I-iquotebazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin2 --Xfrontend2-color-diagnostics2-enable-batch-mode2 -module-name2 MacAppLib2-index-store-path2bbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppLib.indexstore2-index-ignore-system-modules2-enable-bare-slash-regex2 --Xfrontend2-disable-clang-spi2-enable-experimental-feature2AccessLevelOnImport2-parse-as-library2-static2-Xcc2-O02-Xcc2 -DDEBUG=12-Xcc2-fstack-protector2-Xcc2-fstack-protector-all2 --Xfrontend2-checked-async-objc-bridging=on20HelloWorld/MacApp/MacAppLib/Sources/MacApp.swift:' -XCODE_VERSION_OVERRIDE 26.1.1.17B100: -APPLE_SDK_PLATFORMMacOSX:" -APPLE_SDK_VERSION_OVERRIDE26.1Z -requires-darwinZ -requires-worker-protocoljsonZ -supports-workers1Z! -supports-xcode-requirements-setr@@platforms//host:host*{%darwin_arm64-opt-exec-ST-d57f47055a04 darwin_arm64"@ce3fb6fae2997484cd84f6aa36507b231b4f702e38f5aed65831c7030dab9c62(@e5a18b0250f4a457e3a3ff2c5319847d32c75100c3585954b62a80f9db9a48c1" BundleTreeApp(2rbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_apple+/tools/bundletool/bundletool_experimental2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/HelloWorldMacTests.__internal__.__test_bundle-intermediates/bundletool_control.json:' +requires-darwinr@@platforms//host:host@e5a18b0250f4a457e3a3ff2c5319847d32c75100c3585954b62a80f9db9a48c1" BundleTreeApp(2rbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_apple+/tools/bundletool/bundletool_experimental2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/HelloWorldMacTests.__internal__.__test_bundle-intermediates/bundletool_control.json:' XCODE_VERSION_OVERRIDE 26.1.1.17B100: APPLE_SDK_PLATFORMMacOSX:" APPLE_SDK_VERSION_OVERRIDE26.1Z no-sandbox1Z requires-darwinZ! -supports-xcode-requirements-setr@@platforms//host:host: -cc_library6 0@@rules_swift+//tools/worker:compile_with_worker@093f80d28e6a1cde5c7bf09519ef45dd303dabd15f27b00ed8f3fe355f03d6c8" SwiftCompile(2]bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/worker2swiftc2-target2arm64-apple-macos15.02-sdk2__BAZEL_XCODE_SDKROOT__2-file-prefix-map28__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2A-Xwrapped-swift=-bazel-target-label=@@//HelloWorld:MacAppTestsLib2 -emit-object2-output-file-map2qbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppTestsLib.output_file_map.json2 +supports-xcode-requirements-setr@@platforms//host:host: objc_libraryB<@@apple_support+//lib:swizzle_absolute_xcttestsourcelocation@d192ff49785fd9c228648fca03ba4dc099d0fa6f9d6e254a7c456afa578647c3" ObjcCompile(2cbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g2--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-Werror=incompatible-sysroot2-Wshorten-64-to-322-Wbool-conversion2-Wconstant-conversion2-Wduplicate-method-match2 -Wempty-body2-Wenum-conversion2-Wint-conversion2-Wunreachable-code2-Wmismatched-return-types2-Wundeclared-selector2-Wuninitialized2-Wunused-function2-Wunused-variable2-iquote2external/apple_support+2-iquote2Zbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/external/apple_support+2-MD2-MF2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/external/apple_support+/lib/_objs/swizzle_absolute_xcttestsourcelocation/arc/swizzle_absolute_xcttestsourcelocation.d2 -DOS_MACOSX2 -fno-autolink2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2 +-fobjc-arc2-no-canonical-prefixes2-target2arm64-apple-macosx15.02-O02 -DDEBUG=12-fstack-protector2-fstack-protector-all2-g2-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c2Dexternal/apple_support+/lib/swizzle_absolute_xcttestsourcelocation.m2-o2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/external/apple_support+/lib/_objs/swizzle_absolute_xcttestsourcelocation/arc/swizzle_absolute_xcttestsourcelocation.o:' +XCODE_VERSION_OVERRIDE 26.1.1.17B100:" +APPLE_SDK_VERSION_OVERRIDE26.1: +APPLE_SDK_PLATFORMMacOSX: + ZERO_AR_DATE1PZ +requires-darwinZ! +supports-xcode-requirements-setr@@platforms//host:host: swift_library!//HelloWorld:MacAppTestsLib//HelloWorld:MacAppLib//HelloWorld:TodoModels:  cc_binary60@@bazel_tools//src/tools/launcher:launcher_maker*{%darwin_arm64-opt-exec-ST-d57f47055a04 darwin_arm64"@ce3fb6fae2997484cd84f6aa36507b231b4f702e38f5aed65831c7030dab9c62( @223c0ee7c56659ba24a7fd11b26f535736284219ce14cbdfa0b1b8106fda2fc6" +CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang_pp2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g02-O22-DNDEBUG2-DNS_BLOCK_ASSERTIONS=12--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-iquote2external/bazel_tools2-iquote2Hbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/bazel_tools2-MD2-MF2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/bazel_tools/src/tools/launcher/_objs/launcher_maker/launcher_maker.d2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2-no-canonical-prefixes2-target2arm64-apple-macosx26.12 +-std=c++172-g02-g02-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c29external/bazel_tools/src/tools/launcher/launcher_maker.cc2-o2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/bazel_tools/src/tools/launcher/_objs/launcher_maker/launcher_maker.o:' +XCODE_VERSION_OVERRIDE 26.1.1.17B100:" +APPLE_SDK_VERSION_OVERRIDE26.1: +APPLE_SDK_PLATFORMMacOSX: + ZERO_AR_DATE1PZ +requires-darwinZ! +supports-xcode-requirements-setr@@platforms//host:host@29934410bfae259701556170fa39d8c7f902013078217587d9fba66b8f00a318" SwiftCompile(2]bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/worker2swiftc2-target2arm64-apple-macos15.02-sdk2__BAZEL_XCODE_SDKROOT__2-file-prefix-map28__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2A-Xwrapped-swift=-bazel-target-label=@@//HelloWorld:MacAppTestsLib2 -emit-object2-output-file-map2qbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppTestsLib.output_file_map.json2 -Xfrontend2-no-clang-module-breadcrumbs2-emit-module-path2hbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppTestsLib.swiftmodule2-enforce-exclusivity=checked2-emit-const-values-path2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppTestsLib_objs/MacApp/MacAppTests/TodoItemMacTests.swift.swiftconstvalues2 -Xfrontend2-const-gather-protocols-file2 -Xfrontend2Lexternal/rules_swift+/swift/toolchains/config/const_protocols_to_gather.json2-DDEBUG2-Onone2 -Xfrontend2-internalize-at-link2 -Xfrontend2-no-serialize-debugging-options2-enable-testing2-disable-sandbox2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2K-I__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/usr/lib2-g2'-Xwrapped-swift=-file-prefix-pwd-is-dot2%-Xwrapped-swift=-emit-swiftsourceinfo2-file-compilation-dir2.2-module-cache-path2Vbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/_swift_module_cache2O-Ibazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld2-Xwrapped-swift=-macro-expansion-dir=bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppTestsLib.macro-expansions2 -plugin-path2A__BAZEL_SWIFT_TOOLCHAIN_PATH__/usr/lib/swift/host/plugins/testing2-Xcc2-iquote.2-Xcc2I-iquotebazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin2 --Xfrontend2-color-diagnostics2-enable-batch-mode2 -module-name2MacAppTestsLib2-index-store-path2gbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppTestsLib.indexstore2-index-ignore-system-modules2-enable-bare-slash-regex2 +-Xfrontend2-color-diagnostics2-enable-batch-mode2 -module-name2MacAppTestsLib2-index-store-path2gbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/MacAppTestsLib.indexstore2-index-ignore-system-modules2M-Xwrapped-swift=-global-index-store-import-path=bazel-out/_global_index_store2-enable-bare-slash-regex2 -Xfrontend2-disable-clang-spi2-enable-experimental-feature2AccessLevelOnImport2-parse-as-library2-static2-Xcc2-O02-Xcc2 -DDEBUG=12-Xcc2-fstack-protector2-Xcc2-fstack-protector-all2 -Xfrontend2-checked-async-objc-bridging=on24HelloWorld/MacApp/MacAppTests/TodoItemMacTests.swift:' XCODE_VERSION_OVERRIDE 26.1.1.17B100: @@ -54,23 +37,8 @@ cc_library6 0@@rules_swift+//tools/worker:compile_with_worker requires-darwinZ requires-worker-protocoljsonZ supports-workers1Z! -supports-xcode-requirements-setr@@platforms//host:host @223c0ee7c56659ba24a7fd11b26f535736284219ce14cbdfa0b1b8106fda2fc6" -CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang_pp2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g02-O22-DNDEBUG2-DNS_BLOCK_ASSERTIONS=12--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-iquote2external/bazel_tools2-iquote2Hbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/bazel_tools2-MD2-MF2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/bazel_tools/src/tools/launcher/_objs/launcher_maker/launcher_maker.d2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2-no-canonical-prefixes2-target2arm64-apple-macosx26.12 --std=c++172-g02-g02-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c29external/bazel_tools/src/tools/launcher/launcher_maker.cc2-o2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/bazel_tools/src/tools/launcher/_objs/launcher_maker/launcher_maker.o:' -XCODE_VERSION_OVERRIDE 26.1.1.17B100:" -APPLE_SDK_VERSION_OVERRIDE26.1: -APPLE_SDK_PLATFORMMacOSX: - ZERO_AR_DATE1PZ -requires-darwinZ! -supports-xcode-requirements-setr@@platforms//host:host@c99269b38bb31b914c97264933ab81f1b783be9579784a83421fa52ae3799e92" -CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang_pp2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g02-O22-DNDEBUG2-DNS_BLOCK_ASSERTIONS=12--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-iquote2external/rules_swift+2-iquote2Ibazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+2-iquote2external/nlohmann_json+2-iquote2Kbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+2-iquote2external/bazel_tools2-iquote2Hbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/bazel_tools2-iquote2external/rules_cc+2-iquote2Fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_cc+2o-Ibazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_cc+/cc/runfiles/_virtual_includes/runfiles2-isystem2external/nlohmann_json+/include2-isystem2Sbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+/include2-MD2-MF2qbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/_objs/worker/worker_main.d2)-DBAZEL_CURRENT_REPOSITORY="rules_swift+"2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2-no-canonical-prefixes2-target2arm64-apple-macosx26.12 --std=c++172-g02-g02-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c21external/rules_swift+/tools/worker/worker_main.cc2-o2qbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/_objs/worker/worker_main.o:' -XCODE_VERSION_OVERRIDE 26.1.1.17B100:" -APPLE_SDK_VERSION_OVERRIDE26.1: -APPLE_SDK_PLATFORMMacOSX: - ZERO_AR_DATE1PZ -requires-darwinZ! -supports-xcode-requirements-setr@@platforms//host:host  @b0645c6f78bb79d8cb3f629ddc265b8b12a30d25f7c558fdeb91ac9e760c7887" +supports-xcode-requirements-setr@@platforms//host:host: +cc_library60@@rules_swift+//tools/worker:compile_with_worker @b0645c6f78bb79d8cb3f629ddc265b8b12a30d25f7c558fdeb91ac9e760c7887" CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang_pp2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g02-O22-DNDEBUG2-DNS_BLOCK_ASSERTIONS=12--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-iquote2external/rules_swift+2-iquote2Ibazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+2-iquote2external/nlohmann_json+2-iquote2Kbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+2-isystem2external/nlohmann_json+/include2-isystem2Sbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+/include2-MD2-MF2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/_objs/compile_with_worker/compile_with_worker.d2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2-no-canonical-prefixes2-target2arm64-apple-macosx26.12 -std=c++172-g02-g02 -std=c++172-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c29external/rules_swift+/tools/worker/compile_with_worker.cc2-o2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/_objs/compile_with_worker/compile_with_worker.o:' @@ -79,8 +47,24 @@ CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple APPLE_SDK_PLATFORMMacOSX: ZERO_AR_DATE1PZ requires-darwinZ! +supports-xcode-requirements-setr@@platforms//host:host) #@@rules_swift+//tools/worker:worker@e832360303b903ecc2faf3fecfd6bbc1a59a17c943bd8b8374d4fe220e63aa8c" SwiftCompile(2]bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/worker2swiftc2-target2arm64-apple-macos15.02-sdk2__BAZEL_XCODE_SDKROOT__2-file-prefix-map28__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2=-Xwrapped-swift=-bazel-target-label=@@//HelloWorld:TodoModels2 -emit-object2-output-file-map2mbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.output_file_map.json2 +-Xfrontend2-no-clang-module-breadcrumbs2-emit-module-path2dbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.swiftmodule2-enforce-exclusivity=checked2-emit-const-values-path2bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels_objs/TodoModels/Sources/TodoItem.swift.swiftconstvalues2 +-Xfrontend2-const-gather-protocols-file2 +-Xfrontend2Lexternal/rules_swift+/swift/toolchains/config/const_protocols_to_gather.json2-DDEBUG2-Onone2 +-Xfrontend2-internalize-at-link2 +-Xfrontend2-no-serialize-debugging-options2-enable-testing2-disable-sandbox2-g2'-Xwrapped-swift=-file-prefix-pwd-is-dot2%-Xwrapped-swift=-emit-swiftsourceinfo2-file-compilation-dir2.2-module-cache-path2Vbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/_swift_module_cache2-Xwrapped-swift=-macro-expansion-dir=bazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.macro-expansions2-Xcc2-iquote.2-Xcc2I-iquotebazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin2 +-Xfrontend2-color-diagnostics2-enable-batch-mode2 -module-name2 +TodoModels2-index-store-path2cbazel-out/darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6/bin/HelloWorld/TodoModels.indexstore2-index-ignore-system-modules2M-Xwrapped-swift=-global-index-store-import-path=bazel-out/_global_index_store2-enable-bare-slash-regex2 +-Xfrontend2-disable-clang-spi2-enable-experimental-feature2AccessLevelOnImport2-parse-as-library2-static2-Xcc2-O02-Xcc2 -DDEBUG=12-Xcc2-fstack-protector2-Xcc2-fstack-protector-all2 +-Xfrontend2-checked-async-objc-bridging=on2,HelloWorld/TodoModels/Sources/TodoItem.swift23HelloWorld/TodoModels/Sources/TodoListManager.swift:' +XCODE_VERSION_OVERRIDE 26.1.1.17B100: +APPLE_SDK_PLATFORMMacOSX:" +APPLE_SDK_VERSION_OVERRIDE26.1Z +requires-darwinZ +requires-worker-protocoljsonZ +supports-workers1Z! supports-xcode-requirements-setr@@platforms//host:host9 -3@@rules_swift+//tools/worker:compile_without_worker  @73359a8c89aa3546b9e6f302910141d4a6726acc9c75cf4e84945d51f4cfb5f4" +3@@rules_swift+//tools/worker:compile_without_worker @73359a8c89aa3546b9e6f302910141d4a6726acc9c75cf4e84945d51f4cfb5f4" CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang_pp2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g02-O22-DNDEBUG2-DNS_BLOCK_ASSERTIONS=12--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-iquote2external/rules_swift+2-iquote2Ibazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+2-iquote2external/nlohmann_json+2-iquote2Kbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+2-isystem2external/nlohmann_json+/include2-isystem2Sbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+/include2-MD2-MF2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/_objs/compile_with_worker/work_processor.d2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2-no-canonical-prefixes2-target2arm64-apple-macosx26.12 -std=c++172-g02-g02 -std=c++172-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c24external/rules_swift+/tools/worker/work_processor.cc2-o2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/_objs/compile_with_worker/work_processor.o:' @@ -89,24 +73,40 @@ CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple APPLE_SDK_PLATFORMMacOSX: ZERO_AR_DATE1PZ requires-darwinZ! -supports-xcode-requirements-setr@@platforms//host:host' !@@rules_cc+//cc/runfiles:runfiles/ )@@rules_swift+//tools/worker:swift_runner2 ,@@rules_swift+//tools/worker:worker_protocol*$@@rules_swift+//tools/common:process  @b50463ed3410f18396872bc907644f6000121937d5ebc87c0938879c7cd5df6d" -CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang_pp2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g02-O22-DNDEBUG2-DNS_BLOCK_ASSERTIONS=12--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-iquote2external/rules_cc+2-iquote2Fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_cc+2o-Ibazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_cc+/cc/runfiles/_virtual_includes/runfiles2-MD2-MF2lbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_cc+/cc/runfiles/_objs/runfiles/runfiles.d2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2-no-canonical-prefixes2-target2arm64-apple-macosx26.12 --std=c++172-g02-g02-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c2*external/rules_cc+/cc/runfiles/runfiles.cc2-o2lbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_cc+/cc/runfiles/_objs/runfiles/runfiles.o:' +supports-xcode-requirements-setr@@platforms//host:host +@38e8c492a631ecdcb5c24e04119d68386981044455cf384a40ce55391c99f043" +CppCompile(2fbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/apple_support+/crosstool/wrapped_clang_pp2-D_FORTIFY_SOURCE=12-fstack-protector2-fcolor-diagnostics2-Wall2-Wthread-safety2 -Wself-assign2-fno-omit-frame-pointer2-g02-O22-DNDEBUG2-DNS_BLOCK_ASSERTIONS=12--fdebug-prefix-map=__BAZEL_EXECUTION_ROOT__=.2K-fdebug-prefix-map=__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2-iquote2external/rules_swift+2-iquote2Ibazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+2-iquote2external/nlohmann_json+2-iquote2Kbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+2-isystem2external/nlohmann_json+/include2-isystem2Sbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/nlohmann_json+/include2-MD2-MF2bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/_objs/compile_without_worker/compile_without_worker.d2 -isysroot2__BAZEL_XCODE_SDKROOT__23-F__BAZEL_XCODE_SDKROOT__/System/Library/Frameworks2V-F__BAZEL_XCODE_DEVELOPER_DIR__/Platforms/MacOSX.platform/Developer/Library/Frameworks2-no-canonical-prefixes2-target2arm64-apple-macosx26.12 +-std=c++172-g02-g02 +-std=c++172-Wno-builtin-macro-redefined2-D__DATE__="redacted"2-D__TIMESTAMP__="redacted"2-D__TIME__="redacted"2-c2-Xwrapped-swift=-bazel-target-label=@@//HelloWorld:WatchAppLib2 -emit-object2-output-file-map2pbazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld/WatchAppLib.output_file_map.json2 +supports-xcode-requirements-setr@@platforms//host:host @4aa89ea179ff491918b7e5bd9f948c4a96730aad68d4a32e9ac20dff27d54f9c" SwiftCompile(2]bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_swift+/tools/worker/worker2swiftc2-target2 arm64-apple-watchos7.0-simulator2-sdk2__BAZEL_XCODE_SDKROOT__2-file-prefix-map28__BAZEL_XCODE_DEVELOPER_DIR__=/PLACEHOLDER_DEVELOPER_DIR2>-Xwrapped-swift=-bazel-target-label=@@//HelloWorld:WatchAppLib2 -emit-object2-output-file-map2pbazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld/WatchAppLib.output_file_map.json2 -Xfrontend2-no-clang-module-breadcrumbs2-emit-module-path2gbazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld/WatchAppLib.swiftmodule2-enforce-exclusivity=checked2-emit-const-values-path2bazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld/WatchAppLib_objs/WatchApp/WatchAppLib/Sources/WatchApp.swift.swiftconstvalues2 -Xfrontend2-const-gather-protocols-file2 -Xfrontend2Lexternal/rules_swift+/swift/toolchains/config/const_protocols_to_gather.json2-DDEBUG2-Onone2 -Xfrontend2-internalize-at-link2 -Xfrontend2-no-serialize-debugging-options2-enable-testing2-disable-sandbox2-g2'-Xwrapped-swift=-file-prefix-pwd-is-dot2%-Xwrapped-swift=-emit-swiftsourceinfo2-file-compilation-dir2.2-module-cache-path2Xbazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/_swift_module_cache2Q-Ibazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld2-Xwrapped-swift=-macro-expansion-dir=bazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld/WatchAppLib.macro-expansions2-Xcc2-iquote.2-Xcc2K-iquotebazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin2 --Xfrontend2-color-diagnostics2-enable-batch-mode2 -module-name2 WatchAppLib2-index-store-path2fbazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld/WatchAppLib.indexstore2-index-ignore-system-modules2-enable-bare-slash-regex2 +-Xfrontend2-color-diagnostics2-enable-batch-mode2 -module-name2 WatchAppLib2-index-store-path2fbazel-out/watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed/bin/HelloWorld/WatchAppLib.indexstore2-index-ignore-system-modules2M-Xwrapped-swift=-global-index-store-import-path=bazel-out/_global_index_store2-enable-bare-slash-regex2 -Xfrontend2-disable-clang-spi2-enable-experimental-feature2AccessLevelOnImport2-parse-as-library2-static2-Xcc2-O02-Xcc2 -DDEBUG=12-Xcc2-fstack-protector2-Xcc2-fstack-protector-all2 -Xfrontend2-checked-async-objc-bridging=on26HelloWorld/WatchApp/WatchAppLib/Sources/WatchApp.swift:' XCODE_VERSION_OVERRIDE 26.1.1.17B100:$ @@ -386,20 +336,78 @@ TodoModels2-index-store-path2ebazel-out/watchos_arm64-dbg-watchos-arm64-min7.0- requires-darwinZ requires-worker-protocoljsonZ supports-workers1Z! -supports-xcode-requirements-setr@@platforms//host:host#//HelloWorld:WatchAppTestsLib$@c1996ae5370f8613a7a4f8da98728adf3db32fc5707677e8a7ffe85e162c90ae" BundleTreeApp(2rbazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_apple+/tools/bundletool/bundletool_experimental2bazel-out/ios_sim_arm64-dbg-ios-sim_arm64-min17.0-ST-2842469f5300/bin/HelloWorld/HelloWorldE2ETests.__internal__.__test_bundle-intermediates/bundletool_control.json:' +supports-xcode-requirements-setr@@platforms//host:host:&"_watchos_internal_unit_test_bundleB!Hr>AGP ziFw`h%wiYPx#}#JOXWyD$*#yMTXtDFMYg5bk}O%4Wm}43#W^c-TuPM`<#egUsiYD+ zm5P!|{&7{}e7?U|Kc;7m7ddbRBT)i~_7Jkx5o>#l8e-B$DT^6Uqm)A43IEqm3f%z7Pr)@$`Tw)4>K zPFJkQPJO!KwP%;ttwy`<1X`WF`oWEx*US02LOEBO{IePM$^{EOKB~K3*R1uLHZ^Z{ zJ66+k>90q2O?`Cb3UATuwpw*>c2@kMYk9LV)lB`lJoM}8bAKcA+~j-gS zYl-F-*wG7Cr%@`Jg?zXj>{T1h*IJzhR>W@i%Bq~GnP)G_n*LBRmE-Z%M4citM4ia| zPsCSpLbcZBABIO5TMMN`t=HM93zc58iY0ferq`?0+;uE|&Fa;=N1mU`n4;J+J9xpi z`Nrd%xpW$)V^4$KZkO#|r{grcX0U>2<}2((s2LOM_Q>i~oeml-Ub)ig)g5uZ9c(V& zY-}qZOsF-#o@n<&cKU+7>ej0?^_siV>+suQR(p-c#`c;%hpiWlVp-Zwv+6W$*YS?L zAbS2fW+cyQr`K#c9kc7;rdeGF-M$k$qgkA0r_;3Rv#O|94jp>+v*_W=I1Ns7&F!?B z4O&&)eUENK{Br5W%YAiB&<@e$G&_8O2ubKjz8pGTEw8MLzrqe(a6QvmckEu*s??n$ zhfZduc6U2H9KCjC@=N&Mu)?P!KYZ$CRo?T@lo(qM7X}}rqdOKI9WNuQ)Uf;d!kYct zurz!uecRx-72b(icH}~LEjqHJ(UDORF|c`@oi*13^^8_J8Lgy>iHdXV2cDO=+GptI`W zR;cUpHal2ew_8F+O(d)5vq*eLYE@S##lNXl@`YJnVRjd3xvg&5tZ9c?>bDQm6 zS6|4J?66hm_p1w%M$4f3HrR`}W~N*?8V)`@ zCpyObX#G5Qr5TwyhNQl<+8B}?DX-9IgCOGOnvdM>s#*|C6eO+V2v*|A^P+=GY&U+z zjPhp(@*y|fikJiX#3H%fxTZ>jWK3jFz18yMqXp_pWCh1H zc7(^+Vg9+@X|%C53>CUs`_yoqm!ArN% zsDO#V8S?zy`yyk`I(D6IEG@v?zy-L~>bf<_gWYpF#H%c;nqphah z#|6vb*AB1L6g%ZM?RpQFQLTpCG{vC{1Sp_O?pvNCra z!F77GH&ASbmlM-G!wk&XY|~Z7HrkHoweZ@Db8?&=tXtqUS53EJt@y9%Y4(!*-2>;g zQE7okP<60wbn$~n9DUHtiFfF>a4Yzv)cL>2&NbX7xWEQI;Puu9e?>u9*T6RuW2>*$ ztISX(L!Wo&=4Y~EHmBHbxri)!ozJnutzH+T2xrR18NzH{EWf~Z-@1Kk8D|zmv2EE8 zF-x=IbS>NlOWngW?4aTy&F)5q6={k~#VB)c-PAh$Cz-b&uv$*C4H3%O|b4rd^O)2MlC9 zRXD}=buoojv%V2Mr?^2Rm2e(aw~ynY7$YUCdHhvKXBd@r@z;@p^Evx&LIIfryZCr~h`tCqKl?Yy!$zfiSmg`(rk zRV*j#IP>{zzLu*jW~+0#LaydiYIC`~Z99c(KIc@dYALrkUny86r&uY>+u5n1w0df5 zge<}ArjihX{JDXvGy~dTT%EjP6>3hYR?RM2iW5YY`5xl;xzmc zcE@d#3@{bTJJDRwT)2{GZiF=RL^=IM$doix;@G<`c$^pVxK1$|20kBINK9i1j4rPV z%G7I{o>~uR2nN;ni;E`SQN2IvV6V6U`o@UbvZSbglO4OT-l&`Y>#9d_c|<#*YNE9= z+s|8j)N#SPVrPfUgsO{jqVALA-@nFA`vkI3SKxqWmWWIE!R|MxZX58cH8B_w~@?h_52F}ajPx(w6AKlmLJ z45WDWUSzwVhTuFq`omvQe$~MlSIpVg`2Qh1ehgO)Mx<7^9`^AHGXogw{)a(K2GX^E z*#n&R3IBOfN>%<2h+5Mz4ERyMhQFAiI0nmE*(hU^oQs_pz{T#;Ozdl#i5)VKA^ht3 zetvZ?XO5KKV-SydpS>WoGoTdL;*~OVguollDy^R=uhbk$GbxokV#&_3{ltcn?hg-1 zl-)eWc6;t);;CO~I90dT5M*MrJSQ=w^j2vq*07px4ZkS*fqTmffd3{6u7wKl;QV*e zWvH@K?6m&Pgl0_&`t_DYn$WOv?PQ4A4XWKvv%U0eLg+wm`x;ORKt_~u_2&8DSgv;z z+gi!aTcvE#UZ|ApQpvU}b6{d~*=#m%6-skXF`q3txw(asRjg%8xl(n(a^~mri`HBT z+-oscAPwnusLWVS5%Hh3l0CmTU&88HS*lpt=>14G6V*A`^saVbxQ`1hw zOr*8Df)IRqO*^y0O*=vLqF9R5$m6cW8hM_+3Fc{=SW?r6<6G9ARnvzwa3nBh46t6j z6SiJV#al0CVwB&46MG}pqR~%i2FW-(ZrgZUi#Ib7#v^7K8XWx|Z`G|P}T7wW<88A<@JnZZArmPfC)#5Oxg|#<)sd3n86<2YH_%_ts@FXk> zpC!A&C<$uYivLX#GEx~Qy&Cz&NZDiuaOSbw9+OW0kIt}fpMgyE=g+Y71IO~dWy8*5 zyd=CvNbx>4=eWfZ>GM zm&~j*6Bg}G4-oC}mMW$CGwGc6rWWAfK^fv>FmiAKpHfi`%6ToSX}6Z+ArG@%AOzxc zoeMgaL@X=IA5JF*hQ;Wft?BdPPP1kRb0&3_FNtYr|QC@U96#qwYX?i^M&jJ9Ks6omSY!k zmhD*i?9@PVI7Hy?hM$ z&mEJSR&lPJ%cpKy6cDC)Zd`rt|KI1$pSo$0=d~b;shd{nrX^0oAQQ%uant&eW`jQ$ zVS{~&t!U>b+ezzU(CI1={SbT*HqDZ9`Y&o-ieX8O{zVjpx9^;lAjIHR&GHQ#$5xg5 zgZ#4Y1pKl-AFp{Jf2A0|EP9s1u3BQHw&arqS1l0-kbeQ*RXwXN+8P-Tuw~z@>5y;M z)Zn;lF_2G<+txy{RG2Rzjv%{GoiFAKbG2Gwu~xO~Y+V1HamoL{*_9Mic{_s)u%0L1uI8*MlHO3Hv!Xi0s zr6B|r7~E#>52)VdhMnjZF9Q@)0xg zB8>%oo(K!BSS;7)?Rf4bnCet^BGy<`w!42Z{&hmbEi@f|}LfIxZ@ zTNmqMgW%f$h|?avk7DIw;>=?mYeMi$0sDnS^9p?q#FWd=L(rR+A|Vd|oe0g=4|(9T zg>Tfe;`TB+Kt0w3qNX9XYwLb5Bcs>H7y_|1&lf-?_^?;nh2)con>5Pt1sFe-O08h! z3MCjD<`);L2(ivNxy9cc=A**vX7`8cUaXxE1b8v*2cjg!De0FiJ2L96qHvx;7nEROXAJ5;eeM?ogK8WuhmR@R>z zpsW`Un_yjsCt%odUA(Du@%b~6cUZr^2xrX$Qg?tRN*9~qShrPxt4fG|F~6~ctHRNG zcmjnOt@sZN5Lia=6=DXPkY6|(A!=QYah!VDSK#So6Q!?46zRxo6k2azk*+KDY0@D= zh(iHdKn+cN_iXqlrMRe5;pA>msQ@J^hU0o~D^2D0^R`%;O^vP*W+1G95SBn-{!C?&HTuiD*^4R=tPZ%`2i6Zfz;XJ zNK8f3X%9(#w&T*&jFzUNsOCzV;-0=*q}rMxXQ#4cZ(sTuh&HNN8;z&3Su;?6>zVg% zMC?Gt_&_`9@>Ra>)T~~;OB;0+NhRyf9ZDrG4%=oWsN^=G(L&NYT1c9WFt+?m4RKKt zYyFJKP6vG}5pH@+(&(*%MO{ZSXzZCXAd8gUM|O{jBM^)C7-`%y^rG!dRzK1=A&O{c zGFXqYU2Qv;-zZv^zdBs-8g)KN9?Op~C+ThC2`IK7nejgzVSn`q1h=0&!iHwpHV%S6 zsZr|pN(ZUhw=IF?vhxH3Rbm5l@Ofx`LuS2dWyPcvkb(ex5y^>>)0lptq~m;Sc1xv< zrbOhP_z}z%|5%PIE!qM>C|h>dZ8b4F4|*1)sFbMDCHA^ie`IZtENa(#$Vyvv)|`5a z8uJ{hW3QTRtGnt&6AGPXOw=RecqHHD0Jea?$qlsTRxqJQZg*7;;t<z`lb-z_@y^po6drNiK^73)tZ&yCPcCXi_gvj~m zMOa>M!*$ZB-gl7v9Vt5Vhpt@Nuo@l~zx*No?8}e-9xXBoRrFV zJ0>&SI#qMkp=_k4)VN7@>s59{mGESV=;nq(8pj#&ILTg;*UNO)NQS_XjCLNQp2T6J zV+Nmtu4_jQ+iPsUydrX%2mLowb6;omiyHTJ$a{H$9cWwjL(2aiUPYYAcD=XaHg#|x zPJO%Mu3^t90iphRkPpS5;IMif8|CuIr4b?op$W|1YxO#Sp`Kl;R_PRf#dRLd@C%;@ zjzEHXerxarmNk?0NZs8)T8g_Z)gy9RBv1oC33glxHRMz@QVyfarRWDEJy zTp?FnT%4O4MPH`QMOHdYPo|P>VBe9M+VYV}*kj+3ncC`+nTjLP0TLejJwU?As2Vz} z>Uo`tkZ#Uq6lzYX2HZ?*u|j!)a|?@wImET*oyxoeEcaXmAF~d?G=YYmxAJq}SKAdB)9U07;&>j1fAll$qExGjUP#5>ZT9I^*IX zrq8c3$g`f+bqZd1I?=~Eeb zD!06neGtd~#T}E6ViE-R4w?c59&u_4Oih7q)%1F`n!BzL z-;X>$)t}org^U{j8J8xJPtAZ{Sz0&*>yv`E4aAe!Av56XQ8QpXmhp~T0JB;^7@Yiy z>#{Y!x;6dZPT2s5rG$Tu3?wm;V6pgU&k~IGC&B_aI4W#jB@JBEqRo`AzZ+#;5u(Eo z!RJY(jo&fL-{%Kd{syBUXls&KoKKr~^cne-xow<}J|i#c zDG-$5O!(&so4*ZFy5Q(wCq)@G7C0hR)j?Wn_!w_@=jO0_U!Vy1qU)G z;MY6rgVQL_@j$y}Q2(jpbmG=r&#kz1x4Ti6Zbrrnle?R}dY%2<4EqiZ`mbl$ROE2_ zjf>M5XxjMN7>3-}YN7%EYKHx78t~6%*e0<}J{r%M1u$Y@F%k{?`)Al+qV!LH;SAeW zid5rl#Ny|gUEiO1+m5Gso*OxZWBjZ_rlg^N;|l#t?R}}eFSYl*om$`ypi42Er`1pJ7O0$2&>Ps-rU~oi2e1JhgoBS?B_^kdRecG*l7YBes z?k8uap5SQ2wj@V@6r78wH3Gptyz`$Hv)|{m&^z6KqP7$F_ldXsT^(Tg8=T}voe;7> zi6b@5UgUiCYRl^)xmeV%*I#i_e2Sgc#ZA{!;fD1V1=U2NP!Lc{Wn0bqM&Qd+4F=q{ zU2yRFOeG?J`70xdKsHwF7S(EmW-PEd9U2-U~>LzkD0UQ8p}Pds*uOqM^DN2#iCVIe12u0LMc)k#~V$iTzIM@%zkW zu=|9||2i2&to*MI_7F}}ocSS!@$Kb-fY)rt5#~%Cv_A;fV8?uaH?INE3#T;zpF;QF zZRf-rPQHc+@p^epKX}o^A>~RFf!;Pkh}SJ(gT@q+`G4(af17-?es(__0w6nXXWu-f zUrxQWQZKDfnU~h9Q7^6i%11?WHm9}9y8qjd2WjV=cyDM=t#U-aq{cq0{(?zpZ!Ps( z>aP{+uN74W`?2&>+gN6KYR#8|NlG4MhCM*Y5(;tD;TeSaO39naxrz# z-4QgmOIpAh3fm`G->rpKrqF7W!=Tk*c@IOY1uXAj@isQOceuz?c?H(BI9l-y##;Z)8{$e8;~v zLEg##6^bu$cZ}MWpH;uL5q%^w<_(z)#82S}JPMO(8d%@%m_;iUW!3zwPzxzv(HWKsabUokh$&WCd=%A z<+UBVYpw!JiGVeu24dg0_x&eY+9&{pcb!h1pUUMc(ninwb$2!CANrQJEeJ^ zD25;nU7^#8A)jZ5oTf!ky5f=UgXnz{JkgFJ#r}P~+^f|N?P4@kB(jTIg1h%6+S?Dh zZrz(%?E_UEUaQ?!^`aDSP`$|SGpk}(U{G->!lMB@3Xjtbfx$w-E@756lyMB)EnZB? zcQvf`kzGPJkGyeVW=ux^zM|#t!;vA00l`_b3EXEOIh!K3RWvt*9Xr5wwe3~E--FQo zb~~;OFk@I(6=*94=~W+^)s4Da(UXA-DE(OLSPkbW%aFWaw8uF z7mchy0%{UU8v-93&om~FWR{x zfKPK)&RHx0@6;*T0JNgyyJq1p3wg_41nBL2#qLX5OslVG)YMisbahL$8h!j# zvSYB?hfSNTUZc?mqdTZ#%Z&wU`C zy;GWFi1~Cx!QD5UE&$H`Bn&&JuwU0qKsKWM@JFs+a{7rd>7|AyjsXyJ4b=!JX;S@u ztbTvfOCS4qCRzG1>HO1&;Zu~kC4Cqo=|y$`xG8-Yl29il8K#*^WTuiQ`!I|F!sFj& z*#ALd&%epAv13dbe|pOzk+0PbVuT?qM`S(M>`L%!2th27xb#bV*#EK{;?n=PJ61s~ zZU9e#W$dvi6V~bNYKC+9Qn@rL|45d-fc#_7f*|ZJn)=3P@?}1!sSFrw)mH^m_lbo0>9(;AL!2uHZo`U(2w;{x?CV0-Oh8Km0_6Ms*Af-q0Qrv2lNOKl`s4-o$^wSkyf~oCq-b7%p#l z_`;bnSIVca;ZEeHO<%*Ee+@50U&BM;%Oak^bNU&K{rptkzoLHsqKFr220V@MJxWmh zu3LA+Oa^)V;jE2IY8aEDdXy=8+xb+JE!&u$neS%UKcQ#l*E1|?fAHCr;3Gh9jB@sr z?s3kR33bvg5JvZICqC7pr&{zap)JxI@d zj2-5m+v(c@P?VtK_po@XH=^>%5w-5>Dv8BEuO*ZL1)hqG^1hZ)-WhOubX=_;)k3a1 ze3Ja9B)&JF-H@eiF6-2gOFbr^oA2yr-y^luAF#ehVR^l6HLFhbz60-ftLu#YQJ@Hv z)J&6_X;ie&j+t?H!1bn|@JFvpAK{NL@Kgx@oF@ElLbC6+oiYcl!d z10-yDA*TjjU3$O9;K2E_N7*0046^@+FSA2eu54Hh52(B45AkP|&i|=dnF?)o&Fai{ z8|_(>r&=>*7Pj2{e6}{9EjX2YsjyJ0)#fW!!OAW=l`8#`n?-1*(*g47tmsABz*9*h z9Q}2k?XiW9BY$}M`n|8-c=x_}XX)CPmfl+yB!i6GflwiY!&jY}+k{1d2dX|d8J|uC z4wE7rEPvSF=WE#Lx}rp>66&S8Tj^Mx4bxd`)q6bgb0k_hCV+gH66$nR3ALMUmRRtY zwc;u8<5MB{-`lMz{zd<6NX(mA8u9G4Ruf_AJ-gfLNdGUmkBWOdTMm`H?ojfdQKgm} zZWq*GL|eNi|z4!tMgDc^wxkPw=krc_W>sEHdkcPK{Mq=@7Y$}Qlmqf$Jl;F zN#`3qr)fK~)j?zAWj*pJAe@ZY=I&S>B()qdy1Pyr00DqI&?RAvk8O_fJJi>7u|d3F5%!(!Am$b=z#l|a4PvF95~ayOE|TO zOE_?h{v{-2fY^l#Uc!N+>$`+g$u8l*2Kz4I)W}OXmGBadNzL(JW!OI@FPz`Zu&B4H zGOK8VM9>*WeH66CSlzNCj%p}DFNxG0f0$waB~1wWn{Ao`jQaQ{6_%-@wwy#08?sZr zGn4WS9_Ze^jh)&=FNr4fPcrQ9(N6uH427)3-r5i$Ga6$SR6^`csH;Td2e{JD)A;}6 z3>$f?4Rxez+R+!KO8yTbNg zfCy!_IRl2EIlMJOvL)CcZ+2Gv;TI|Ue--K@h-4SMF5>OPKVN6ZF7!Odw0hl^$xZhw zomQ_+m|>Zz-C&~$LM;R5uYu5Oud&mCTp$#G20zqjX3zu)Lxw`Q4ah7yIO;DBo$Z(} zuI`zx-MMj1aD8I~X(MU(38R?on6V4C9f`6Q^LTSn9GQ;ndavq`ilnYk&W0YJ-GgO4104px%Oj1+cb|-r_WSsnM$TfUyTeL8nu*Y;^mAxKc;8u)HUrvlt>R z4+`@9>F2eq8^g+qH2`!Q5>L4^c0Pu$^NToAhPCrC?~-3kkQFpGv{c8TM3-{Co<+}-mBxHv2E5XE`f zPRQ)oz}pHD*$&v9l4;=FRoOJXUPS`$c%~_YJoNs^ZPJM}Yaq3Xl8=)8a{0OJVremJ z8Aq z2|=7l<8LHCt8p@jUqqkPI5E#Jrq1f{QtGS@?^2)D;f<-Y8YkiT0}G$kF$p#QD8qh< zII~~i*)ioI32U>0@*o)f@oK;o<^7N}Y{8xq@n`=a!~PQ*{ol+G4u9=$ zHa5guww%k3!iE^ab8ea)j2I%~%?@YSzA8Z5JA_-hFTd}`t^3P&Z!O&vulkb&j6fPT zsPqIc^J4i0w)@uYTgwQ+$ZO8xwSLKUKnOEpvs=AxyVo`O*7>Z}Id)ini0x|&{K}eU zSE9#@LeqHnv-)rEwmMR>m%7|S#D_?ijH{CumBdqy%^g=*+vdSAwlLMHtxR=H@5q0i zVZTB243hpJ)oq_b)A+{DQ?q~(BM~i2p2~al`X4SeVQIVR{dE-5>01Ff`dV;7WsWcC|l6C4zpqDWJ0F1?ZQDWA{%0AB_lsQSQDOQE7^|aFnS8+u{W8q z;=l-D!57f1^_n*KlYD+EU=tQ^e<4_qEIzW}ai1rj6~yZ58Yf@R&A86Hfp2|Ym6M` z*sNB-e)9bfRm!2KWtAGb?8-8ww`sKxgfO(Ff%0mrR@-ed_ar?AQ$xqoe+n;umqX?x6Hif{#yWx0j+ovQSk=*u{(yWommr%L}8y!#kAzRg=R zx3YYFxf%7`LYCXe^7SP=)U^UDGPRjC9uq5-z*mK9@3>3Z&ibnO{Ujo=2_Cz?aFCsS z?E1P(G!F!B{0cpGe>XG4PsKNpks6Z!O9pOyeam{z$PJz)*&xz-q6z%Bd)SZf!Atia z>|xQgo^hvKS$VE)dEi1dktE^Dm4J~a`U>l@`S(`d#h|yvC(!isntr>E>Ny6ejG(() zP!v2>QoY&T8xwgPayb)-(#F;=XM)xfUC!b3-FM^Uo~k=W-y{7b8u_>OvR{7zWaU?0 zV4Hdu$H+YA0D+J)&zokRFKGgFHuA=VxI{sSo}kCx+nR5Vs;xAg^xpz8)ZkO_RO#O) zM?5C-2cG0R#GCwe?hl+)D`@Kk3m?SHL$sjqB+2x14C;L!58oX+uO^vkkwMMC~V< zMAFlvLc^ZG=}}!J8h_IJtHaTr!2Q*IC7QucXV^~=>HJY1$Q5FLpoQT8&w@dm>9*^} z?JZNw{>BmwFX;hMfqYNkfT*q#jemHwnNPFmW%a{hcP!d$P=|@;vT0^VQ5>np8#l8P zZa&czhEV$$q85~own6Pjw47+*NI>;>=$ihmOrNPOrumSP&v>xqOFOFRBttj8_w5W+ z9P@6=Gd;IqTAfCzI9;u*Oyien|Cff_%+1ear|;dL&My@6#nNJJu8_^1J{YPvd1bp9 zPx5Q*bMV%iS!uOa>ds8nS>p&BGnJlOug(BhWX6I+--hRUGj{-QUu$(5u<+L0l^&eV z;Ou9VHd*_2o2q&FKg|{s*1Wgs)a&6+m$qE>g6jYGGc0KxlD8p_fZ@azGU2QeR4DRs1 zhle?0SH(h#RT$BfT3cgb_~=57i6N<}fs474q%sm%bXsn8W=Z@Rp3xV!+k%=%{wFhR zc{7dia~eCQ_s7zV9@w`sqllnbWPnzJMlR8R!)r8xlEl<*G_dG50TrwE>c>YOL(z(@ zCp1V$t(EYAt|eKZK~1S4HCdvg2fe|}wRSr^fPA6>h?=UupUSYSNvgpq z89<+%jTz(!{WAR}-1Xh+t>Y{O?ab`$E(|#!3)%F zg_q!Zk`WB5tqIFxHsWE8A>QF}B)Wm}B?%G#^7nU*;sypDyF9z>tRpw3+W@*P!a0C{ zCa}|N4n1rE6UsAzr`EMPD^Axlp8x29ah{z5sCdWX1vy@`N#ZgwjH1ACc0?2)2Gd?e zBjWc0JGk2Ny1KM683*}R4wv~HD?(8OEH*Hq6`)iR#G7u{1T3$_j5g7~Nte>(D{XMZ zH{$_&NsY~f{-2PDJ>v_Czm;KYUvf5n5Y4Z?-B{C)p8?xNEs-7M9Z3-R#xt;3*36wnrGV zI2&g=%{6{JUT5d6TFtTHGB#1!m;gXo2dK^uCvak#p35Z(IzQnQtu`{}1;;XUo zz?o`$08j*gn6W#b&1Q`fd(-OJt1h+N?Kr>=M3Pt_pmohg(`mGtuI&*p6;QoGJ7Sz+ zFLS90M-2;tLm3>?d3GZF5%0fS!w@_<=o9P^2bDuD5p|*_48INW!H-E$pI%|d>{h*w zRYk;A)xm#+jH14uKvj-c$VD}R2Xl;FkTs2?Y!_C>2n&Jb!dsvM{{KYr6$x8PtX#pu}q>^h^C11Q3oImMKJO0`8+Fy z%EV5NUuhYagdL)l)`z3SrXvk>I$Do0YT|;ZdT+C0s4rDdT?w-WZVo4GK=rS) zlacB?TP0mV_GYNG+r(Q6j6tljxXY#u z6A32^f@I%hmqHaJv`^Kg{cRyl03xL5HhZ`$4aYcl{l>fRnoI93-MDq{zIpw_TTAcX zxMp5my0?7u#;s+L89Y{j2Tryo&IF&%Jj;bk;AV9orBXkReyae@XZj=IXE?eJYQ-Z( zB{jRqCPUp|724JcKmbj<=XG&_=rHhhvym0+fE0E4W%XJ;x|u#fk!@d!w2gZU@mgFM zrz^*;PGy!|3=O2a3ZAG7QXuKLZDC=>Cdzxi#1=y}=m}Pn^}@3?fsSO^8|JFh>(I%u zWfO0(bD<_km&~Um)>NOCKgh6sH6iMF#&{N`Ff}z z$IBBfuO*=qP1iHqkE)j^Iu2M95O~uf#sie#@&tExo#E3It4aw1gc;vcU&-!h@`9od z7erBgb8*<$%}1+5_&KG=X;j~6X;$j33Ro#o3|rfA9vEL|jP@4<#=^&K|8+nua0UCsS3D61s#b^4 z7`dL(cv!SPk+cb2^oDkn%A9S1?*@B)}UY*9y5m}8ei6~r4$6u27hGa%?`aV1vV9~ zMm#9JFiyLrcu9Q~RbM%FF;t0K4pSHZb)9m$7m4*XW+r+ac7D>}RxlBcN zDO|i&b!*6-f>g$W7pJ32d^}jKHAjsL+!me+fFRRmnS8MnOD~6UogMc}2rdExAl7F} zGNZG^UGr=A(QNs_TR#N;be8_ff9F5FWq?m{y$Kr3gg7Bec`SPYda|StDld^<7&TNN z?1H`%F0=)rNSDlWA7dhg{CsHv49YQF)&3cC$_chc(Ivd$HQ?_G9@lt@z33kc&h{Dx zW1da%>-;?xzae0pWs%J?uO0A9o^euTQf=Jrbdby5TCO=^v<4&LrI@BEi>!}cP z171CY+RzpC9J8RSQmPJIa41!*)t*Y`n={30*jOA_8<) zob56q+D7cOn0`nTaFsOlLY%+GkD|OVdPNEmc1UOdOt--|4AKuLND!=A9T)7e;Gte- z`(-(L^5iAJiI+ciTWu-){q6}iHm$F5iM=LuxZ%q`5oRKHzYkuG1XAclNg0hhD3I3W zI4?5D72*rg$qF7);`iujmA~U!6P`PS=vN1oTq~GGJY|sfMbR_ts4lue9HcFUB;sf> zaP<*11Dq_$o1E2ZI^YILy2A)$OOp^>1MA{aXJr-d3JtKYu>8G*ZOEoa}SL7*qgBx zao53c3vCz*(7vBV1I^Ynh78@oV~2)Ls7|Al|ePU`jCg4UiBePvq!dE zc_=_`!=1}hNH-Ek$&(5-c^mYYabIGq1+VK`ULJ;b*j#L3wKDjKrw0PNRFhz-YF4kV z=M|N{)x7jkw>NBJ5~2rwp3TJetLt(3u2re^;5fwPPq`=~J0zNl{xE8X?vh%}sNB{! z(7qvpmm4rd?rTF=0y|Ep1{7&s^)qOrxmX6SDR^yFoj2L}P)~vfR+p3xr`)a2u|lXI zNH-UfqP(HrEq-TJH;XJAsx42k+Uk!%E%X?XTn+YJj2xAI8em#Au)-wdtn@%tjOXXFMpP^wS<9?!=))~u zrFYreq0zTU>{JJoL~F3}O0WvA0bWI=8)`Zx^r32OQ40}D)Fjg84A~^S0Wo#x_^OIIamA}S*AXJ`o7wD*C+ClOaJxsKr zd_TmhK;<85ghq|4V0xg1l)sR_IQ^?FPjK{7QSDB59WNN^+4ynwA9zjDpp>oQm7^ze z6*_-QlSte)bVahCus^5^(UfWhNil`dK~j*@%osR4Pzj!BgTS+bt0~)|dCF_4)^v)b zZcIB;qtf#>Dy?;H4AIjlvs_%+2I#2^TlTuX8!`QG$+Ev6ziw=gZ?IRSL`P3G-zU=a z21E%VTNT)36MRK*T`+xVSfXmg5f}&Y)V5o~On|o)OrpH7#Iv9fSSQik1$I^n?TWa_ zouyY&tJ*QR5o;`3gA5*1PF+O0f~2v;F&D+5LJJi47f2DP;NprJ^K5o#je%WFvB{wo zNfrX_=9ZivV&nCe0AD=GS5==HP4zLRhU*b4p^jep+j~dZsf6GoRC-IowIXWHg>v~- zUSOyMvG;>pU%GYstGA3r_A)OG9dgTqKBra3b!f-i6=&hSP}ZWOaavVXytLWfXv1g% zJ00oLM6>Ff;Iq%FpE)5Si<9x9_TwXs8TbhDpo5L3-4j)CA48-J$Dc9{L4iqD9A9bE zK|)g~xQR%s1vQ}P3e_bmc;q!8$;7u)KyV6GpcF*7VvSz62V%p!lr-|3)Cx8%8{UbW z*X}h;%v_z;nGnsBwj!}6dI|YMB@*^3Qgs~pk0K3{ZzHTw;&&oL{^CGg!>yv#hw8DC z{llmzMyA&hgkZo}Pa%I1p9Q$vNHd4oi`_L0N4J6w`44>)M)Ukbe;e3U(mu4B;dTx@ zvbr`@r=sn>A91DW0~{(tedy~05|jGY-_0?0P#g)xpo@+896K8NS*fd#hbTrnLkFCz zb9o)F42;!rcn85uIs>M1LaKr%NRd4uOsx}E$C;41aVMbp6tBly@|67m%PV7Ifawq# zH?VZzJH+2j*|IQ!h&QzS{bOtko<#<5=x6QjII#g@m}{$Cs;Vhv}5U^&w{m<#BLJB z@YHLGBr2oglq-#qW|d7akWd!{r8sDsL&T7(Nh6Qi^otRpNFSMceXU`Vs?;wTrmQaX zy$!NOR$E< zG|Q??Y9Y#jH%gY3cM?MsKZH0M(eO)bzxd`~Vbxb;2nIXAOVaUEw;eVM{u_8VVOP;4 z3x_uJ-YXeLGWIwbN(hyQ7TkAig=UM|RM-3pTL_nGL2Q&%f{z3OftZh;t2Q@^%K;O6 zs0CSB9)5Me)lNWFKB%;EL<{mPq6-kNP$kJsK#f3W3bd2^0mylmSw2$uAvPYTs16@F zyb<7!tK5U|N!@C=)!I?zU?yh5S^6`Yn zlv)S1?olHOU7g^?Tjf~~wU3ipzRT=Fs5`3WwH@27fp&4;ny#nnWRWDzfLsiQz=i&g z-vf97tU+}w`$4gKPlyU)$tT!J&MHu@N$AnQLsU&Lx8#ANiQ>^A>w-%eJlD8aSpJG- zKZF~KI_$VA_>tS-)lcC5K(*pmw-Kscsa~gc zx9?2cx_y7*L;P@W`91{0{p<4F;DHgdD#LSo2fWwGk`;P2y@$vu+U>3hb{nUYyVHv$ zDgVw9wk5Z7m_#Ql8(oLXuvi+hiU_u?4eg8cBl3()&cN-Vw}kt7%GIZx;=KRI?YcUV z#FGduC7lbdVHGbFISIgN)Hhgw0EgyB{>q$}m#hislx7ZT3xkYgF>37K!@@n(1-iLq8`-7Mb9QT z5b_d=4HYvLLa%a+5u9CA&px28CRUf&h0qRw%}@_lP~k6}v7#Dra)nWo;giF$=Svk* zVqc87?8*Df3vzO+rNsi93JnH)T%=YtqOKYehTgEtL!NMS)3t;x@TV2}xBydfG7u)ObQ@nWOKG|In)5ag%~?EAI|1cA?IdyZ?#^HW4F<*^0N= zDbC;Xs?mi%K!Qrw`55ZeT#h{Hh=+CkgIWIN=aVV^iNn=FXnl%*m}){q8aZl_Lk%ql7uRgbXa%PxR~+wfs5a3x3N}$TQ?mUin={Q*t^5L`+%aKWtKc1R z_~2^Xa2~Zf55Zw}!KhbycrjE>ZdDD`jb^U zz2?&pyUYD1-Xj6yYhRPIF8|mbHkRl`hz%1$v;&)??uER0!jBd!z4xP;c4cPu0ZerL zg{8ZkF1(Kyw(SQ-G}4DtCY)H$#(IP1BK8K(KiGC|7nALfr#98#I|N=j1%_t?{MO^ADMAfZvr7{tf2qz#ek#xgq@ z`AG;uc%clW^NVSZ7cYwkL=WtJc6LxR@Q-ke=@Cs)p};($f#l8UNAfgeYg`7nx{Gc& zv$tpY?%msWVO}|=zV#|#-lWRdNjj-MhA1wA z(xP%edqWTp(xj_{Bjj*-w@LZSW7tGf^14B1zN08Ck768ut*`ox}ab$PWsS=Y%R*w$|cdGmJ~fCIOHRN6H?LHB4rTYam56} z+s2jsz|A2vAmTA(VSOXjs=v<8$xp%F5n6+2QgS_!+kFglBh;O->&}OT^1JK+8t=fT zv_=vfjGMV>`HwQU9EQ9GXTo8j!a&GX8-Mth0ZU{Y2?os&xX?3LGEK>*Md<2#t8hH5!EkHgOc9nQwX6=AQY)ZOCf}S z62?8-QwX7fgh_~Q;xSoDA%rBloLCjuAyWvU8L<|`*QXFdKnP4BgdkJopC*LRAEXdM zq@RO2Lh3+$M~5AT5XuE1gf0L=s9y~bMnrm+u!H_M#SZ!uV+Xw~u!BMpZ3-QvvC>lL zAh;tb;5Z6pfI%RI4oabexL=9X>qTQExn56!1wwfnaJf&RgHq@q0%J&_gG8VyxkskZ zLB8u>3LP{Av45}%{1XBl^qswq6u>!IVwqqQe!GkBICGMfL)A~g@?8_0m{}njEsl{g~vh2!^O4`1;i1k>>j`? z$;pt9bI+~iufTCK>gZB)C}IWE0-GiKRpuyZ_Kcd^J5HBEviU^AteM3l)c6+)WAjbz zVMjh0=c>9xV0IVA$%rFg)QL?%OK|WNxcljK6o$vBF_S}LdW6r%M~S%mDq`AUmJ`LN z*g?1>Av}m8#j!ZXsgHbM+zF|aFHd}wd+>mKjYDN&@`Q^rd<)=p^U(JcflC3x!sCs2E(unq!^cR|LH%n-7C;ce;LZ^s;K)l68GLx* z6P5yer2t>T`ZF{v9+o0|Jpcm1wvoL!=b9pWJq}=b zrpR6?vKQi-Q)DlIeY9kvmlWAcL_?&=UJ=x}0q9&||7Yn+k|KKvPZEJ5Au>BFj9VUS zlOlVi$X+(`698Z;MfRe^Yo2z>N|C*g@gha`N|C)%WUn=X!SQA|LedN%x?~7BM`)V4 zLuh~323Yv|!MajpuN2vfgK($FUOXG7PKlQydvORb4!Ib_)>6J$pABTM-~V=I-!7vV zMfRHJjsw#?(-Wnq&CShZr|;dLE>sq4#ay+Nt5!-;^sjk)!O2%@3)SLW)n2p~Y-=t% zU#%_F78eWES}6~#uZ3E1-m1;za(1q;m@C;uYr(QB^H$C&T6T*5H4tPc91e6%#;AlI z!DkHpD+Sz20k;TdQDKSwXog)Gjs_=zq*B1G&m~$Xg4&u%0k_-~aBG0Hlmc!EtlboF zi(t>6D&W@lQoyaJ1h`cS0&cwpz%35csN$3_&CV)+VXrK5!O7gNZ;2!d_A13xQ-ThW z`c{DN8~dmIz~u6SQ3(+=^LlR;$u&bvtM<(X9=1nc1DN!}q*P8(w-7Ln0OgKD8S}a> z^2l{{HaobVib(F@j*yG402fDyIKCs5B(ef1NB{&;hd-(`*Qx;0#)_zRAf6*1l^;xg z3V;Etj*Y~_$Prv|fvm1$=@BHZlC$s(5-Mn4$}XD^iG129e7X{0AgarGT(Ut3>xX zp+_vC`bNQnD|KWKtpkmWig}a=>Vfff#wc44@K#*QGwy!GGe_{|C{M=QSGZ^{I-H&5 zzn3KhUb`#X9$1h*JfH|9-l$B2>@?Rn9tkpR@Spo12h=i7vVG!f-wUC#o9PU?NHb(y zWUnHv0?(|X0x|$@Lus~wsiM+M>`GC${FFn)9HgjQDeBg+)Lfc-r#SWa#1o$o)U8MC zo#C1_4n{n4)q3mCtld06 z&V_qCOVN@|Nz9g;Yf`TYAJ$hwxnyL*q5z$hgZSkPOYwYCJfGV)t{cG4S$-u2G8TL)i#xEiG6f zV`%`>2pO@hj@AyQcs?nfk43;vWtKyFc@F7GD5oCs7ZMUI&(95W_PTng>1o6N`2((= zbO0d@uUqMP8-P>g$v*Y_g+$9T*CajFyj{wgXs$Q_Go>W8GH|89CY#_Zg3l|5VFhri z)1_*}5f}&Y)B+dQ<%xtJKtFLrzPi|7Dx@J*FR-%$OjIYB<;+9X1V@hyuo|xPmB1>f zH#s@fdvIoV`pzeNs># zx2;Z9fu*26DX5Rb{V%0j3KFMr_y=J^Ug=q#>f3|__Dxd4g;d#9*OTd^oE6L75GXjB z`{!V$TAc>HR;aFg^FH?4j_uYqq+aWFb~;q5=8`rK7A9)d*lSg*^iSh0_G+k@+aPnB zD9KHWTx-hV%le8o8&0Fu!C-m28f-?mFXSXY_1AJfj!Bp&A3hLwVR2K5ar=UJ5s1KYEEHaFwpguZJ^vC&D zB?a}V^j1<(AM$X<^{Buro1Y1*{>a+!C@{yYY~X3BSxC*PUKb?K45=2#sjnRfjWRu} z=J=T`kFf(T)cs(I>hO}%%-T72jDA)=Rkj1>s%bSGX;*++SA2%~l`Nqc#2O-gMWLubJ^0|qUGeX3&mWD>yzU8!0%z3!58^o&#(u>843}dKa+^X2C zB@zA*+AIZdkpEVOrMNzh1@)WrE<#P!@oBO|N6&7zXRfu|p`|tQNe->7srvh=47-}7 z8vH}Q(Q`T*Gw(UgFVkPbUEke)8y8f|YG^;7VdW&vrno*Su1~9}3CrVAQH?RgJA9ZE z-9Y&$g@}Lo`zfvu1P+QY<5niV(o!S-fW4%`;LHXq-T1(BI&X8FkZ&3bL0q3pLvejV-24Mr-A-#g!qY|e z`TlXXIGo_=*khYJfFt_2<4AI89APXF)N>*qf+qOn6KTKkEq3>l(ZB*=*J*u{W)bz4~cJ_Bkq$eZs<|0WW81GnUvy zFxxJDaQ`-87CDF~>e$=~7Ya{=Yv@1;IJ!8r#899%S0+$uLM`z`FnjuB#5yg{2L*gk zxCh^!&$Cj(03H`%371sTCpb!mUe*#OFOy3HP(6QD&ucm2k@@0v^R zE#0_v@4k8c!&^)5-?(O8UAnh?^Tw@ZV}hNEYfYR9KAri9BSs4CgN2nr<-%ETi7kfK zknn5NQ%UiMroTm|4D(ubdL24BwvMqn7i!{B$L(@IO;J^!mOsd_eHu;XyP1zTPTmZ# zZXQ2|YSF521U$!Fx4T4f1ndsQSkw8rJkjzf64D_@7rZC!N7c&{9f!cq5K~~mb%1tV zf$-QCrpbrEk#vBCMo7WxtAj@(h4#Uc>CH%?eaLi3FO1V}DP9tPHr*OdqB0rg*u{{^ zFopIJ?}%ETSJ_EPA?VfUfJ4(SwkmR#y$t%!u_YS(&4=mqF(4%h`T5cU7?fkUs&I0X zc366&C<2;u6<})=T>@-G4Rk=7QD0&&f-x|Ac&1dSslk|M*JY@YEOvjo;=++@$yHV1G@aXC)gK;3x7gy zA)}&ahACH#OYAlIeL_fzl8KxMGm*RB2d_p^+pnp=(wxa0$T3 zBYuy#4*5H-HD?v!k2mgL>OXc1Sc;rU+~jU64Eh z@Uez>*f&IgX$+`A@{xm;Sa$><6e!ZV>L;qgPz%DvvIruVs`Dm0AL>cGs|tUMy!Rz_ z`y4BT3Q|}CdCR#?a6&x}dBybtdbc?CgX(6HWka>WHi662=o=pc2#hUHFMaew6z64~&We zut&r4Kw1>P^kL>aQ{XtEEsDkHk3;j0f8hc7vPjDg^}izO(;$Q1WZ-cRzuMol0>MQwDG7S7b7x} zJ~H+CTEna(d5&LlBGj0x;-0ImuChxD<}+&T&br64Hj0G&($K3s)`0~>0Z zB!HSemv6AJ*-XDx65hlgU|78KEZj7CVUbS{>l=%kf<2I5|%PEoZPmD_twABh>< zs#$@E+U1g=NcI3Jx)~IQKNo>KCO$m4dD1O_baX=5&$B40bs=AabpQw|)LW{}_XXPm zM;H;Ya#9ZXd2&*+!vWyVr0REgTE6In7Xb#g5 z(J%l@MB#P9!Q>-SeMN>~umij#9Y0kRCJX)>0cz3|af@UlIJB`Mj-jx^6Tlik;blK4R__TAP_e5M>?CIukV1{rcHkkZ6pV>CSIq!1k@D<4T5VzG z(n(8pjY}Ck*SJ^pE|Tfk58;KPj`U`*eZaK&T%`)-GC0$gLi?o9J}I=%nlq&3uv?P3HvUJMIf0lFY%w9xiG zNoxu$%=twpo8KE7d6l?73ioe}>chzqMroVzj&|wT2mI#cRl69GJmmf51^KPodwu!cr4Mf2 zHwtVjG?*0H2ONv0dwjv9vj&!lES-w(!RsKzLg_lnI6>wy#S*2^J}I=1rXlpus#AnG zis0MI&l{f6E`ZDBRenW;nutqYx8Tfet!R1y{nlIT6ld=x5fBfeQbZnrk*(ErK8B7q zmowl;M`D5NAI$PEKR+t*w6Ho5PRYy{^SANGwN?Y>aC#=ArvxY3HDYOr{w9jyAkV5;U&^~3N@Nl6ZC5?hGf&!AC53LM5 z&0do43IAP)P7x4B z1_n&F%0|KiG|MN|U6>nIJ*a9$(xK4U z+8cRkr-G;r-JfuCcdBws2z!haFHk6q0yYx^hcj5DkVfnwJtMl1twnubLf@f`}+i^(y*ma?+grL;xwtL{; HGr9jCzeppc delta 14421 zcmeHO33OCdn(qIR^;S~ZDtkf-61E}hIb*g;mo0E*C!65f0D3W6aOlAwTXD~EQ+ z7P#u8rNyA5woA)Wj!{&wX^yx9GM+x#uI6t#G=U^)D zy}JMX|NGtl|Gxje+;TtJxGpoBJn13-RgeMs9~O`*s=JHn4tEC4nYkcc78*o;@Olbn z4g7?zD_cUXS%T*rl3in(O`YLzi@8j1Zp|IwtEERqh;RYT+ggz=PH11%Vs$j>ZEY1@vjF>dV*Z#@SVL@4+%x@8>6`RMSQ0We=J`+%+rozE=1?Bey9&m`$&oRCvnB zU1`%iV@P(xYBLF$7hWRb4RjKK3#>pD$+01J&_` zSWv&Vxh;Rv;0XcA6#0-Un?@j{@={0f{ia_rq@bY$O~bGh1+8h4pO-~B zBx$^&2K^zW1jtDbdBlSYy~7h*=$rRt(1CJex+FCS;^65tcS1$Z&U^mZIvn$Reg*B^Jv@|WXTCH}yGu+c%K zaRebhKwQoPm$f%{I^V5!47EJZYVvEq+vMF z4IFlCZ$NJ@uA;N1&8EW+X|$_2kUNrOI>B2O?qGfvJELwJduWm=YLaBhhQOPGYz0hJ z7Sw#7h^bi*%NV!-lSIMl9jCD3P@?ys6l{`m}d z0`FHPArw+1-a_;mCa)pB#h@g}ennS8vMF0ez|u866i^M^3A|>aK|@f2!B9ZfOE~hF zhy0l(m_HSe3cCFd74)(3bJIn&LGb^8x&B~oY65er6V~xF${oDznzDcsRXTUOM8{5j z^^A~<%$i1_|B#B?ugLxiOeYOTn~TVEg@~gAg{0Ei4qg59BeZ$*qZQ{iaT9MO%yBY2m(>d*=W;uy)kx64n{gPkK@0 zP~Ads4N2gk$lf&&3L?`+QQ%ZReS=?;HurMaV%rK#agt=YCa56jvW)cbOE zq*#0(CP}Ii^qVFx`E@@Z(0N4?{6Qfo7(rRVeRYC3gRv*Ama;KV_(^>R0c0+J9kM9mCZ{(u>ju_PLjEGd4=(D0`rDzc>Osu5JR zfEBc`fGGjPz&xgFA-^b_B?HLMOUM(&h=WIqiIWyL4Lv{IFEj|scM1VmOn1(%$R2ab zf|b+14=9I5y6<4|DNJNyO6}Rh1A=sHYE}05uNXazZb&Wp#;}OwrmqEh=cO+C?#42D z;L_vto+m5l2bsI`lv9u}2$4`iXZADoqWz(+(u@cDwE}?4RqJ|i`31X=Tg#vyvpo@lKTD~$i6V4YOH4_qs zIkBAKV?lj$o6c&EXi33DNgE+wi4{%7e9J`g?@Le@|v&9AFc z$P|r$Zj_{ufAx^9jO*OyAyMq@aHrCpo>aOrXMVb(v3&6Z-}&}@ht@Z^oGp!EjqLOc z1WwT+hYJg#bY3rlGqE?CcNaejlaxSElz0S>sah&;B9#bfmM#WDqNIo+TvNPlngL70 zWtDV%M&`AEqG0l|@Sm*t#>B1SVtU=aJ{C3?%gLfFTMNi5`3Rqv@`=~6c(buQL)5ee zN%&5a4DENF`NoOD5k(F4Luu}vrF3HRZr7qj87bYoybOex|Cy1o%Ll*!3<8~eiJCXz zlq@pRsV9vQ57v{k$lgmbxc=9YglRfD(>6CKF_?aGSj1SPEIbf`2Hnu)4X6j|<%shcl>e;XK^I zBBKdEWd3iT`M;!ePaLjxRLAhe3o$u}bjnK#eSGoj^olX=KCPV-x)fPFZ5^r&)P_n> zQiGBxW1~b6v94RJj}Z!JqKLv)K?Wh1Vn|a&yrCEYN#RwKH+f_cR>1H@r7PNX`}*>w z6S~@%1ikvIi)?Tqe6DqoD4V5&H($W<0h)JjHB7fZDupr_Zm+uh^ocFa zdWTp+SH4rhiIw(=e5gb=xqCxBm-RkA8wKh#SW0)nnPmuF4QMoCCdF@j0$6_kDGYl0=So0=b8+UKfyf zHEoZt-oZlh18-~22uspar=O6u%HHnh;UuBy#x=-b2G z{G9lWSyANaZKHsGu-?TwE0K~e6=E%w%4w$%pS}(6?N?tzy?d)8v+gPe7)zHNDh999 zoVoq(H~ZgbsbWJhZ7rfg!$ul*e9~Bh7#pkjYodfEK|g&d0Wd=F`L3CC!sTu{XMbuO zE*p!;LDrMmUr2g)6xYUj%KvZRvU86JE+LVe21iNrzKn?bNg1&FOT(j;uZK>=yLT*L zZ=AsSM8ChZ_>T+9Whj~zu>d`ekPnMnf5J}e~n zF!Xd4l0L$Y4*zK=rqaJ_1oiU>DrpIaKE3Tex@7%L^urfi_8+pKGE)3=fyrumxKKMY zaw6NWeimrcq0$7O?z;Am{g>L6&NT3dlb;8XpysUo(*09ZxZgapoN`<81yrN62Y3`S)FtP^cHtLv<7B@jW-t zD_;n^e2H{Z9_{zKU-UD9?r`ukLxy6Vig;fh-#6KuIGjmuKlJ9r{u1=)bg28q3{H%u zkrRi9#}XRaxG;94nFOAC%tf{_s{TtCiK@?LzR7E36$GI zM?qzQMzZvdHp}d6TGrg^oPrEu!h!C3cQbvNy6Bugp3K^Ts$p5M-4Sav@0iGR!lw6R z6b_r-8xr~Oy(!>Yod^}e?3gfMg(%w}%>_B~;J-};D8*s0O~r0Wm^_^aknwMN&(Hay z&oM24gV7J)Ls{U=V4*XiB(eKvfIPu+>7zgrnuBJ)-5jTEzjBeI1Y`IzA&yuHqZ0Xg zWgE%)EC_a45$ttI3IA*C$`YutGm9Y!JH;7ncw-W1MV|;D2@gFdh@lrh z({XR1;H`5ky?r6J3NC-+NdGr@>_CUvJh5+$^Y}CqE(B2wwb(vq`%;uZ#RzTPGZlaXKc1L@G$E+?N&rizx0 zbpv3JOH9PJdh>=t`{ERMtN%GDK9oCI>E+rivX>$0aTiuc)M2fhCY?oc>3y8ijmIeh z=Q=mx?-)k@#@NI2;P?IaI64^Ti}GE^?If_tQvl<)pD%%>@zp=>B3&#dTV14w+S_YO z5d^$&Ho-ad&6MuRuC-06EC+VjP_XdN6*YE0z47@r_qf*h@>uDEyP4F$Ld#i!zSky%+~8XO&bw zrB{QD8rPc2@|}?VpT>_2AqPpx5~&dRUMBj0UqfF~DMT1hNnw@iPg>?`nHk7~CA53t@1o?Sl&- z7vHmGgs{SZYA4*qyv0!dj<u-CV{x6A;UJW(dH35(G;*X_sKIb_;>7_Wv#aStiXIJ~hX^1eChxVZH zJr`$Ab#@_dw=M!R9%gpYanW`)C9d{4i|cX0=7O*&_QkBDspN)KT#2hwNe@C?w)Y~K zF~A?oMB{p8qB{GkHmK`<_9FNNfb&Z|>slls{q)|NOa$9IgRnY2&3{mWn}o1nQQ5)D z2cD}&^QC=_)w9A+0@=mxJ_Mv!wzQ{*AQ%rF621G_BX;ubta@uEUWOo_@=QnAjCoS1mE`iyg#L_)yz!ul&#Ad5yBYEvLCXRX3 zz%<`;AvYP@X$z2>n4{MLsj^>dft7I|PYsfj9}~x#ec}_JVYdBAI1wc3i)1m_-xM9N zA}#;(jhHa(eY3b3{qEOwx21BgXLjFqIot#G!G+u};cwk}&%pJ7FT>;&a0MwTo$aga z5e3}n?s1E_9VzZlfMkR$y>nH&)scV9_LgwZ4y^TdT-F@wtY6h(H7#uk8+r>nILE)X zX)<+lS@+79;CM>+;Y#jgcK5G4xRIqPFQ$<3_I4X;y1i4leE>sjAp*tj?B+Sk!mXB9 zP`q>6!}jb5l&1(hTA&xD;CvVwk+IY)kQ7V z;kD)!&1>~e{KJ`xF<)1)M}5|6%f!FA`P%0{+hS)w4nz9=#|12`FG2VCC*TNyzkWHQ z-5Am1-!_=LNB!Ro;HMkyV=3H>@%_}+-QiTOI4kLqi^6dDug?cGoTxK$pHgq;A$!5z6 z{s|&=ZeGNC5YG`W9tG(^(2E!G(yMsr#k=XQP>M%S@A1B0zI@)}J%0^e?1B;a3BV5^ z-&cAMpy4=Tf3UuDbv-xXI6H5Z!a)(fDdvH^TZHAVSlapZpkgkm^@;(<=G`#x{PhN9 zTP&a~aD5gR2eiq|`3TH_o8mDjjZ_^cN;r!f@wV@^&Wl$dnJGbt`8Mvv+z&R3g(*;# zT2aC_PHX|8^>qqQ0hF@P!?4*b>~6j+bsK)zoX#fZpdx9C90_iG_yNh5SQ}>adzPAGD1{WF~u%35haF(T!K_u*9?Mf&$CQs zBWf9jK`qZ@Zk=ch5xu5s2GZ5KZKG+#Ocy?7O)7n7+p@9%}(`* z?37eJLL1BV1e7}h8_D&yR=Snvm2=rik7ZM`-e`uDRsX$ic~!nvaj@<&!=p7D+eEW0 zPql0v=@e^>m`rz7m1JU#S-6H&Rl^#h)O9uDsYKTiG0+r{zdsZ5(4GHIN?#65os@n| zKwIn&Er@~P(e(HDZ7@9zi|z(uG@vAiel zm-kXjkuOLeC3r=gsm+U7c{qKt`VL$w!!bY1-pg+$9Jj(Kd&jo#GFb`|&SeFTA6MHf Uiv2L?$!Yu6T0dA3U+%5^0h-C_XaE2J delta 1065 zcmbtTO-vI(6z-H3=m4cI1)9<#DHzQPwB4WXwwM5d2x*8!F&qqOW_M@Xm2G#ky9H`A zoQxL_*1dT$diJ2J@va9wc+q(Fsxgs+F(!IYwBwP^{Y=+vY{$z3ytE#r98LE_%gkqtrNx0;>3p|NM*gvLYqk&XaTrjs3*%CF~ z3bm0Z?0P(GJD?mJf)J@&sAj54Wg`@fcu2pDRMSnNd+aH1ZRa|GK9{sX7CS(;s!7_i zOQxE$s)EcG(R0G(xeHZY*9?n_A9#CaTSx9Mq*YwjRb*jm=s@@^u3*E3rTMBe)i&Vm z{@{u*4Y47jVcDqtq~nN}$~2FkI{Lg#lm)B{9Jf>L?{*NEVkA1va=e_91WM%OG?z)C zED{)2;?f+Zk;n+N%x7qdlZ6x`ODy6=L}x@^<{3;Lu9y6)-g3D{GD-W5KjCU5z`n#V zXqMVb?n?|_BoDQ-Mf49l$<}rMUDxmuaXK+WVOq*!k>hwq$YyyOxm!w1yUxfsMR9_= zFyio;im3>Ss#rC`XBk!J#^6U^@C$&QGDcR_z$WqD-if^&9v^A8 z^JLY;g`%nnNZoI95s4*dA>KFcd*y@E_QT|uohQ1Sn@f)YIA+i02ZKGzN=d8Wk#uHc z#n9~a{E#orPiCB}`8B`yIk4ZZELUn#s=*8l(j diff --git a/rules/setup_sourcekit_bsp.sh.tpl b/rules/setup_sourcekit_bsp.sh.tpl index 17816682..3342c959 100644 --- a/rules/setup_sourcekit_bsp.sh.tpl +++ b/rules/setup_sourcekit_bsp.sh.tpl @@ -75,7 +75,7 @@ PlatformDepsInfo = provider( def _sanitize_label(label): label_str = str(label) label_str = _strip_leading_chars(label_str, "/@") - sanitized = label_str.replace("/", "_").replace(":", "_").replace("-", "_").replace(".", "_") + sanitized = label_str.replace("/", "_").replace(":", "_").replace("-", "_").replace(".", "_").replace("+", "_") return ASPECT_OUTPUT_GROUP_PREFIX + sanitized def _collect_dep_outputs(dep, transitive_outputs, transitive_output_groups): @@ -237,7 +237,7 @@ else bsp_output_base="${output_base}/sourcekit-bazel-bsp" fi output_path="${bsp_output_base}/${output_path_difference}" -external_root="${bsp_output_base}/${exec_root_difference}/external" +external_root="${bsp_output_base}/external" exec_root="${bsp_output_base}/${exec_root_difference}" # Clean up the old output base if it exists (from before we nested it in the main one)