From 2439236b1521d7057f67c776dbe79b29fe140a08 Mon Sep 17 00:00:00 2001 From: Jared Henderson Date: Tue, 8 Oct 2024 15:53:09 -0400 Subject: [PATCH] iosapp: gif blocking --- iosapp/.gitignore | 6 + iosapp/controller/FilterControlProvider.swift | 25 + iosapp/controller/Info.plist | 13 + iosapp/controller/controller.entitlements | 14 + iosapp/filter/FilterDataProvider.swift | 45 ++ iosapp/filter/Info.plist | 13 + iosapp/filter/filter.entitlements | 14 + iosapp/ios-poc.xcodeproj/project.pbxproj | 720 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/swiftpm/Package.resolved | 123 +++ .../xcshareddata/xcschemes/filter.xcscheme | 97 +++ .../xcshareddata/xcschemes/ios-poc.xcscheme | 85 +++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 14 + .../AppIcon.appiconset/icon-large.png | Bin 0 -> 97425 bytes iosapp/ios-poc/Assets.xcassets/Contents.json | 6 + .../GertrudeIcon.imageset/Contents.json | 23 + .../GertrudeIcon.imageset/gertrude-icon1x.png | Bin 0 -> 5886 bytes .../GertrudeIcon.imageset/gertrude-icon2x.png | Bin 0 -> 11093 bytes .../GertrudeIcon.imageset/gertrude-icon3x.png | Bin 0 -> 15532 bytes iosapp/ios-poc/Info.plist | 13 + .../Preview Assets.xcassets/Contents.json | 6 + iosapp/ios-poc/Previews.swift | 7 + iosapp/ios-poc/ios-poc.entitlements | 16 + iosapp/ios-poc/ios_pocApp.swift | 23 + iosapp/lib-ios/Package.resolved | 123 +++ iosapp/lib-ios/Package.swift | 38 + iosapp/lib-ios/Sources/App/App+Install.swift | 130 ++++ iosapp/lib-ios/Sources/App/App.swift | 116 +++ iosapp/lib-ios/Sources/App/AuthFailed.swift | 64 ++ iosapp/lib-ios/Sources/App/ContentView.swift | 161 ++++ .../lib-ios/Sources/App/LoadingScreen.swift | 26 + iosapp/lib-ios/Sources/Filter/Filter.swift | 24 + iosapp/lib-ios/Tests/AppTests/AppTests.swift | 8 + .../Tests/FilterTests/FilterTests.swift | 23 + justfile | 5 + 37 files changed, 2007 insertions(+) create mode 100644 iosapp/.gitignore create mode 100644 iosapp/controller/FilterControlProvider.swift create mode 100644 iosapp/controller/Info.plist create mode 100644 iosapp/controller/controller.entitlements create mode 100644 iosapp/filter/FilterDataProvider.swift create mode 100644 iosapp/filter/Info.plist create mode 100644 iosapp/filter/filter.entitlements create mode 100644 iosapp/ios-poc.xcodeproj/project.pbxproj create mode 100644 iosapp/ios-poc.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved create mode 100644 iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/filter.xcscheme create mode 100644 iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/ios-poc.xcscheme create mode 100644 iosapp/ios-poc/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 iosapp/ios-poc/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 iosapp/ios-poc/Assets.xcassets/AppIcon.appiconset/icon-large.png create mode 100644 iosapp/ios-poc/Assets.xcassets/Contents.json create mode 100644 iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/Contents.json create mode 100644 iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/gertrude-icon1x.png create mode 100644 iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/gertrude-icon2x.png create mode 100644 iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/gertrude-icon3x.png create mode 100644 iosapp/ios-poc/Info.plist create mode 100644 iosapp/ios-poc/Preview Content/Preview Assets.xcassets/Contents.json create mode 100644 iosapp/ios-poc/Previews.swift create mode 100644 iosapp/ios-poc/ios-poc.entitlements create mode 100644 iosapp/ios-poc/ios_pocApp.swift create mode 100644 iosapp/lib-ios/Package.resolved create mode 100644 iosapp/lib-ios/Package.swift create mode 100644 iosapp/lib-ios/Sources/App/App+Install.swift create mode 100644 iosapp/lib-ios/Sources/App/App.swift create mode 100644 iosapp/lib-ios/Sources/App/AuthFailed.swift create mode 100644 iosapp/lib-ios/Sources/App/ContentView.swift create mode 100644 iosapp/lib-ios/Sources/App/LoadingScreen.swift create mode 100644 iosapp/lib-ios/Sources/Filter/Filter.swift create mode 100644 iosapp/lib-ios/Tests/AppTests/AppTests.swift create mode 100644 iosapp/lib-ios/Tests/FilterTests/FilterTests.swift diff --git a/iosapp/.gitignore b/iosapp/.gitignore new file mode 100644 index 00000000..417b4dc6 --- /dev/null +++ b/iosapp/.gitignore @@ -0,0 +1,6 @@ +lib-ios/.build +/Packages +xcuserdata/ +DerivedData/ +**/.swiftpm +*.pbxuser diff --git a/iosapp/controller/FilterControlProvider.swift b/iosapp/controller/FilterControlProvider.swift new file mode 100644 index 00000000..95aea787 --- /dev/null +++ b/iosapp/controller/FilterControlProvider.swift @@ -0,0 +1,25 @@ +import NetworkExtension +import os.log + +class FilterControlProvider: NEFilterControlProvider { + + override func startFilter(completionHandler: @escaping (Error?) -> Void) { + os_log("[G•] start filter (control)") + completionHandler(nil) + } + + override func stopFilter( + with reason: NEProviderStopReason, + completionHandler: @escaping () -> Void + ) { + os_log("[G•] stop filter (control) reason: %{public}s", String(describing: reason)) + completionHandler() + } + + override func handleNewFlow( + _ flow: NEFilterFlow, + completionHandler: @escaping (NEFilterControlVerdict) -> Void + ) { + completionHandler(.allow(withUpdateRules: false)) + } +} diff --git a/iosapp/controller/Info.plist b/iosapp/controller/Info.plist new file mode 100644 index 00000000..60ac92b2 --- /dev/null +++ b/iosapp/controller/Info.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.networkextension.filter-control + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).FilterControlProvider + + + diff --git a/iosapp/controller/controller.entitlements b/iosapp/controller/controller.entitlements new file mode 100644 index 00000000..cbc0897a --- /dev/null +++ b/iosapp/controller/controller.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.developer.networking.networkextension + + content-filter-provider + + com.apple.security.application-groups + + group.com.gertrude-skunk.ios-poc + + + diff --git a/iosapp/filter/FilterDataProvider.swift b/iosapp/filter/FilterDataProvider.swift new file mode 100644 index 00000000..658bc450 --- /dev/null +++ b/iosapp/filter/FilterDataProvider.swift @@ -0,0 +1,45 @@ +import Filter +import NetworkExtension +import os.log + +class FilterDataProvider: NEFilterDataProvider { + override func startFilter(completionHandler: @escaping (Error?) -> Void) { + os_log("[G•] start filter (data)") + completionHandler(nil) + } + + override func stopFilter( + with reason: NEProviderStopReason, + completionHandler: @escaping () -> Void + ) { + os_log("[G•] stop filter (data) reason: %{public}s", String(describing: reason)) + completionHandler() + } + + override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict { + var hostname: String? + var url: String? + let sourceId: String? = flow.sourceAppIdentifier + if let browserFlow = flow as? NEFilterBrowserFlow { + url = browserFlow.url?.absoluteString + os_log("[G•] handle new BROWSER flow (data) : %{public}s", String(describing: browserFlow)) + } else if let socketFlow = flow as? NEFilterSocketFlow { + hostname = socketFlow.remoteHostname + os_log("[G•] handle new SOCKET flow (data) : %{public}s", String(describing: socketFlow)) + } else { + os_log( + "[G•] flow is NEITHER subclass (unreachable?) id: %{public}s", + String(describing: flow.identifier) + ) + } + let shouldAllow = decideFlow(hostname: hostname, url: url, sourceId: sourceId) + os_log( + "[G•] decision: %{public}s, hostname: %{public}s, url: %{public}s, sourceId: %{public}s", + shouldAllow ? "ALLOW" : "DROP", + hostname ?? "(nil)", + url ?? "(nil)", + sourceId ?? "(nil)" + ) + return shouldAllow ? .allow() : .drop() + } +} diff --git a/iosapp/filter/Info.plist b/iosapp/filter/Info.plist new file mode 100644 index 00000000..d4c9f8de --- /dev/null +++ b/iosapp/filter/Info.plist @@ -0,0 +1,13 @@ + + + + + NSExtension + + NSExtensionPointIdentifier + com.apple.networkextension.filter-data + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).FilterDataProvider + + + diff --git a/iosapp/filter/filter.entitlements b/iosapp/filter/filter.entitlements new file mode 100644 index 00000000..cbc0897a --- /dev/null +++ b/iosapp/filter/filter.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.developer.networking.networkextension + + content-filter-provider + + com.apple.security.application-groups + + group.com.gertrude-skunk.ios-poc + + + diff --git a/iosapp/ios-poc.xcodeproj/project.pbxproj b/iosapp/ios-poc.xcodeproj/project.pbxproj new file mode 100644 index 00000000..0bb15f0c --- /dev/null +++ b/iosapp/ios-poc.xcodeproj/project.pbxproj @@ -0,0 +1,720 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 60; + objects = { + +/* Begin PBXBuildFile section */ + 7F7E54B62CB576B20012844E /* Filter in Frameworks */ = {isa = PBXBuildFile; productRef = 7F7E54B52CB576B20012844E /* Filter */; }; + 7FA7B8472AEB238700363B53 /* ios_pocApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA7B8462AEB238700363B53 /* ios_pocApp.swift */; }; + 7FA7B8492AEB238700363B53 /* Previews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA7B8482AEB238700363B53 /* Previews.swift */; }; + 7FA7B84B2AEB238800363B53 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7FA7B84A2AEB238800363B53 /* Assets.xcassets */; }; + 7FA7B84E2AEB238800363B53 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7FA7B84D2AEB238800363B53 /* Preview Assets.xcassets */; }; + 7FA7B85B2AEB243400363B53 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FA7B85A2AEB243400363B53 /* NetworkExtension.framework */; }; + 7FA7B85E2AEB243400363B53 /* FilterDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FA7B85D2AEB243400363B53 /* FilterDataProvider.swift */; }; + 7FA7B8632AEB243400363B53 /* filter.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 7FA7B8582AEB243400363B53 /* filter.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 7FE743D32C8F431500607876 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FA7B85A2AEB243400363B53 /* NetworkExtension.framework */; }; + 7FE743D62C8F431500607876 /* FilterControlProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FE743D52C8F431500607876 /* FilterControlProvider.swift */; }; + 7FE743DB2C8F431500607876 /* controller.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 7FE743D22C8F431500607876 /* controller.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 7FE743DF2C8F4ED700607876 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7FA7B85A2AEB243400363B53 /* NetworkExtension.framework */; }; + 7FFB54912CB477C200EBFA3B /* App in Frameworks */ = {isa = PBXBuildFile; productRef = 7FFB54902CB477C200EBFA3B /* App */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 7FA7B8612AEB243400363B53 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7FA7B83B2AEB238700363B53 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7FA7B8572AEB243400363B53; + remoteInfo = filter; + }; + 7FE743D92C8F431500607876 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7FA7B83B2AEB238700363B53 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7FE743D12C8F431500607876; + remoteInfo = controller; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 7FA7B8672AEB243400363B53 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 7FE743DB2C8F431500607876 /* controller.appex in Embed Foundation Extensions */, + 7FA7B8632AEB243400363B53 /* filter.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 7F4A14502CB5843500FD6ABE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; + 7FA7B8432AEB238700363B53 /* ios-poc.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ios-poc.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7FA7B8462AEB238700363B53 /* ios_pocApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ios_pocApp.swift; sourceTree = ""; }; + 7FA7B8482AEB238700363B53 /* Previews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previews.swift; sourceTree = ""; }; + 7FA7B84A2AEB238800363B53 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7FA7B84D2AEB238800363B53 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 7FA7B8582AEB243400363B53 /* filter.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = filter.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 7FA7B85A2AEB243400363B53 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; + 7FA7B85D2AEB243400363B53 /* FilterDataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterDataProvider.swift; sourceTree = ""; }; + 7FA7B85F2AEB243400363B53 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7FA7B8602AEB243400363B53 /* filter.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = filter.entitlements; sourceTree = ""; }; + 7FA7B8682AEB271800363B53 /* ios-poc.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "ios-poc.entitlements"; sourceTree = ""; }; + 7FE743D22C8F431500607876 /* controller.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = controller.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 7FE743D52C8F431500607876 /* FilterControlProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterControlProvider.swift; sourceTree = ""; }; + 7FE743D72C8F431500607876 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7FE743D82C8F431500607876 /* controller.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = controller.entitlements; sourceTree = ""; }; + 7FFB548E2CB4768600EBFA3B /* lib-ios */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = "lib-ios"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7FA7B8402AEB238700363B53 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FFB54912CB477C200EBFA3B /* App in Frameworks */, + 7FE743DF2C8F4ED700607876 /* NetworkExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7FA7B8552AEB243400363B53 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7F7E54B62CB576B20012844E /* Filter in Frameworks */, + 7FA7B85B2AEB243400363B53 /* NetworkExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7FE743CF2C8F431500607876 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FE743D32C8F431500607876 /* NetworkExtension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7FA7B83A2AEB238700363B53 = { + isa = PBXGroup; + children = ( + 7FFB548E2CB4768600EBFA3B /* lib-ios */, + 7FA7B8452AEB238700363B53 /* ios-poc */, + 7FA7B85C2AEB243400363B53 /* filter */, + 7FE743D42C8F431500607876 /* controller */, + 7FA7B8592AEB243400363B53 /* Frameworks */, + 7FA7B8442AEB238700363B53 /* Products */, + ); + sourceTree = ""; + }; + 7FA7B8442AEB238700363B53 /* Products */ = { + isa = PBXGroup; + children = ( + 7FA7B8432AEB238700363B53 /* ios-poc.app */, + 7FA7B8582AEB243400363B53 /* filter.appex */, + 7FE743D22C8F431500607876 /* controller.appex */, + ); + name = Products; + sourceTree = ""; + }; + 7FA7B8452AEB238700363B53 /* ios-poc */ = { + isa = PBXGroup; + children = ( + 7F4A14502CB5843500FD6ABE /* Info.plist */, + 7FA7B8682AEB271800363B53 /* ios-poc.entitlements */, + 7FA7B8462AEB238700363B53 /* ios_pocApp.swift */, + 7FA7B8482AEB238700363B53 /* Previews.swift */, + 7FA7B84A2AEB238800363B53 /* Assets.xcassets */, + 7FA7B84C2AEB238800363B53 /* Preview Content */, + ); + path = "ios-poc"; + sourceTree = ""; + }; + 7FA7B84C2AEB238800363B53 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 7FA7B84D2AEB238800363B53 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 7FA7B8592AEB243400363B53 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7FA7B85A2AEB243400363B53 /* NetworkExtension.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 7FA7B85C2AEB243400363B53 /* filter */ = { + isa = PBXGroup; + children = ( + 7FA7B85D2AEB243400363B53 /* FilterDataProvider.swift */, + 7FA7B85F2AEB243400363B53 /* Info.plist */, + 7FA7B8602AEB243400363B53 /* filter.entitlements */, + ); + path = filter; + sourceTree = ""; + }; + 7FE743D42C8F431500607876 /* controller */ = { + isa = PBXGroup; + children = ( + 7FE743D52C8F431500607876 /* FilterControlProvider.swift */, + 7FE743D72C8F431500607876 /* Info.plist */, + 7FE743D82C8F431500607876 /* controller.entitlements */, + ); + path = controller; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7FA7B8422AEB238700363B53 /* ios-poc */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7FA7B8512AEB238800363B53 /* Build configuration list for PBXNativeTarget "ios-poc" */; + buildPhases = ( + 7FA7B83F2AEB238700363B53 /* Sources */, + 7FA7B8402AEB238700363B53 /* Frameworks */, + 7FA7B8412AEB238700363B53 /* Resources */, + 7FA7B8672AEB243400363B53 /* Embed Foundation Extensions */, + ); + buildRules = ( + ); + dependencies = ( + 7FA7B8622AEB243400363B53 /* PBXTargetDependency */, + 7FE743DA2C8F431500607876 /* PBXTargetDependency */, + ); + name = "ios-poc"; + packageProductDependencies = ( + 7FFB54902CB477C200EBFA3B /* App */, + ); + productName = "ios-poc"; + productReference = 7FA7B8432AEB238700363B53 /* ios-poc.app */; + productType = "com.apple.product-type.application"; + }; + 7FA7B8572AEB243400363B53 /* filter */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7FA7B8642AEB243400363B53 /* Build configuration list for PBXNativeTarget "filter" */; + buildPhases = ( + 7FA7B8542AEB243400363B53 /* Sources */, + 7FA7B8552AEB243400363B53 /* Frameworks */, + 7FA7B8562AEB243400363B53 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = filter; + packageProductDependencies = ( + 7F7E54B52CB576B20012844E /* Filter */, + ); + productName = filter; + productReference = 7FA7B8582AEB243400363B53 /* filter.appex */; + productType = "com.apple.product-type.app-extension"; + }; + 7FE743D12C8F431500607876 /* controller */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7FE743DC2C8F431500607876 /* Build configuration list for PBXNativeTarget "controller" */; + buildPhases = ( + 7FE743CE2C8F431500607876 /* Sources */, + 7FE743CF2C8F431500607876 /* Frameworks */, + 7FE743D02C8F431500607876 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = controller; + productName = controller; + productReference = 7FE743D22C8F431500607876 /* controller.appex */; + productType = "com.apple.product-type.app-extension"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7FA7B83B2AEB238700363B53 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1530; + LastUpgradeCheck = 1430; + TargetAttributes = { + 7FA7B8422AEB238700363B53 = { + CreatedOnToolsVersion = 14.3.1; + }; + 7FA7B8572AEB243400363B53 = { + CreatedOnToolsVersion = 14.3.1; + }; + 7FE743D12C8F431500607876 = { + CreatedOnToolsVersion = 15.3; + }; + }; + }; + buildConfigurationList = 7FA7B83E2AEB238700363B53 /* Build configuration list for PBXProject "ios-poc" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7FA7B83A2AEB238700363B53; + packageReferences = ( + 7FFB548F2CB477C200EBFA3B /* XCLocalSwiftPackageReference "lib-ios" */, + ); + productRefGroup = 7FA7B8442AEB238700363B53 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7FA7B8422AEB238700363B53 /* ios-poc */, + 7FA7B8572AEB243400363B53 /* filter */, + 7FE743D12C8F431500607876 /* controller */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7FA7B8412AEB238700363B53 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FA7B84E2AEB238800363B53 /* Preview Assets.xcassets in Resources */, + 7FA7B84B2AEB238800363B53 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7FA7B8562AEB243400363B53 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7FE743D02C8F431500607876 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7FA7B83F2AEB238700363B53 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FA7B8492AEB238700363B53 /* Previews.swift in Sources */, + 7FA7B8472AEB238700363B53 /* ios_pocApp.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7FA7B8542AEB243400363B53 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FA7B85E2AEB243400363B53 /* FilterDataProvider.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7FE743CE2C8F431500607876 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7FE743D62C8F431500607876 /* FilterControlProvider.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 7FA7B8622AEB243400363B53 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7FA7B8572AEB243400363B53 /* filter */; + targetProxy = 7FA7B8612AEB243400363B53 /* PBXContainerItemProxy */; + }; + 7FE743DA2C8F431500607876 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7FE743D12C8F431500607876 /* controller */; + targetProxy = 7FE743D92C8F431500607876 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 7FA7B84F2AEB238800363B53 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7FA7B8502AEB238800363B53 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7FA7B8522AEB238800363B53 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + CODE_SIGN_ENTITLEMENTS = "ios-poc/ios-poc.entitlements"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_ASSET_PATHS = "\"ios-poc/Preview Content\""; + DEVELOPMENT_TEAM = WFN83LM943; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "ios-poc/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = Gertrude; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchImage; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.gertrude-skunk.ios-poc"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7FA7B8532AEB238800363B53 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; + CODE_SIGN_ENTITLEMENTS = "ios-poc/ios-poc.entitlements"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 2; + DEVELOPMENT_ASSET_PATHS = "\"ios-poc/Preview Content\""; + DEVELOPMENT_TEAM = WFN83LM943; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = "ios-poc/Info.plist"; + INFOPLIST_KEY_CFBundleDisplayName = Gertrude; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchImage; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.gertrude-skunk.ios-poc"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 7FA7B8652AEB243400363B53 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = filter/filter.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = WFN83LM943; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = filter/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = filter; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.gertrude-skunk.ios-poc.filter"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7FA7B8662AEB243400363B53 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = filter/filter.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = WFN83LM943; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = filter/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = filter; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.gertrude-skunk.ios-poc.filter"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + 7FE743DD2C8F431500607876 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_ENTITLEMENTS = controller/controller.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = WFN83LM943; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = controller/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = controller; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.gertrude-skunk.ios-poc.controller"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7FE743DE2C8F431500607876 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CODE_SIGN_ENTITLEMENTS = controller/controller.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = WFN83LM943; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = controller/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = controller; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 17.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.gertrude-skunk.ios-poc.controller"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7FA7B83E2AEB238700363B53 /* Build configuration list for PBXProject "ios-poc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7FA7B84F2AEB238800363B53 /* Debug */, + 7FA7B8502AEB238800363B53 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7FA7B8512AEB238800363B53 /* Build configuration list for PBXNativeTarget "ios-poc" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7FA7B8522AEB238800363B53 /* Debug */, + 7FA7B8532AEB238800363B53 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7FA7B8642AEB243400363B53 /* Build configuration list for PBXNativeTarget "filter" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7FA7B8652AEB243400363B53 /* Debug */, + 7FA7B8662AEB243400363B53 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7FE743DC2C8F431500607876 /* Build configuration list for PBXNativeTarget "controller" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7FE743DD2C8F431500607876 /* Debug */, + 7FE743DE2C8F431500607876 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 7FFB548F2CB477C200EBFA3B /* XCLocalSwiftPackageReference "lib-ios" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "lib-ios"; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 7F7E54B52CB576B20012844E /* Filter */ = { + isa = XCSwiftPackageProductDependency; + productName = Filter; + }; + 7FFB54902CB477C200EBFA3B /* App */ = { + isa = XCSwiftPackageProductDependency; + productName = App; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 7FA7B83B2AEB238700363B53 /* Project object */; +} diff --git a/iosapp/ios-poc.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iosapp/ios-poc.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/iosapp/ios-poc.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..b41a3b70 --- /dev/null +++ b/iosapp/ios-poc.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,123 @@ +{ + "originHash" : "294cc5392bc6679434856a5c441a94b895b5c278e5f25fa185fd58083dcee459", + "pins" : [ + { + "identity" : "combine-schedulers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/combine-schedulers", + "state" : { + "revision" : "9fa31f4403da54855f1e2aeaeff478f4f0e40b13", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-case-paths", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-case-paths", + "state" : { + "revision" : "bc92c4b27f9a84bfb498cdbfdf35d5a357e9161f", + "version" : "1.5.6" + } + }, + { + "identity" : "swift-clocks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-clocks", + "state" : { + "revision" : "b9b24b69e2adda099a1fa381cda1eeec272d5b53", + "version" : "1.0.5" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections", + "state" : { + "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7", + "version" : "1.1.4" + } + }, + { + "identity" : "swift-composable-architecture", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-composable-architecture", + "state" : { + "revision" : "8013f1a72af8ccb2b1735d7aed831a8dc07c6fd0", + "version" : "1.15.0" + } + }, + { + "identity" : "swift-concurrency-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-concurrency-extras", + "state" : { + "revision" : "6054df64b55186f08b6d0fd87152081b8ad8d613", + "version" : "1.2.0" + } + }, + { + "identity" : "swift-custom-dump", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-custom-dump", + "state" : { + "revision" : "82645ec760917961cfa08c9c0c7104a57a0fa4b1", + "version" : "1.3.3" + } + }, + { + "identity" : "swift-dependencies", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-dependencies", + "state" : { + "revision" : "0fc0255e780bf742abeef29dec80924f5f0ae7b9", + "version" : "1.4.1" + } + }, + { + "identity" : "swift-identified-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-identified-collections", + "state" : { + "revision" : "2f5ab6e091dd032b63dacbda052405756010dc3b", + "version" : "1.1.0" + } + }, + { + "identity" : "swift-navigation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-navigation", + "state" : { + "revision" : "d1bdbd8a5d1d1dfd2e4bb1f5e2f6facb631404d4", + "version" : "2.2.1" + } + }, + { + "identity" : "swift-perception", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-perception", + "state" : { + "revision" : "bc67aa8e461351c97282c2419153757a446ae1c9", + "version" : "1.3.5" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-syntax", + "state" : { + "revision" : "0687f71944021d616d34d922343dcef086855920", + "version" : "600.0.1" + } + }, + { + "identity" : "xctest-dynamic-overlay", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state" : { + "revision" : "770f990d3e4eececb57ac04a6076e22f8c97daeb", + "version" : "1.4.2" + } + } + ], + "version" : 3 +} diff --git a/iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/filter.xcscheme b/iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/filter.xcscheme new file mode 100644 index 00000000..c303bdff --- /dev/null +++ b/iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/filter.xcscheme @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/ios-poc.xcscheme b/iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/ios-poc.xcscheme new file mode 100644 index 00000000..1e636f07 --- /dev/null +++ b/iosapp/ios-poc.xcodeproj/xcshareddata/xcschemes/ios-poc.xcscheme @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iosapp/ios-poc/Assets.xcassets/AccentColor.colorset/Contents.json b/iosapp/ios-poc/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/iosapp/ios-poc/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosapp/ios-poc/Assets.xcassets/AppIcon.appiconset/Contents.json b/iosapp/ios-poc/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..ee893c7e --- /dev/null +++ b/iosapp/ios-poc/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,14 @@ +{ + "images" : [ + { + "filename" : "icon-large.png", + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosapp/ios-poc/Assets.xcassets/AppIcon.appiconset/icon-large.png b/iosapp/ios-poc/Assets.xcassets/AppIcon.appiconset/icon-large.png new file mode 100644 index 0000000000000000000000000000000000000000..59f5b3a9937ff57b5eb5c58ec0184553b7e637cd GIT binary patch literal 97425 zcmeEuc|6qb_x8*fYgr?OP?9ZaF_vso3X#aZWJ%e#vhOoew27=Gp=8Ov%Q_RHNXWj6 zEMXYy3^Qh)d-VCep6~DTdj5I-|NfC?nC|y|pZlEaT<1DRPxNnSva;~8Kp+s-Yg$(f zAP_is35PH-fWJ`3q$0o@HfMEpeOGl&bx$`>FT;Dc@7QbFd)Rw9-!ag<41p*_M;lu? z2^e#$zNsmfI{71_FFQMqje^w7iP#GoF!Db zFL8X%or<5LT7DKg?vjstCjGub|2;fHoY=jq`R*q#^HR-)^1Ap>t_>YyJ9DY4Ve=E- zD-#D|Kb^Krnh=GZ<|~q(?VT=fn`>#g=<_+Wn>DmsTIxljWa23(|4b8R1h*>OIx)Ci zO`tk173ph2ACEs8Do|)YF>Mc_@O&w=Lc=eSzA_Km5t&<*+){<7xtc2>rbp7)@nv1F zU!H$#bM>@%-g8RJ=wrrtk!=e&qc?u^g)$WimF6f zrylhAde)b`wd-g4_BGRVoFeZ5zUQJcCY5WKzoJYl#XfM@RQaG{rpLbOj>fk`(=q9M zv-27ehTvpVeuYq}L62|M5BL$mb&M^L3=}tydSd$!31A#AaUJ;vj`Fj1ILlYEq3@ zlKpPN5?bqN*`m3ja^tRQmb9_k?efg`<_MErm{12Kv?idA$&ta5{G0GiEzb2DAx`KN zYG&fM>aQQ(>0asgC(&Q6rp|cTc-h<+@=n)u=?h$ybzLdWEM=Kb>TsOm7!r6C$h1t=4oe;^^eF#+%D) zeO`acI@qS4JHM@{Oj&%|{O$LQ9ZT_f$-@U{u^Hk^wF`9uJ=tuP$xgG7lHl_SO`g{% zd%UB8S@z!P3<_j1C4xnjBKuSUT{p?8Lk{gY)36FDP|Xh5HV6=Fv73Y`^hY#*Hr3Fi5AX-fzu&}&#|p=OC0>DjSKz#VqQB3|9&VM0)_ne z*UC^h7kHvDH1Rqo=YQ@4d`uXERs7es(MTA0;>nCSi4*_pIN)P&hyvsPItf@o3p^1G zH#&dy%72`YwgEH*GXL+r!I;4lW6|2#kN?w9v<+}TrUd@AH>5BWJdsQP8#m{_4+Mjx z(*1jdli-O+nB?mdC;oLHU~KPy?F|zCUt|BvB>y$`e?9v@1Lwam@}JfKNcdkE`8VSJ z7qkDHApi1`|6eu|tBXAPKlCD0s@qAnlWf!MX;ABKVW<{GBEK0}usX;-dv z7dPMe`LQDHy-Kbt5>w@)VeT~tg-yY?~|Kdbz#|&258ZMe=iD; zde+G2ORWh-iF+;G-%3frxsc^u9JU;^t9NVmh9U)5^_+>TnOO7*m@{I%*BMpVy=|H~ zx#~(?W<`bCdpp#mvUB&bk?#v0=tdns)lE@Uo+M;>DhG6raNojvHlc8JpDz8)qv2+N z!aTl;xW};{CD%BaqKUaB6KMpQJpqq~ch;T@9R()t7Bzh()6a*=*L&x(mrNw&3-gMD z`U@6qf^Jn7wB@haxTzCL<@IS~p1MgJ1d%bE2>tqt;cSC^J9UHJmpK_|qz zBcI%b{*s!uTF;3Bg~7hnMY+|#%|2dZsrO4JU#)VocJGl-HixO2s%OLL$m(F2``FIp{()~BNONQ zGYEp@Z;`rc9wTJ8W{3W->46{8_jCx!>Rn+XaCm((#>Aw!A!vnv%gMHZZ|#6O(K4FQ z{a|n{C}%gXDtA_BJgg(WLEu2~yFr!)V$j-xDpfIm1uk?vwo}R}gQ1ZTy8h@nA5~)X zlc+tNy2NNb;?5g?2e;lTlWtpm5hj*el#_bvIty3DHc6VXx%eNdJ@p8%>3R+!Jq?

zlQy<^ z<`(nAi(4_PqoWIrSEF$QdWF=zMlrtmXQ<)NtC{CjD?6^X@y^oY$6&{wWO!UiF`Nny zZ;FM%c1$>I15Vyi=kJtryY8BRw3y6syQ@>hb5b8^i!@{oSqz_yOocaMW?86xpYJjL z;|&E@&=9P4Lcqbl@7i|UleW~b>!KXBvorD7qk3Iklk$FoZ0$u4{*-@3gizYuZhrE_#%eEpl{lni-nP|G=<6eAx@MNcZes;^Bls`eetL;p z-_{5Dp&5aL0kM8t^r@~+n>PJU2A~Et5g24BYi3r8fs=7oS zTeByODxAmvCoBtYfs1G_3^+-9JSfWQ+a}9#U9KyXh3Hz9ddu=Cm(9t#Khczw$erq> zUmJm>i7CQO=uJ95#k3Fd#N-R+L6Zg;4({#<^1uem!WL4AsR@m&s_b1w;KgL4 zP`6mA!PWKE7(^6m_oh@}y3F`I>p)htNn2*=WR2khvrXln2J=-ZRw6glCg`5lXNZll zEve|ad;j3vv398pdq$NQY(`kJ;rY+cWfZlte2NT)4(%Vaiw5R9k{=-ZFq(guiIr$_ zUe&WZxGF5YOYNf|15wx3Gx>q4#DovTz!|y;xEDTRq z9DJw2z|9aU8t(J;Xvv*)4F;zmY+7;|-|^VeXiG~&cp0DKR5+wq=>ar6mby>jo2+`^FVt8UgTG(5B2gDXSyf1ah9OLzEFBO?h*uD85No>m`6ew&Tw*>9Z* z=2AQMo?YJNBD}#;Q_wp2+q3(VTpZL=l@qpqJnL@@c`-QIhwJjuPf4-VZ)*HtYfLK- zEp|Yt2p7)MtJq+FI<8;%>&$yHNJs{C=@l0(i#|F0%2Wn*WTZH7Z?J0+x6+@Y!k0gs z8b?kH4Zw8$A(&9#M^F5^dPHR%cL>U_=0Fd-d{+26Pq#MAvN8^jMAfc5#u7@d!LLUSH`6RZVe^D6e(K2d17mhti0v@c?zV?#HXJ8q{R_xbGrp2Aq| za(k!oeVA!}RUB1X)sOGNGepo5Da&^r3Z>?`)@t^cy6K0S>h$YV*;hUw`ZGO(*%8g$ zP(8i{9Ttaj)qw|pvq3n8#}ZhRyr5>Mg^n(r1Sbgk<8qXeAFt5Q16_3d^`#nJc1a5;CK zQM{JLC5X!POa`qZL#B?^RcB`i9j^TyyZrL%Ut=Dp?CX0QRK zv~DZ*3#LbKS}y|Qm|yG7C`b>l(9{$7WF80$*+Re7<_`ExQXDN-hQ6t?SAPM4LEqkS z)Z6!tHK3Pp!~{)=?|W#PIyTBTIdP~fYTJhR-fr-R5$=~$XUGJqvd`kY$C?K-NY>$KWykx>DWK0av*?=T2(8&UEl#43Y1_KiPCM3TQW!Tutq8a8)O@ zGc2}u_7HXX)|8$l1cK~(oJs%Z&oG289sWbu#83=Za}Qpx?@#IbCXM;lX~w92x{8FU zY@G9GqmnBl+x&8WwRe?iCQQyv+w!9B3-lN3kQkZ=bO*yuLYEsZ&OD~Y)fJY9ij?*t zHMQP8JSA_uXHW$}X-{X~Eb|Q+c8=2pH$D7XIqu8q-_SmcE@_VfI zO_6I3Z?q3D6!T)}onR^Y-U?i8bB9P8K} zng_pbKj&en2+7cZpJqE*uoJ%aH*T2fGl0!_;lKav-;b*>$DH$$T9!K@ka8$x5JmEm zK1r-28h>fs^3EDt#1R;dM3*3P>HLmr#0Q+kb``%Ybf{zdoggCYS=7k8Gf&JKSnkq!2>38#a?jH_(Bqz&x*BhTs8mKVDb&)gsEaT|HN_B;_YVbjY2^b zJNp%WC|c{m=na-DBG8cZuor=4*yD&@|CO#0{z;jk9>RK+vu0~#qL8q95%$KVa! z(Ta$wAsr4oI^&t7a?%D#;_Ze4Mc- zPVhvq%y8`cZqgxP<|!}9v8a8YFb>bQ*z9y@7mVpgRAXG?*%$rxZhi5v`8axKYu8jt zPi{Ba)h19R@K4oPsE*K~w)AB1NXz*Y7gIE2dPvq2MbXT9|8fVxl9abaqZJPTuX|fv z7<~Trwa?cbYWOVY&*Rtk@8=0G0EB5hD1>(GtwZ?M1bK>7mPyrCe##{3syan%Wf0dW zUo^KBtcTC3>hp@GY$PB~m6eTToo4r%=a zW`6PPH%AtGO#n30VjyvZ`8IJLr(r1vJ`&|RT$!!%$++CRP1|p=`KgM*DynZrFH?;( z=dvg7c@_q7EkwP9eQ{$VyAFe3kd$LEn?1r9TMn0deYktH@_Ua6SSVBkAhc&*+yk0d zG>A?$P^uAK)X%t-w|fO{@-hQ%H?C3NPZ)ceazYjgFY5m8siK426c9E&3;1av8KTWi z^!PjxrdG@YKi|%eO+a5s6XNCr7ykG)@UK_KOi>ZwCN}Gk4Fi1w)X2A#Pj`7Sr$4q~ zZpX-WVNBfF3A{)r$sX%Pg5kU3_W5urcC$y8zPt1578mt zJiEsy@g_jOe4|a$Z?)E=e?v`i?&F>%KWhevyD%Q71)r|m4*Qw8gkvEpj;mBJEZZ?@ zGwVxepH@u_2mQieZO$#=ipVig2DB7vC_83MIO4TJ%5lR^`ihdr}v7tnyLXP(5?S06}H#!MVM6{A>+GzH@~| zVr)zNR-CXe%v2}l&+8(} z0eYx1+mzJp>(Nre0|kqr?+B4AAxoOhqb2=0@K|2kj}mG$muK?10V>h?)5A0_7;6@u z-6|Kn8dh^xE~ql^B+6b?C4YF!+gPfr+U#<(Q_a9lyMFP2X}AwX(=+^OcGLAS*CFzC zV;fy5?w@`OxK#JCxT=DpAIg`6|8btThk^4r-`u7_(8=qPIZLIdvA2- z$KgmNvCc>9CrbFBD9jZ)io7H{HVJn$c#knKn6MhrY=TG#?2woB+{woz z;6`3+YuU{;QyPBh&8UTo(O+G8jK=trLyhv~aNDyf9y&=qd635IQ>}&0{02y@H)F|P zE8y!v(?Khq9!DEUobop0&kIZ`j%p9)!$y6sE!gukVqqgz{JK`3FKuKj?1$*tp8vF@Cl zll#IGsLnVcQq|KhX}5KPzP`HjX8GAZDv?pN4wdPUIp{i2kUuziwGa8^{HvWV%FML% z4T7|4(WfvWv0{Z|I=7Zw*X|c44$hR;cB**{Z9ddHkUKi6CO!1nR6o>hkm?+?ZqgHmbO>o9O={E1LR{^X4sh?Fo(t?kuo?#%Nc^ycC$N+}T`b zDCt5W56lY=tu^4RXQH_?Be=-j3@!;6?Ts^3Xxm02ukC*QZAaBJ!@PXEYFj0OK_{Fy z{Vm??9mnHf$C)yA5Lq?ZZ`DkC;?NRGc#DCF9e(LUpDyG$2|R&ftX^vF^P^aJ?B90Y zltlQ?kntNRv(i!RP5<5IGLG@#I-@L~u;vZ) znL#=kTKsRm2ZpsSK)g6gv$6dB{V`I8+e{|w8{?Ttet~E4dxbq6<(A+h z;m82B#ruDr4}VQcI2J17skXDKUPZDUSbwz1vW->WkF+>RKm7a6*&M9DC&G31$)0zluNvcGFspPiz$bT=+a@p;Q7sXuqN9;~wwWR|EzS`{{fsLd=6B>CEM5opRU~Q!EZCGI%H8PY!vSWf=f6?#0 zQd+yWC)7Y?R^k`;C_ZrdH@y2R^_Q+hFz#3(8@}U`5?&+e52V4mMnH|`ZkM1M5Fd_s zD;kJ2oS5>a%scY=Ef$NC7G*^F>x`>i%r#e8Q8F!Y6DaCUOpx8u7gCxy@;Yka>Y#^! z_x1dxC(VnI&E?i2^^Ph5IrYZ`zt)kBuXez8Nq+h|a0j=I8`4Mr?m9LASoMh-Js2|x z|G+G}s4FG)Ym(^H>0y&M{5!&AW-|Us)@WdJ{mW9HrDRf4lGF<|!ZY8T4$ih(i=gXo z&urvv=P;7AAndRJ^y)-(-gsRat6@;2T=r=-Ejw)1)|W1tWq#6H@`bGuG9YtVWDM(9 zQEMW{G1mPh)VQ~#0ypp8LI(9dqMj_rBh8F9`ommwl1%rg8sj%y5@Hxh43UiPtGBu6 zwga}jh_uT(a3Gd$>JjrWlx8X=Sb4lJ7&EvpXh&b9w_v8G$c0rqRG%@yz2u_s zI9hsB{_NQ_h;<<|2H}UjU;!MqdAC7cs3Of;XdPB4IbQe@a*%GZ^5Sd&?S#CX!Vvt4 zAZ1dh4OQ}}#@5+(hr(#FR*vg;7$BK+vC&`i)wH^)K+k{h0D^2TrGa(`ZB zBraIgarjpIc0-b38ai9`5EI;IIh7&}OgsKrQwh$%4vSZhNqo|Lbw6h`0BGxfvv!ac zM*}cjX}D@}E0tG>TfLRaKcC;ey{ZzjxMxa0^>IA*J+7bt!0keK>>*??^hc<*oE{gk z9Ch?yJ{>p1wS%7=7M73D&Phu{uZ-YPG@-!fa)z~M3W1!y_7H_S^IDAj#&Eqj7o>U2 zq4s6E@ChEKbSSO`eZf%sU_iZH&4XcfieGotYR6D(;Yo(&@sZiDG&6bvCXdHyD8s<= z3(U~;4I2qLT+d$0c;lvT6GkJ#nwpl2WaA3=V6K>l?r5PE=?`ia54x>NA#|J}SnNFu zDD)JIZ@y%}G1?uEf?QK8{bPw{N>|~jXzKL!X2G%C;cu9PevW~|C#>NZzUy|Vp*R+3F4Q8pFl~OVG{Jf0ZWVktuf%-mqLT|GYYcyJkpG3 zsKr@li>nn1FX#U1ilqt`TxUBPeunu{4 zfiC_$&4~%X1AV$uOfQ4$xp-!ZnX0{UIA~7>Wn7h?lZZpL*6nQ>)c%4s&ir2H2yf)h z9sKT~d~T|=%)U&5^rx7?eJSm9FLbx8N`f1Nzd4}DajxlQB50)E0oeq6altahQMCwQ zZ=zdB#eg<3$KcTmrJ&WI+Azfccoy$|;9*rp*Sl9wR>Wc;o4e z82BgeESFJ&LsRIZ;{aRsn2}IUr0_Y~$c|w@H#Zc%dlk!1&8mr1skbUOM16Fs!IX7& z^;wEg{%ox#yJQP6`B(|Fz>GSw|6DQ7PvWmy?N4nm)f!z%F1HZP_*j1;a~(PH}d+o8Hopq^HF zqrX4Rb6*?oqWXTV!u8vW2+4+8QMuW`&TNFU;09@@p6<(r!gH|WztV#!dgOO^P4!Hc zcZZ)wE>=b2cEtjHehF^a-3tJiL8c%i2W$U*4=c)J!glb4`&mf}-n9Y0!MpiV9hLDsm}92;SuQ zbROQl2C%jrJ|Uz;Is1caY00Y9sTVFt&h;Zlb}U{Fnn`{6<>_;41|W_gur4tqWNK$D;4m#pvteoYE`F*Q)u>FzCPDot z<|u-)cTwqpeEEJUv1d9<^8fLHAI~m9(tP+G-eS^wN;-{`;)^ot7&Tm4>^gBxwPJb_GZzt zCceL`{>ET?fD|~|Se(djYsL1Q_b>XE0;uFMTtm`A2}d9D16AoJhZras<;~y5d#K!U zl0Pg)wj?!A@z9*vp1#QkauvF`dp#x1N%Yism6-dZ&n9-*(@&tuzB4z#8p3CQ?@t>X z5&-?Vlhz=j?6=6lnUnM6bfS8Xpq}`z^fOhNil3fn!f0`9gVlsBcz*-8a`9$QVUomK z*AZ8>Zmw`X=2&gl7A_%+B^x~fTG}sp4z_8p|LFjLUo-abr$IC^Vzfq2+i$(gg&Y&y zk={xT>Z30PS2uZ@qjJ@i1vaK^b08mn-T4Z(D-3b>jo;nIop0oQ3DI^O*s*|LMdmq3 z4;3`{*oh4NC`iq>F~;q_&g;CMw^kfIK~3VM0?@in&;6kw@r@tBt3O+?uTa@>Tb??g zeekOf`qjYEC{UO^0cCpZ!eR~{>~aDWmBruXaqG-Bi^Xp2s}*zPsOy#&KjkL7H^jsb z(rTonLrm#6pPCNjIb1MgtqZ8X`=%;;xikGRsDz)-GXCsPi6#L{1KV6f>&^N;n70Sn z2kJ=B&kV;}`R9fft#f{~sT(2gIh6`Y@N*7mI z!|yuSU$g}Cgwqy|w989*Z~~1?gB#&y4ms+ULZ(LYdz(~{o{a1$#E8{)efiMxN0)*R!$|*eB*Hq*xf5rjwnzx?TK`Q`3YS6ld{mQwz%l=ywSdZ zx2-6u(K%7j3SkZq?p0fL;VCySbn;q>FJp}sKR2bv;MTG7e0CiURk%s>_bo1*Ul}nFg+MbUrWy)oOh19@8L2-&+U#yN*szU6cD@di zQJtlssvUqSVL#(0D4?krCfWY2)g?O{N|_sPjB(RXGa!=y`4Y05l_UXHE6_q-LjMfu z^{~nv>ND&7seO>xOm+PlDW7vX-d?=#>A^q_8YhO*I5F}rFYS&Efcuh42A6WA{K$l> zb*Ki9c*1BjO6AoAHOr0+VsP*DRC=HwdGjSC{tm0sPO^a$QE2b}gxsou9dee@b|3i7 zg29Tep5LXwVL`?3fpNq%@^euVmj`xI2AVw{-Zi5sEa&xswqwTe_yL5nqY#$kF|R6R zS!L_DpcFV-+g5N^i^CTB%#(Jp|It#2lbBMWhTT^pe0n#55+(Q6Q$aVuRb1TmxtH$T zwM!p4k+zqF;g=9x8Mn^!HyBicDo&K)x-%Tz=of$F9`xz|V?A%m>SVz%D}tg%jfvA$ z?Mp18^lagE!nj?l;zNPEOvCwD(>EsFM9HL2 zcdKP2e@#9IiJl$8N^N<|#tpc*iNsWTydWIk^}Te|SBd02?Bznlkl&`d599LbIN)ZY z66`coY`h5=o%}jphsI2XVTI2IvOB?I(HD$aNz{wKgrcdAb!)Wp$hH(zDB_)O#%s(< zSw)@eG&1|kzrN?5d$0fgoYEjIDl7~1N;~{#SHbFkl(Vo z|6_UJQJ#v4HTu?>tQIt#+=p41`HflTGhzEurw%x^cj?+mkk9jwTErYhs_JiQU%HOp zj9dSyRjFS#N;5*ojIOC%5SNEB)t4aaqF2*%vfi)fJHfHcp+6iBIC$=bU>W37?0Go; z#z{a}_~wRMq9aZ8`^Lqjv-fdLEhx*uQB5+cmD*?4oQHdelBLA^s_I*SQ}BnMJ(lq+ zpH4RMh<G6QJui*a=BVEi*3<}3OpeLG3%0qzil|;*O*$_snna)89x~GHve(5CL~-C)brgUJYQ}D3liY zV|$P45lu@wY$QQl@K$oxM9*kBk{Y#ADylj*xFUCJ`sV>P1OGlNpS10b8ji&KJk{aq z>0MXT+3q#kjruvtp3iXJ`3(9G?T)w z1nP5F)h}SXSR_=)E{O1yixO%Eh_I0pSqv|b@fGNYp3v3b1Yzv*opSz^w5@>pcgC=v zew%wumpOzdM5h*LP_}glbkovtZ|aeeU9Q zHhS8okg(eyFnWxyTrF@n#v6&D5+T+YO8f&>w)i8l@iZzEkOVTQ!OR22x9g6s@Rl`u+?6#VvZk#j|-5@v8$hc~&=@)K+(j6H-+Ah=ay>!`I9;GI!y@ z?V?4F)6+BWS90qXLKfz|k4w%x8`ltl&N+SuU4xMUl|Lo=9a#O5NR0|l&bTA^FV6!3 zMsFrVu0crosuHXq7heYay3(ar@K*6iXE_h)H!9hU>>+)f9^c`SM6#qm#ZII612?g1 zU0Ypp05U#TuWygAuW#>BfrrTlz|q3kizcix(Gb|VLx3ZGmwecK2@<}-GG^F>@fJ#K zGC&>5OkvDWhWs7CP&qXf9dZ>im;J`#bCz9i%wm$vhvmZbc^>#zj&5A(;_rJPz2V?T zpe24)%Rs2Mlblky+BmLYSS1r?TCtRqFSnE75na3DMtw0sMYf=5kgCT_oUhY6@b&k1 zKPg^p9aX_;l{}6%Vbrobm1(ozV`1ji600Y33xNC4*cZ^M;q_~iyQ%WQAFwNlG97;Nm;1AY1`?MMPx0F(uN469Av5A( z*P#m^PLV)@9Xddyx4mD*d4@>__3j}m1t>eMloCZ+K?DisVYzY%z4O}P>uOmj=8S*; zwhUm2Q>_Cxv<`l{d|eO-!J&XWWvu2Uz>cG_Ua$#~KDXR?8=bxJi#DZtRR5k8E7K;- z7ZqxU%FDmJKIjHe5xy(Sk=EI-z7fc`3~Y2Rrhc;B`JAA^Ow^V+NLZ|SI*aB+PW|70 zX}C4#r()mtT_7Q5&G6Kr3KMY{(-&`N_Qwp(-eNCv*uHl*#pIa<7ICiA39JcYA<@)+ z=XEFGx4eKh?HR-;0EkZF!CR+Ao+nKz8JaS0Ir?9L7eZJ;=5-qzd~DX_mZ&B zx+{FB-h}Z}V39*sjiS^Kd2q+OT;X7JWi|$>)_1`k*d_5mEd1WAi85#_0?Dc9IOR^Y zi{Dy#+<3!>EBY~f+VHFg_c{k7D!(14HA=gVXLOOWVV@J@vcsb#&t+(YkJn^m!PdyW%c&2@R@t0$ zp@Jmco)sHUGechV?~uhDi|o@hFmI=S{|9IqDSp#2SA&&rR%_Qd7w?rM9zwUErK*2} zj#+md2<@Qi6$LLi2azG1WSZ}%ca8dDuj+2*ZkTiPq!KlmjeKjR(KF!55ZR?>X0CDI zbWE17z#DB+B;7k&fN$;x_?Pb`LnMZ3B%%*W$>BQF*+D(Dl=%6;2{bkc zG%3v3eXS3HxV?gn+9S=WQ(~xL)=+fHc%2c*7=wFZ=NbYmcgv|BV7f(3tY}ike{4)M zRAb&1lX~E0;B?5S%)q#KTTtH};)P$2dgarO;I|*8BtF|{XK?b{Y-52POv&o)NDNbX zku*rV@r$&{x{d5*!0`tz0X&Je=*<=!sQjMJMX@Rx?u)4H&%1a8lQa|Lam?jWGVNbX zi$*wzFbsO`y$q;ALTXy6q2; z58xv^l;!Q6ywI&npr!KmS>-?~O7UU%o97ePyN_PFNfVKI58*lOH~66UHr&2wdl$aE z8->y@X^QoN#~qsba*qb@EgHx*U0OtB5a1~(8`OY;cM~aP<26Q=YjrMU)5EMgIct-_ ziS3-Uuv!wI>V+yZ>GzbOXZ)4lxqZ=)F?FB2+00k?8oCtVQ!fkl4(tV5ORX;(fQ6Ic zm#a|e8>50B)dX1&fHzi3)16J}G&!BKx2 z2W2X_CHx%T-7FL{h+EdQpM^WQm?L{xpebx;V}FW=pOS(Xq{eFkzVV%=Z53Qr5C9?O z5FRC;fL{&je6i;-;UUSSpC7g{v-8hfb3V`G>2EP@i+*bxWg2kV0t>m|jU0NN3*mm1 zsmg*N>zo8ET_f@HJ8<{%2gd61tWgMZ!yxs?m%RSaAE?cQZTYZ6qD;5Q`ST4jBbuq6 zN>+1W6E>+!=Pp)-ZKGb6T~)o`82WNu6jyVdPoUm`<)#y7 z%sh}N6chZ45%{eRBs;BGd)Gd#&k0Dp6*JYLl|Los<3p4SQE#HyvT~eAh}`?B_&Tho z$|v|GDQN|?)G%5*aob}G1Cu}RXj{B3sHoR@J5Ais?r55sHVf7hiXSvIWQM4mn`*I& zW*`=DWkcOYlPg&*d-+&PZt1Ev2(8d&Ii~@+6h4Fad>rnO)f;5Lh%9AHOMktwz{1XX*l1zK4GR?iT zoL2-eXo2N|4A3FEL^!x8oe1?}4Er7?xW-{?JC&N%KpJ9PBwYRY zMJni@ELgbhINk@{LYivoDmK;Iea5)mB-Q<4Kh&D^E)pKgZi~YXgIQo7(Ca{IDh?k7 zFSVyWSLTK8*jUWzRX6@l@7l2$dJH+OkEdY|8tD&a98elhprI}n=Aebr6$K*L_UTQ? zcp-~5(9zS>(E+pG8Ef32a!~^995tn$5?3)PFkjOzIAH)93XvvNHgU(3Tphd8_RVJ^ zoS~*Qu^=OLZfdA7#cH?yy(N8KM{PV!lLxAk2*l3%l7JxW8W+A5bwB%db^i?N7s!Vg zlkzx1kvLtsJlUBn_Qx%wfVR1M`bB`tH`Sr&GWW5RvU&~3bGI(D+v1&*`2nWKG^3F3 zK?QrVc2`0fw#JEnh*C{hU&+clMh!jpeTU#iJ!$e(@7Vp5`_|H9Ax`Ep&%zaUa?0#C zBu2dz92qCS#~;C8I~4}l%@O7gDI<11$^tBa?A+vQ*h9W1`=s@XAABv%^(6;;f1P-|lg~c2MhQpW5$x^%zHv z*2NX$9oM{(-wi>pT1|>&3o{-;*_=)yZ|K1H2R!a`0eHz7nKI+hdIhRtLay`RjRf4> z>pYd8UknrQp4UifUr+lV?T;n}y|bwO)h$zeDYOb6RI2*1ZlbVm_D6MCepjSMQQ~~U z5&e!qYjTBKO}Nn!&RBje%an@I2K{jX5is`%RNKcc*|AJ5dKroMV(01~CdB;F5u+ zWx!C=xWHxcNT>U(diCERJN9@;E@8yT8*AjdyQrtnlt6R=zJwIsCC!E}Ged#Cld7-i8&Bxb>{>GH0f#o7eFk$WYYE3`f(0*s2*`%{iGVT zGu2Af8o@>RQWB>C!~Gw$WKu|I(wcby}_brc z#Oi<=47^m|X#ZSchn-|XIk@Ol-5w@F0$5^W7QAl>R8Jaeo;xABx0?}Pi8V%|lWmB{-SRTs-eyVou{V>)?5_UMy- z5X`-76d3k+J$TcI%QKeiv1XJ{Kg;l+%uFT?8T;3QezK`B-e@*ueC0l}=ZdKFui=Y> zd5pOnKR0E_`1u$O78z;6B5e#N)(1>D5n8DalN2vzD^g7x#m${Hc$F51w9ZY4|H)yT zUA+(WtRT*Lzsg+AJRGL&e`ajZ$8^YLzd<5w-v)6^41YD@JYcTu#>9@{m8Cz#5G#&DyB$5mJ!mI28JWl#-{%vYw zYpKom)E%8`pV4=N^@HHM+F1T&mbt6Z#D#$fh#*8OU+1{X&_m0;WbHrxIuWQwp-@DK z4JAt>Hb!9g;w3FtwcA2L9u-}UWgpHmo#w)OhjisD0*rQ5+wG6V4KD6i)>sSXvoPDj zyTdYIg7DSRV&}k2z-aT+@WmgNcB-JfcxI)e;vRYjPRlOuu`c7h#y?!x{mG+#`>g$= zcL}oXt#>xEwIEW{enSLk;* zwWOUiT0)@sYU#k^j-35CPdBS!TL^BepzWQaM+siziS*Q2qRm z?~0!H?D~Q5a3}6?kIc@FDa$2< z<>ZDM>^^Vq5;?tB5lETFtIhA(Lrz&YF+EqzomsC0L+V`-@<6=wU3xC zP&k~7kr~eF>Zm>IX*HBnzt#n6nHMxaYfRzd&SdT?0+x}HenF9yMDTm;zv>!HiS%9C!DTX&f~GMJOLQ^;mo z818PS@b?<9@6O!l;&fHQkS1If4AEE|@!bq~pPhlu<`zGqZ_+LNTgW-NmvGGdO7RA{ zO%NAu3BP!HYE_yYCeE}yrO`>ttYtx-D`5!NU~4cI5>+{TjMj!_wtb(U-Xwx2!@Lby z`7woVREuWfm`x&HPsMNX>m79(8#?Vl%?P?KCuE2#Tx{eY)M%k$ERxb~9 zhpi3^ndo7H2%%SyvI(jhU(6M_+1UbOFsPLT9lpR1Q!^EDu|KX?s3r@#82$Xc7jy)n zpW;b>DpRbN7<2MdbRqi3YC`RT-?4UQV{}0S)wB8bMWkCyG97q$8lW}ZhW%eYpWt8* zHy4$>n17n;FVnv~os-qQu^LV7rid|d#Ar{8b4g8kFRI62g1AE;H?sdBFi>7Z43`WL zU(oGRW>Xux9=;>1nyTfu1%d{we+A#y!rSEgSKa94xP3OQ!&VVnXmlL?0Kx#fK~Hq- zYjGME94{Q6VT_KomHsW(BMwb>nbLTddj5nk$DqZHh5J`UOnq)RCfsSJ^U(yYo){FO zfZ%=#zQ!e~UJ6uAb(*ulzj<(IJwUUQWF#d9Ut?TeW7HCt!8DqRpzFhD_+^;(y%vFV5bKiN)=*k%7xhYM$o8ufHjyxRW26jQU}u~J*g<6ZMC3}e0)?@ zR&3OC3gLaFjLBg$@@~tjW&PH4=(8BLqDjL0rJ!Tpx0dd$-B*c6mQk^rYZYQb~*L)>gfY#D{2t*b}qpp zCr=;4%$N@%9wC_-GT{&OLLH=wk`qIy0>0HHqaRfK-%XvPIH)Xr=$!t1nrf*ORKvFp zb?bf%>2(o+L+wH)?m02F&_=b-6$`Vmhbu4<%d95e$ZchKp!QJn%Re3MrMCuuY!|z7 z0+C=L4cXT#RHIhl`6Qsf84PD+~0>e1tS-iJO ze&nD=hADvhO_$F5V_@?y!Mh z1@ZMCV5={hpopZ5VpI+#%`LTAQ*wl@r(Rg}n{su>xth9e;~hF%K`}B{lcy49*6RYZ zSv}HLEKT${Mh~#N1s%L4NN7Q?N{FG0|Bl=in1FVf%a{K{)mKMF`9@pM3_~}FC@7s$ zilo#aAl=d_3eq6mGoXlwbV;M4C^a;aGlJ6Hh;(=N#C`dFcipwVwfKJ?o;YWpz4tk9 zfb4aeG!!k(dMV(y@TJm9+S=II?IcM>j?PD(Yuh#d=NA9`h@0#~c&)8OrO=nR@L8&s zWa`-P1?|iul)BPCawoZOCq&vqUZD=Y7vFj2TAd+Gc2?sW;6E9F`|B$kLVnLZ@5fsw zh`a%M!r_dvKaBv7e2vH}!<`w|nF-Bp?46mw6YBio(j`OkAE2gDObguC_~LPtoK@%@ z+3Nz9v2$hWo7H*2i;0$^$=GBjp5lwjAz!r=DVLo%gd9MKITmheuTkQkQEtptbKb4I z*fSBC*PQE`>g@kO>A2DI;Vp600-Bvq^~LUVe>R`gVq1}%4T9I4`QKo7)_gSm8DOUU zUTEBs9Bfjw0JO)SGiYTMf?L-V&3=vNm(I^N?CsBa?$#k*cStu zWdHw2E5MYxkVhRKDpo{3FCc#O8-5gT;o=lk^Q*ppJwdEd5s+esEa4vcRPImPY$!)| z%v%T6F0Ss(yIuJXA-Qn|<}LAc%T;$x4ztRkpCbeb8t!$kLd#0N<-QOqy<+keiv3t7 zuos;~=q!fNMZJ@V04GB0tZ4To8z2!ZA2N?N1b}u18$%OWl8**d33n6`Wlsr2B49}J z`-J%uE(uGj`EA#RniN1xS;AXWaDrB=kMqtRc~(q6bM=ct(}6vXMVbbDD)Pn%u|)PK z3der4aZNVmJLdf!M`a}p)gSWCtgA|MV5Oh$fG@Y14Z{#FHfcM5qbs%JB_Gd%sG-W> z%*adgMx|#1B(m%@Il&pO-PS<@Usk|Tj}6c>WE7X7*UAT45@2}FdG3Zq!61b9a`*Qf z##%6LL;aYF@8Z>{mO*VcVwETPTM&5>xzb!m-PN^btZLZPa?ZUKw--^Xm!j^-tCLUp zTI%5l8OClu3jt!wi4?xPn|i{2SUtcnn0sTeK4bhiwHaxDl3K-z51RC2Syoz9=en-n zzXIVm?fw2k2L~4gEBw*pEu|FH2%)BP- zCBtNGk(m1)S*i0LOU6PQh4t&~XYHZ`D`mT+=Py645$x+5q$*O}=h%hyTVv-skI9R*gl|+xYmi5vYY_kU|1^-3EyZ|9+ zPtG*?Y*PZr0cpQ7gA3Z>Rz#by{DZt~@9-o)eRS~N-z=M-j48by%C~W$xAwv%z1bJ$ z=85djPYbMlmQ|i^1#RU;%ASeNWE}-m4(blH^P6^q6h|u!%|=7L{BFkOR|xeG4bsM?(g_71Ewm z1x9X6<~gid{H9-;D7r`P`^hn;X*3sb8?w$0X@E6Y))f(h4>f5JRo|E)VYwUG#r;_` z@>|{ptF0RHjnwvTYk&jR?+aM~C1BA)@c*x$^6t(3cKq+1qMXZoM;ok(`jLf&x7Eh0 z?fYVlKzk941hgI@r(pX`8nuUQOW2XluG$f?Z&gF6P_In0(2&R>>3tht71?#*QGqAu z@yE7f>Ev7qe+d{SUq-DPz84K7=ZrqR+x52*#Z^8kD!SDyHEfL1$xNjQD=gk22d-Qf6g zOD_EBH>bAgVZZa{2ujD!lOOnde_y*8W$C#i?)4O&T1TGl(?;p@GRch&vVm-V*cqz} zjAYgx&Z4NMc|unU)F>v~YI;6#4oYA1|@IFrj6rv%_FxeEMwf^sl-j_6-~BBRsY>dv>vZ+TSJKx}%ie$lh;?+a4o*M9b%F0)5slAdl5DXw3}1q*jJ8nC;Zb67`O$49cS_>i=f8a^{ZTx`5Gru?26|I?X} z)O@XtiG{5335+*`xS-nSD*((tOzf1Uoy`Pu6*{T%Gv86ChtA(o1f&tbB^?IQ!z_~s z>YV!<9AV`a0KOHO=2M!_{u&68gSW%KFYGZcVk7pY?5qt_LP0@uP1bUX06p)yap|{Hs2g7QfP%!VTc+Up#CX&7-D&0US^q zc>ss7$GOK;as^hk>Y3Xvfd|9rRl6QO?s-Q*)a*RU|C4hE{(1lIrD$sgCE0tcZY_!R}Ak70em{$pDTm2&nTxDY*3oLBAMNeKizyEOht>n*0^bHg}> z%^Yk@iS;O`ewu$+nqBtyk8WzPN}$Q62Gx3AGZZr3#1s%-iy-E%BCGiT|C(P_GQE9XwXM;6uQZQZbuA}eK4WAZCD75s^eLrw58nm?8V~CG`I#XDG`6dI z4{d)khg&m}kmAKKK9|p|dayP0IBmXZc=On9A^Y%_c<%wS5uy9Z32vXd?BQs5kD~bG zS?yK)s%y+DmfAzdLdUEQi){~fpK)=Wp<+`=p!$_>l?iXwC1q2s4c1eOT2eIqW>;#_ z%(W5Owie$nu1g^$^JxphO?0e`{&QOw+N=Jtz&pH>15I*0NAyyU?HFS+dTw$$m(1Eb zouR-`!{X^82Ks`%EN|sEm>@K7YqW?B^1$o`@Vhip0RsU15B=5~FA~<{zhWD#g(|`n z_g>BT^4Yg>nqMmJlp4bKH%uwH?Z&7tRS|sSV-u{zg@|OhU+S6|nMw~xvKr^nEb)T4 zT5y9X*0}qHEXN<9a>fb+it06C%WaTvtvxl01zO-onsP7$N!sxjvQLHY(+7&`t=G^G zMjoSys$TEi*xtcQ*ve2lm7#*LN3SW$EM$&nXT5pSD-*5Eu7=>OmG6yh>wO#S&X7iJ zgWI#hw^io^Ao}@TCeWY04d3p7xJ&h(opw_n)~ZN@0d_SX4_J35@xEH5^gQ#;>hjfl ztsOx4AjPvNJgtQTGSMb0c0u5#=hH28tX+82aC`9MXZLH&)Z48q5kbr->bV!r9CAlgO zGpAJhD)>pX)@@RntnNh^jVS>TR!hM58kKG3pt)-2{-0eZe4a@^oOQ-r9eC>3v(&V@ zoJJ!4y3D>fLS|Pw?iuUib0^GuobHY$z^S3jWDU0CSs%{KY(~#BZ*q{)xXotOn20Yw zlKe=PG3k*#oZ!0RX!cLaVuaw?S~PVo-Pi0kD#l-ou6IR& z@K)hu-igMKYa7Xjum!25=ukjp45zy~$G`{9nazbrkMe&4vJ!gE0+?l{xqv}TrCDW^ z$DQIN4;%WXc_`QV`F}AVVP&{;v#|k#ohH$fUlGH*ZPKy#4vzSwR|*RbX!dC%QZF3T zZiT3RA@1;)C^0x5i@+qu1L5mZAE@fEro}1z`VgGzU*^jr^Vz+Bc|Cro17B%KzTX&g zT(A?>UxP&MWW#)RwkYw{ID^%YkJ|!3uXJHclTC4ytLN)kTc0FfD!K4rrol>t4E4%( z<5Y?qOYyXk(1dyJ!8>=E{ofa<=&H|+DyLgepheFPy#-Low@z)>JV~@xQjwzCcIaJW z669MLBY;SJz!~X4{|q71$4lZn#XK$i(LlgUI;b+?RcH;mc2D`-gCvqXh zZ6=+R6gPX($Ug1O^-_tGX;as;bYK9n%OHYG1j$gZZa2g4RtBl{8dnTwpP~KsZUuaO zLtc$!bYA&pC1+ewEf1R0b5BlBVMKdF0LB>xzm`prmjz;^^xxC^+EWxSyDO4%F1&}@ zRmIol))KnIPvNaPMDM3*!w1)gnfXdxX0?MwPus7UHj%#5{;15Foh$FOu8XV~e^b@+ zDRr9ts_Xs%O^-G4WAmO$qpWA4e!BDB#L~R#6VSh`E-JCG`s2W%5L^U*(y1ET3uGV{+Sx@>XM#dclA4R4Od~Ll83C!juoXkFl!iO)YjqM(L|~r zsrFrE!(PKYuJ@_*a?uf((RagReL%iwx*4D$3%8pMshNz65r7a|%wQ_p`zT8i=#r+2 zo;pP(R)t>vt(1HY(8Gze!8Mh#Vd4;df;oEduGB|y*7u<{l;vI({oSDA@Z|~-;d~fE z7k-cbT+H6LG5C}7l^B_G@VEjwDWpm2elRfO>6+$+-}Qu&l$fHK1^S+htOC!bHOgM* zMDYPv+`T?$#+c7%0<-MY%0SC^3^PtXZ;ly%?FYeU0bbwSI+K>XD$4G`Tz#)v$En&k z2Kw8=Wak%t^NzC;?tP|TN6RnZB2y)A?Sfx_sJF5zdG`jDLR=tQzh6=&E*xq;y!QOz z2gu|}k#X@Y^(cD*dL8A1>tY)Mx-Pau7NIvl`&!M6@`6**bNw#$EJ7!RKR{wQdVe0h zc^#7Tb!V$}DuEw!;Xs(})II!kP-E}UQ_?pZoo>rYQew=8q~*;GINU+qt&X-3Z}e$m zN^^RyJ~5_oc+N=Y=zs5q_}zJo>Iw~w)FruL+52oSNW!iCNY_A7$QCeu%Qi;f6qcbkOk{p%D3GIls`sCMWv5ckeObKAocN!OKs)1x>*fOvc2wZs|nXL)0lcqa$D* zzyn(E3tIY4&oLi+lXVfl|D;bi%%EET1R^(@ptnbQji6IW-?XEcPMl6IsXf%ES;Q}G z!c=>%fc{b>d|YC8Fxwa_ULfgWpDSBr0pVxX6WRLZPsVg$M1H}?Vp(c7lOE)D*6X*W z7LfCTJV0wSnVPXME0avGjyx~ru`mK_UelUR(!2aFljn-!({VEokcTInKP+i~K-kO& zwkiz#4qj_I!RUdiK;aJi?kJK{?d-$Euo~~ zzlTo1Gb*i4xp2^&w7463b%&}Rjz1-E-L&po{WdL9h@!;^nbHUOHGDwi#j`;91OTpz zqTES!>TQYw(8amN2Y8=pf%f!80l@yy;@g(UZHcauPfwkhqsQIFpM91a&BiC}i!2D= zU~#waTT<8+pNQ%xWJ7f1tkyh2Pbs86zCT}zx?TQy?qm%7uHf`ptYLvXVAvTfWYDY# zvOv@0V&@E66;3d$_&F6yd`Xzx8mca)eTcJs6~ZEWlnd7_SoOx*7{%k+PtNy(xW6pm z%rv96o;K)CG;suk$C0{HXc{=|7<}g4nV~V5W)8$Q?~cC{_E8 zan+CMh1%;>un#cy4nHtSl28Y z3CuT{DvEX0jp8=)Ci_W65v(_^kTV5{;O;=xw`k0HN0);Tqx+)9(eLD_G6#bU%nHkY z1AkvK;;z2D0sCaaKEHPt)qZFAFzi3liz%XEt!8{Uj6%tZkc)bU6bvvl?){Ur+HQgQ zE608g%#v1Qb_Z+Lw|g)Lsq{x#p#j2=bAj0T6va4|qUOj~3nm zXiZZ_Zdeu{oL+Q#fzPfYp4cSclJ!6O+>d0PzFR~tjt(WiQGw%0JSmXSeFFa_EB&`N zl<6jR2^_ql8aQ1o@O<`4`7Pcwuky}6aUt$4vd*CQo$`nX07#g^xoAHB}%JH69A1r~qf=Mso& zjuPMVDMqT#v`ku36-X8(eNmpbAPl+PqckS~7=hf9zldXZzKbx6Sns+4l734~{(}Hm zcGIGdpzc#`AKOdM+~9xJ7HdTk#TGUU^ZUV(2_MD#d=R{y=iu-YpgF%h_p-^)juSC92@kzPu?%U}9CsnSy3MLN{@ z;ayufmncBU;0DH`KLm%nlLZU_CF(iqFtDoyqy2!(>(KVPxhX`524a6X2VxB&MxZCHTpL>N zY|Pp&3Xk>=+JG5l`L~RV0<7|;<$;O6K!eRph))M{QR?$=z+k7QWn?(`ljJ<4uW|DN zzYXu74&{DTWa9H;7Pl7v%(Cd+(z`?i@9}i7vK+2EC~UqDpVxdA7AIK0E2lfwTt^|x zR5mm_{pt>t^s=X;a`axQG4quj=V{ao>*>Js%)8jhv5{apenR!=B(=ncZ3kh0ub#9u zdQFUm=^9&!5yd`f8!c^E%^Gq9MHXdcs zX^F)2i7@@7dYQ6+_-+Qqjpt@+Y&W6%AFXp3FEIYTKhQ$+z0YmRFeM+*2+QN&kL6vJ z9Z2=S31&l8OEX+FxeonvP8XQD^L*i|bF;qXT+*3;eQzs->E7K2dn0Y#962zYg~wg# z@1+h@^HJVZA^4;F?0vUmK+e5(JW>*cywK6?zkZpbuZGjAJZ{+gvL~$EwrP5lsr1!L z_eHD5G}H&PAh0}Q=&}5eg`y;mU~--M!|KW;L&2lhfkz8R5?VP& zlk4}J=T48$oxhRJw-3333a$CsVoL-z86F1LF;JlYnPfi~m6HwndvQ8Bf<_c&du^44 z97JVzQF(3`aY`&UIKnh<(y@i_(&a<)8=K55#z}7NNQU4hvJOcc@RACyZaDGByX{>H zYb_W8DEyXW?Yyw5s9QdFFf?^MTEdX+zjJc_K>Hb7iO2+ z!3EIXE(HUulk+zZ+|%SU{HI~E^SU@^qX#r;eF{;?lf}mVL5u0ui6Hjq=7|hF>5M*w z_H1{Io9gl)t)_6ZRnkKwh3_5vVC>Y(FrYNQx$pigfw5m_7P)w0*F*u z7eR(tzg_i~g5ETjbooG>F$;gM7uTF-v%31n^uy%xU|Fg5lFI|SK`L$alI-$ZqoZLf zzp}gR!!C9zvx7?6LOBB~@@eMnJc&OY>2j4*hAVZr(Q_^drZ~EI8~t#B!9vUHB#mDM z8M}^PCYx{YTEBAc35P}={Cp&EIOVZbNmPgUtHHJgH*I|gAA!l~5n}F>CZJwC;9D)nXWthpIA89TkRz1@`M8dJ)A;$lwsINx5GgUpkTzG zx+JtaiC9IOS;%}(pTfk7gUq~5^KkBgpEtNA3OcL?szXd+)+`EfoQ84PA%D`6kvHw3 ztGJ~OA^u-JX5_lK5h>7Qp*xM>#V35j~0xc1Urhs!;2S~*H7_=Tpae9z>{R5mzo zcr&fu+-3`{W}MBKDU*;tlQ*G`N-#l}zp5rEI0QK)<__{#aO=#8XEspGgoU~tHPO0p z2Kdr-@_@}jFAR6LeG5s~S8WJzW0_uC*teJqlu7R@>g_r{3o9aHC4^Lkyy7nR1sBR= z8*UFFy*t6c_$K??DuW7|hF1sWyk&MT8tF7(3~oiBpXY6rB_hTzoZ3~%Buv3v)e5eD zL8M{}qV?xe3Guie91ZXwR`~sQtLxQ-0-yq-JN;doP4Nhq(&%Vo$=l2{ zr0Zq(z&BY4hrdsJg6@A{M%)A6F(veD;(;Mt?LGsqCV}r&Ma3%)TOG-v{6DHpUA4kz z@*bTStB+=HY18Wu;*)<)rU}!K?2&5kNQyai(R@zK3;2^bqP8RHN1=$LS?Bi{DySm= zY|Fr9OR|oYAo`QFC$WMfH7P1CgSNC6FMNBi#1#g88faPy z$Qb-wDAurWOX`hdfBGHoMI;WF%e}hDq+hT7O&jo|bu;rUcK$(l3pwl65(AB=s zqM46{4MU)DMMyB){4=W>qR6owT_#acx1Rks+}JOH^sET)P8Qf{Ge2h@tp6t&?^bc}Cxv!UTcQ1OwGU3aie+lrXr(6SADIo9 zQN{g8M~aLM^4fLN@zz&ai4|z~Cr^MN+c|jH>co>@?~?cLaJd=ZAWYrjr6N8q$dw=s zTuZbG?NH{G>Y>->*k?!f;Z(DBuQ(9^}&%z~tVO0(yo#|_$Bde6J~xUX|GmL?x!t1x<=(MxBV zak8@ea`GI$(EZO!`3hO*@V#0~Y5L?flKc5jeSY7`~I=W6Su-t>O6lW%*P|Qam_pi~h41OkjS$hXstP?@0GE96Z!Ex z2fCG7n5g%H>=Nidby@9nrO^-iuy9qHBaYkbz}Y;3_POuIqlc9SpqR!3Yi;+? zZH+GxTh)@v*>0yDDR~-1;2O`a=WqFJlNDaICZ&fNr!6rpQy1c?Fqk91fXxAW6H%^i z<0M!NB2&vHE$+ZD&hmmBN~qjW6B#8x1CoN#DZ)}g-e)0BPhAYme*OGo=?m%JDD*bq zX!!Lc3FxKO0}mQvN@UZZf0;ul&;5yUxa$nr>juRrRpalImlMBppgJZj@TW)kNWl0qPe%~8o$uHfOm=fA19e@BanE`+jnWF`phiaf%EFF5n zl`0Eo!8*EvGodsK8`elKkoqarJ)hqROYdv9>5z=Tm`Tk{#NxZs$?u=kJ+q5WhJVBs zZ`?N&vA4Zn9+SbA4<4mjXpzSyah@q4W2PP7@6|T;%RS|3hb75uj6?Z_2D6UI56eJn&JR>mB0Bl_VJ7ayWk!kAUYjzDxQ?cHR*SkAQZ4 z+l@xJ!S!*S|(k=&;q~xnrK4 zKJH03efKezEnJP{jj$ZAbp&KSj18+qd2typK9u6}ZN2TQ)#*|8)JE09+#;s=zd&cl z{ZO#iM?MR+_1@yZ9-te{38%o;LhoY{HQ8-;+(HsOJOFli7tJ>LVU}*tR`d*|T#ni* zlU3BaU03u_qgXqOH(uN2Q!J6k+23|n`qMVQ&;^$+nnm}O8*wh=%puxKg@GvpA$7JK z80t8SVd`W!xpdm~?o}$mUI*(a(yljZ2cByyr6t^kNg7$?K`r1WkBI|?NZ(Koqr~76 z?v>;O1pT&@6Y)PmnH!7y(jC96r~DGyO9@=5NqrK5t8MkBuV_&<|F&44dIzUqKpDy+ zeafOtko~*XeBIxMz#~@Fc$ErQc`(G`LHyYFIHyK79@Al|;j5gEF8q%Pa?yz6Fs2(H zc<_xcyZw`3<|K~Y1JNV3q>v!IrmFE8^P=Ky8hOd#Vck>CNT`I9nU*cApt^~6v_SS_ zGA^;{INrP(s`hDe>g#LTe8{{l=6nN6KZt-kuS&%@;`49~b|E-{{m|ozi?w!zUlH~r zC>0pvzIp3|QULvrq^VFKG5RndsRP0JFtCf?Ff1W!05a_hYn0mphF8qF_{6`KO2FG7ObB z>E4lt6ZK-m=jZb9G9kFRV)an%-Y%5cmS+V$CdS0w z2}j}wQ@C|#;b=02V?udbUyKxK0xW_QYEAFt5qi;vuNTh4YZ@_;e9$C>MG$8G`BvvI zo;l`l_<{4~vjxA6ouoVUo1VEnivhNIb=)v=gj>b_pK5v_d(+-0`tcn1%*wqv-VtAH zy7VTQND}YF2zR(FEE7!QY^ONfC$uQT{N(B=yZM#cA<>yMpS&Q=9z-1KKtw2`0g<5@ zeA$X-*R;M+xvluhDlnvt-YD&ew1Pkk$DaljlR-52Hl)Jty*s*b&i%VVanwTS&Y%z# zMxhG0y`3fNRnrHXUToB;(MWB9c^iTuyS6?B-pK8^nCfHMJ3S2*Cah|d+mg{uoxC<} zUHBCagRq5B)(4zj}>9Y23p@DVe2R; z2Yb1bGr%{v#Dw?$^GTfH7a^dprO-D0h<|#~yb+ry_J)x={2bsM*jg%|^*qvIJHCK_ zK)@$vf83tKe^oX8XB%-p(pxbq`pCcCOIMx(V_Yq6`xV3pyz8s|#}qAZ{AnKfFlfd*#ql;rvS!Peb19 z|C{gkK$AX#A)7n%A|eu6sR1C)5)Jw1*zrCT5P!+fWG~iPY4`W&P41OL_pK1~cM>Xw z5-N9#w#eE&ud*D2P=}r@(h1~V7lqun6`u8UKC{TCBM$238rV&MaY21vBW-xC!y)r6 zyb{9^W&IP}gBMAW&?M!2xgGI)91lHT2IBW7hAzL|iF_Qgn9??1r=G+;{Z}8z20k}< zMQ)lvm>B$a;{;eSN(>IRls`%(Bn_~CYWiFmNw?o3+%YQDYvqF*%>7-z)iwJ=>iE{? z?)BXNjFnOOb~;U|3KZ08^V87x1cB1nC+hECr}d)K%{hy!5?}_Tj#}AMSuH?W_TKT% zcb+hX5HQXYi0z8k)QjG_+1BCk2M-;b!UeDLl`0ywNfv@@^Zk(P19~^5>;~~pn2@mI z(N|z87;wV5mPEb_FW%Nvl9mp-?SMenFaFsIDWMANjWznD?)?+URXp--?`^ zG?esC(s0}iukf%wUaZSBUGSa^^7;3 z4auE)rg)jXI?%42`z&7}b{`pz8_m|o`i>R6qTs==d}<=~8a1H)U3vn9OJGY#Oi6AQ z39A%YHeo*r#g{d%F8dVI*}A~}WLRCXmVj#MW>b0EBGv6&C~>=);Z1=Cq9zjL^4Nr^ z{ZLfYsfK{So%dHxStlwH=5@_0T2580$k334;=~DiW6x;z_tJP{s6&>HJXj7w`uAY* z@b}!|r@yjlh2mjhnHN<`bjx0 zhTw#|W-q@LIvmB@sx;_bVCszODXZ|l%Lscks+S^s)K^UQK$6@YQ`mxg-XTOkgYRWl zQ9c*R1nQXPtVrl}b*~O91rfCi)}JqZ{&#hQ?4+?X_w~<5y(EL`-A%?Oq_FT6W0l;0 zPi)t1#(!5Hy(6CQ{PZQ0BjL!=#Qs-z&||i!z9jQM!XKK4y4q{?b+Py3wF8ij(QV(wjuF@(xzBHah+WCl!c>QU{& z5z)frq}N=ZIxJ81rtyb0_|v4Xw{`zLVT*|m2)n`UZQV!?z5gck4vm~*8XsenYK^a) z(B^A85ZKRDjqT4huTkMyHC}TGNKGL--Sp>J1x!QErpM8$&BQ(DsT$wD;f;wTvX+rM z!(PoSo!&<@cW)QPOfmgE@TwWbF1qlM6pNmF3d=MVw2pQlg(6PuR zEvWp55ILz!f>dW#OuvMW#_s+;@t;mFX-3k!2EU5kSq5$>5rm-s>hL^MK$6$_9WpsR z3`){#A#GlN{8*>tq1QF$jQhx-tPOy7FWx+T3 zw3*p8$yAkbz}tajQ={y9*G7L(c&sDCXOu^BAR0Qo*Mycz0I4S zrmFhtQN!hLRoA<71yAYu{+Y65u*3rG&$qX9e_q(URakt9`q5S6zggLG3oS{@cHY}R>8R%E zUvWNZnr{2gIS8c)oq2TTFm%op$5LSr5(Zs9`tJmflhD6^L_9Ug^dxZPXw*^JEQi># zhbz;gn~J^5<5oH*WG{~379D%x*;tlJ0vIha4cPGnp6ef1&%C`I^W@a#XH3+|TxpLa z{QEC1+IUwYOwYWUT0pw5Tex9$$fuPp1xjzcw*p^x#zc%LNwNjeh33zYsSr9fTCkCF zk){FohZ<|>PFM2))8`5e;C4_#A<)K<{jV`KToINWopEs|q^5H~T+1Z6PY%m0$f#&3 z>AjQ+-CuqPlxU}g4Nns`2V8Nf1gSN*nJK$=${t*G1l+yV*OjryV9)g9T^z^c+^6Sh zH;Bz?anJS#9^_ckR;~P3)Jq#AZy<3sJSaTM*xvW%k%)v&cCaDu=C<#5x44(=ox8NX z9fmLO23{zfbPWlJ{py*uRr84dF|2`fHJqus3=){1>(w@430=}~^EIr-pRU@V+&&uB zIr%Kr6h!P1WpRzuX2_oWrclJVil60m_EZQEeq_FBzx`2&Gs?{sSFxiS#Bp-=|6Z{a zZReWzV#;qmL0+9H5~6p3x7@)+gQKeB?yIv>Cu@Oj>WkT9u@VaLCjV^a#F?A)2?&Je z6Vyj+s6LF*GNK=AfhM7YciDFB9IpHnfkbTuTeMhIf`#HvQl7B@3dLM;%stTRe$~N+ z>chI-)Z=HU8eo~FzC0^u?&a!scXN_#ZY}E~3l(wiL#650bzf8dK;iZIz&=YJjJIY{ zhP{DzfmlOAGOt+X1n$sfGyPkvV)mL4VRH1R^al|d6Z~y>Cl@==#Q#>rb;7;nrjp`L zrMgIp)j1Kx%8APFhVOx<7URo<`X5dv?zBTExnH&j&0bdsbs>`t+R)ZM{NV=?8;rM+ zJEq=!xc25B_m z2o6gG#+P51R0%%0J4<^Te~SRJI*JNqGu~$0VD0Of+Dl)?Sg2$?GD(0~fDH`1{sVC6C-aq3h3?EL&UF@4|wR`Q!7_(Lq+`n)8 zf$Pt={}Ulj-@?Aob@ob9W;CyKwTUp7!jw!c*H_;cQZy%$x`aLmA6!-d@-jB+P?U%s zA8nYH9r%SU$j+F_m5_e%R@ej0me)`+I~cUa|@lfoz^V!Nch7H$iD! z<-Oyh52S;Sf8*&N125?f$vv08(LPk>IkL52ziQ5SB}-wnH#)+EAo}#Rl#ABn+%0Q22u3gjO~Opb?~l>*YkL-wtx6)Arbs%K~?0~T&!lY=|_?zk|0p@m}T(yV)J zJTwJZ!5!iX&Oul=L-OXHf9iM_o+E^`{_VS*?8$tI@cngGX3RoYQ#MWqyow{tc>Kne zlBR$xJS`L?4!ZLYNO=6bAnotw5X+Fp7sJQ>mgEJs{Q+|P=|QIr6S-&N_vZ3n$ zwXNOZ!(P3BW`qJMU>7Q-u_XNILyhhc$y^x9-K#9@!o$ccbokMQ35Bd;-=yt3Z~y6J zR3>Eg;D&FvbcX!Po_f|BE6Xk_P;8Y}fOr5aa^BEm(?xYnx>p^sd5*$ls=#x#E=YzqAL2fUf|H$?728#O^&)_#OQ$ z`)_6PE%8X3IW_Ai@oa;vpKVy{Efa>G*G6C3@YO-EuZ~dkinv(da>PQrl}dYgIY;!~ zQdOsAs{g}uI0?Tuv`Bj7@Ws~A4pL%=eJ{TC#U;1Pbj;MF)vYGfAmOR0tA7#cAcSpf zQTxeSD+2Cv)Dm)mWZFl%ACfkboTqm*u)ilhH5Sb&d%ks&d>C9PU9b}L3FGs5VpzFD zta-cEl$C9CSPRfKLVia_KKpQ&TIJW`hLZpZi881ZFl7 zZ9dbfB2EJx)xFPib~}Els(X|TI#C75&1_9nY`_r|w`$D^Z(eDyvi>GcxkEs3`ed-g zR~5hs+wY>_+eG0!Iv2i2_9AQMohgc$_s0Jei?77u zYv!N?Eb_gj#=|RF?Wf*Pzv&l|ZYDcxnK*SET;2D*1uKDj0{Ov~ z??OmP5x^P_&asKsvhiHrv^gP71^uA$D0-ww2rK%XQPMw}sCqJfC9V&LS6xgzg}de9 z3o=M}Vq`5EEg(R-AvyhSSpo1vd;vN5_xr~k9S8-w&b3(c;@xZmPfQsp8 z;Q0&)aMdp&!2PqQzyECT?R>2ir>Y#axH}zt4?+<3*3?)xB>B%KPyt4Xzm9B!#9;(u zBc;w#$q-VSykFfO%HzYRXd|%3XcRNkKJ}1c{e|w2-^mj~Gv`}mMn~o@OepsAQ`WaU zHUwC0j+(q&=P8vMviTRevKy6ufVVrtkw2goOME|QG^v8VR`9vf@-H%&;nm^6ln{S; zt~)JBN3}4!v()l1nlT<(Z>kW`u3i2P@$q8NCf_2~P7V<70baj0yfytZCk+v%nC<>x zI^G}=Il2b#Pk-{YX6k*JgLMYfkB27nBB~H~Qvy#VabdV7-fW|;6I#c|Ia2$*OCcWV z=g@^p0?q}d#ujBb@QL3-811XUfOr3s`Y7aU%^T)#`^^{~h!b0WaENxenVEC%pZkQR!@2pvH?YV~`y@0;YK(oTSihFtYW7%Ij>GS7O zS!ds(OH!|cIh{64s7NQQ;}<)Em>guYy7wH6R(1Jo-`&2ah5kvuDAY2M5}Y^w=N`#F zuxtJ0QDw#Zsf!Ve0I9Mnkki&D54*ES#GJ!>XMH{qmU1q_`w9p|t&E$YocXq|g>1?79aVvjZky>U=)$QpK`Avh z#ujBDOX32x?(J>|NRT_tJ+K%LdM19W@_dkf&aJx`{~Se{(1k{1MIWrW1H@;(MZrV! z_)82qT_N(<0DL!&SC{6%W(0R(O-@2>^zhOBpnq<6(-tPZX_k?2E|E4vH51=IK&p>B zI1xEs`8bR0@UlAr&SZmQKIPcVrR~qXgz%w9pTD+==%tfp<#ugsJ_t_sg)EpWbp-gT z5ZGQGo-^ylS*zHhKXXQgJ+noZP$#h*=aC^;U;`SdSp>MySVMec-ss9NMiLwWobM9z z(*DNp^1Oz@QHKQ-ox}ybRN|vk128ilqJ_W9PrY_KpZBfZ^JL&al5}B`N}N%NDug&t ze1bq|Xax~BNJ1q*7@(9gN!KS$dQ6NU|F8wm#&09>>6KbGun(W)`M@7J?)NRmTg?Gb zI7iK3lr0-GF#)+)HrWE4EavifrX7U=1e~AFOSJLx^YT4Co&F}XByx|`SR`t-$QUmR z=$+TdbDd=J&mDswt1Fu#m&>G<1bP3IZPDh*T}Gdk`UN`Pz#J*(%OqEBTH0kA!>=YUHa>}jHxPLx zCV)4pVlv%2qlUM33n?pl7)-%ZUMC`&qWAmVZmX*LlXw>RMtOg89*P}r4Yk<~F-;c< zi;2eS4<25a&@1TdW-yUA@0MhyZkCUvG_HKg)?zP0WnQtq%|nHq{Q5Wd7zA5g-l-`t zRRCf`Ey?nSsiP^@8x>Cm^BsL(klLB&yT*pQp51&>IgHTUo{4AXQA#T_EW>LXK-9ZWrP|O&R#|3@E>qqfO58a09P&x`N9I*J z0C~fP(>63o4x^CK4{MKEoii}rpLZ(qP33?Etdgt;u}#!=GRZvanU`9GpvBRAZWfwv zdmlWDdZ-Lqn!EAgglW8&>CP1`Kt0SIDH}RSimT9)16&K@CWyARZ}w}}{t|utQJA)S zlSR74-URJ@R9NT~Gja1)g)ocnGbaiBx%&d?L=*|0*IJ-^CGTd%fxp(@yRpiBkFO&W z7w};%Y1xviw?fia%}HYSw4H3R`?rXR8zjl{R+?Szy6}Vx)1YmsEq|FyCosdyqIa+0 z`=}M5Dzk8X!Pi}E1_IUs1Fi%~zQajUAKS~%mtm(_4ZSm7U%UI@#!-(4E=#lEIWXS? zsdxEdO38uJ#PlPY3c@{;PElbvxnv3fp6koFLwYB|cl^iRO$wHODRD`zPmhTACCTLS3ZrZO~XilvU(AYD6^^#P>a6kV|9@#aqLdiB&>heMozr( z-b^ij1gHYn#fB)X2TFeopn!Vx8&92lk-8g0790uz1Uew!(a2~>;x;GX$6kv4D65o> zBSL=8P8(XL6l9YWj<98CZmj5B@s-vQ6zwVu3=mu#d zq#G$IVUUn+q$DJyyF@?+RJuV*5L8+kK{}*E8fl~(3F(^eBEH{mE&p?^;oj$-+?y7Yuhtk7eC-Mi6sT}6R#oXa{_9g(zKIO5B4g8e6O5z zYLMP2LrR8}7fw5she<`bB{r{ifTup^L$Gc}YE@AjF8k}wC_}y|`C;AbaakYZdfOUOSsg zSo10JG-+$%a&3M}FX+8Fk5kZ_?$jT%Hyoqb;sR~P4M!p3^}K#aVfO7DPDSTcwaB!MN&B7+GQ zGM`ggi`O6Y6BL4Z?@7qK<^E^N!;(hQE^*hR{*7+`Y@2&W$D=Yl;elOx8LjgVHW@@g zY?=J>$|E3e<9gIW;BixRL?ni15@@kMV2aY-6e4EdKJ4!ZSTBgjtiGynVl2H2@u)GX zUhCe*)g>i#pKg_U%0W8rxw~q|xMv3a3cR?_(D+#ePAepsd_M5hZRL-NuEp=F>8ZuFEpYk5J z<|LFuB@0!X3E*nDQQuB`K;I_{W1sj|x5LcDL<;=~PEWtS%|tjyFW?S&lx2N<#10J8 zwR0ayxgAK^fW!Zjis>QO z1J+bF=NXk6gR|E`q%5k0&ykP0QiON9?)YAN5KdqnKQ7YpV){OH6Phz0z?7c=F#o$^ zj_=8NE!+Gwvf;vNhdDZ6Y5h_fROi$}HIruEqBnNqm5Oe?_ju`K&}I;?h`0~LvDa{a zHDu8%p)bE2?A-8IdG7Rb7(VI`vgTokC=o5*Ru#JDA1fJ2mYeoccqXiL6Dr!32er4} z?821EW-R!p*SpPsXh+SXGKeRLF6>MFL~#h_*8%vG=g^wti&RXkJSl#bez;Z;9mUs} zh-807ZZ%Z6B8)=k0ef%2jPJK7@%rM)%lEhj7YoEX>Gh7DnB>F{B1#tW>+27(VV4)r zG7f122b%ir{_-MlXbOYrDk>{Nt zZDRH1O&@>>Z~`|wqS49{Eq)u_<81K(i3ag!+@`wYKeA14(W~h1HIl~3&z%_es&*zh z9^&7vSUy5}!?`cB82uP{PnNs=573CgP6&MCyUc_B^2=>@QF@;Gi8S7NN!Hx%+QY{2 z?$x4hHO2$s?=SA;R@po1#=VLnZdLs%YXo^-{2;4*S;-qfXYn_RgYq%vkKuq{TL!F1 z($_6copjPJC9i7(Mv$qTEvR%em%&o-6R3+agWdP=`#V>#vxz`J-C(`d}5{;XtgkXD0VU|`-POB*C`#5mK zXI*}v6#2-|q4SNoJV;s;cl4pBD9;EPwkGvNagstT!Sp096bCwi+k;skP0L(MF+z-d z>+^xr?9c8`Lo81TRU*c&Hv(g6bJm9YjGI*5y&3{~Bs4r>33!Jj#xkU*U&S)>|!zTEH~L{D=Hm9>XJ zG86)-;KMkcQ!@az)Ab7^hh*qt&+3ZrUyXNGG zd{%>Y#gQUD&|pJg$MiR}g@{3Ppg3w%t_!)A6e(2^1N>aTBDY`_k0!J>`Fqmyt=hB4 z7CW^=22GC*Sa?2IgP~mh>#6AU3qgtk&eMaHCT+{(DxM=j>oJYD61sXfm704?jubNL zDSMX^2-JZYZ06F7k`L5_gQv^J7*mnzx^3Cn7CvO!&Octdu&*_t;Ta0^l+J9>JBguQ zVlMRBi7TFYUz*3cvpV9dhIYeBOMP@2x15a_n}6Vb@;PV*SZHSHtqnQeXdoT{0-X^uKGDcvd$GWNGwok8oqy zi{^jf7F=nu8ibh|NqP<^wqSFkL7RsCme>3T6vz3{OR*^dKYJKhO7 z$N@-4(uoQkm^K~{Hkp?QyIu-LoCK*_&bzwZhcDJZ992*XG8QTqE~*YNb(o5?Olarj}jyZP{t+KT=ZgUCI>;?kPp)W zxk$<*|J77GfsI;)C0I|(kOtKDQ_!bhidTCJX`m7;J23PzLsw^+8Mmr2`Y+=RzOUy! zb((VLo{cVnr`?LL(_}o&+M6t2BZ_CKN<;KtMMyV*a(*L6$`f*25QN#~;_6B*1)_s_j8^j*&lkMp3L>#YOO$Rt z=LRz`p94d&|rGO&BR}cDL>sS?393 z?9ruiK|=>??YTp$UJlFBPczj1He$Q*sDvu9v?@k`9pti{ne5p>hnj> zCW~^MCGm42MZePu`Kk3D33;$-NXoTK3Ow8jEpkCR8GsLAvIj(u)r#uFT8WR;_R_95O6RbNeRIx-ix<{6%3+p?cWGcX; zC)%osn)OERXKNtwL2Q%t^7;aArJdV3t6j$e)YgE9!x#$kCW@e@Wk3Cs2JcCN5@+_r7m!^pW6%Jk^&;<5Af!B5mfJWQLO=B6^xO)+|;&vUr)2 zewD!2szGB`bG+mirTny0rONLq!lSizw`MQC93-B&Xn$CLSsASoJfze&5r3C4#&HHUx2vzbBTCaxJOF8>3fffZ*y%Xd^ez4Unuq6 zj;OvORM)HYTJh8GBxH#|0S?&NhQFqtlK7HSqfSbZ-rt*@K^j}EfFh8uh?vT;?*6lR zlMiB4pv1Xc$q&ieTBn{L?Q$&sG^DQX=w5wcT4D$z-K|?3LurGQu3W11F7leoDJl&`yyvAt2${@H_k-OH;@pYy!$-y%i1 zumgE6G0&b@@Gynnj;KaTnrrtz-4=h_mcjS9`E~X#CFiRWQWLVp-*^#0Gv{ZH2ezm80qgI}3zW<3|DI@o=})9UdAvYM>5*O?XsH6@Tp5$zZL zS<8g_Q~JhzCmAw}0ZWTCieRF7#z5$C^m<#x$M}94f@9%7F!$N)#75%=HvaLa-k0w< zBE!&7y2MlaprGQ-{L{$-*|#v(OtoT$onJ&w*AbyjUuMU=Wf|_P-4l%e&>B$TAZ8(7#l@<6A(ZlA39UI4l6b`-3>%FAD#vnQ5T_9GaE{>|7g-v% zxl<$GGZ(~&zZ%UeJd;e%dC3o59croyPO(vJ*a22i4cc*^dB}b!C=Xw>9p6wQpy3CD zh970j)l)1p=Ma+B+NBpbV7zeqaq9l{aKHQgu zjGZPyR8yy(6*K)slfQ|59juYn#x8&rIrRoAEJJ>?JY3`Oy8YLYekUEZIpkzMS(?pUnTH5U$m>f#ir1 zIrCB!u}=S1=epH!nen$+0((G}W@RzqRZ8-T<-Ye!ODIN$4)T5tf*L!X22+m5i+1UW zPfm)HY$hwkO3(wrC}Me-hufaa6zpu;8pj3Z@GeBXhZZS#i}TxG$jiF}GS_6MkPSD} zI`n5~F{R-egw1*tnNPMm1Ggr6QI}JH(C^Sb*4M7~Ho7&{HDdLZidrbO6eq%*hs5F% z7C2O;+xYSO`B}!Qi9B5c>w8h1L=)*?xb5;qOO6qIb z5sz*n5aHoW?1M6g-;f~hwUu)-V_IkYey$HU?ey1GDZLvn^2Fsem`m@#+zXGQZGKxO zBby8ao+oLHw%Xk=BR8*LjF}LW39B~keVcJ7_R|ydk?kWaUrEfYU_|ZrJQ8rE!Nk#D zJt?RI?K3_6CG0Zr!=CSNR7BkMT89B$FaE~`upURAdM~Z6s(f%C>d3iTP#>-wJ;gN4 z;TCpXf3Y?6ecr!}keKT4Yo#z}{?Ygq!<5^k8^<#Ku;!X};&2`zqxL8tr|WRA%W)%=ZKt+=q$O_-hsU$eNVg}C zWj!y75_xK8OE@2_bPMVhD5(SM&*+slF$YoU+V4GyN1jc8m_d%dlY7g8WFz$$s3ql2 zc6~zkxs#gM(i;}eev2_dh(Z{^dYJmVugAU>Q}?slg2mB_vLFY7qn|E!$foZILU67! z>0QwSzUO9=Yhm|)Y!#X{`?NZ@wB?pPXAY6kZ*aWMc=~v+XbhAIIxq<$6?lTR!$I!aJj8z#+=2j+iPX5v_59RZU9$&f>i59$&w=h0sQ%mL; zvE6Y?=i#^jOsd2*ilEqlVz=xMkLb7Z3!@(*`*ioNnwA)jXsN$yfOD6xDG@u|?c;G` zna2!bR}rZ(xGF1_L}%}?CocK-Ok6twL)DvzpU;92QCcfHKrjXKh`4TE$Wo+X{DHoz zI}z=4;PQ3gh+V!^oqXs+FoA^#y|chw802)eYUdZl)*8oOa5ApB>2=)6HJ1^HmI=*3 zf|~roepFCRKUmw6(Xfv{MJS;xHgK59C(^Zc!mhTSsw}Z`9~?A6HW@XORMmA!QMM2K za|n1a<}%?IIW;jsn&zbvYB#;bvC*eQBo3*aLRZy8(8j8OdoGgdp1&yPcp?XRC<|4QaGZl9(7T^Lr+v58q3s9RWzk2mXPk~NiZ6*PO2j9tpFd=n!$K zu#ivU-Yv2B4mj4hqN-kC1Qp$oKMz8=K`Gx{*I!AxQ0*b~uc%1=|9Kl&a)H3+QleSL#VtoZPX zR_yItVlAX>K*~7dZT}X7a6Av5|L%Fc6NjU++Ri4cN5P{4bzw#rEl_Gg`e*hmK<-Y8 zTZbp^6r4Aurv7s*I64gI*)B=G9%>XntHEVFg0TGnkuGUmDqx%`|buJ4t4j&<= zt?^%MQ=ZNYD$F``xi+GU)$yrFye&RHBoy4k$e7tHJS+C%D2H>V-Po+qkntx!2hE;`t>~5O}tc@06=v@@0prG=6PK_gm}@z>(PZ;6uP59HKk0<6fW6@ zoxnMAiAVf$W|Q1wf{n;IqV^NzB9RbMI=(6*~aV2rp0rg ze0b_*d7Q{HW{F0!Rea}DN#xCH0k7;JIVN~%6mTutn8ycK8l5iRDIOR%*p5F%I$GxX zxrKG5`*y`OYACsW{A@ua_Cx5lev4^lhEn2Z0`152S>MuY^*nT_6` zSl+!4$Y^=a_v2Q+7-+21Dp^+l@e>_tvUO+nx5-+2xt#)43$j#rQ!*imuMatP7aaQr zdkpa3@T2BO@Md~g^+VT6I{tC0iObW)C%h<|j3MnL;}Qz*1T1r@-dJ_+l6srre+)p5 z;+j%mA+V0gUZHH|7yFtA=oKh6<@5`hywVLfbTN<*V#%T+s>&9wbz zIXP1{AcZ0xFgVr5zHI4?g#~a%U@=KN5>-ppy$x75cfF!!CIazf_9AZ!0hT61BC6j` zqGUmTo|Q~@oh#7ULX98Bysax1KP{wpYzQq=2aBi&T|3q+Cr zf5K6U07NQQ%>P>n2-wM<&x{X?Cf^$fSZl&91!g z)PR)wJlXfjwO#p{%IAgsT!dtKy-h`71bG_DCdf5>C8?>L7{tYia8(Dga;&y7{+6cz z=C*vMa7+?$3E4^?ewZd@DdPaiVO0HTX959&3PHnbTVJLRgC1t$m?}s>BpQi0TY+4p zQnYydC+0na2g^ZD27wptIh_fJ^Vj-&$Y4}>8ErW2C78HwaxEOHPZ!e~Rx^>2#L>js z`>YLRUDCqxW7K;E-f1GStK?9*518DdlNk~d*$S5DC6 z<-%rYCKeLOOZmeS|1E1>wUM7Mm*V1(@r8G})&NCTPxn z+^B3Ki^EqPP@oyXlma6B@;Nig1b9C>Yc87~8{qxgMtajSYbPt%2z~hDoprrMRoT{Y zlBh_>7HK7Ri;2i*^22gU?nLk$o~QBHReX5iXjR<%B?eB7xqkhK1aRbvsiDGkA;i%d zF<)IrC4TI(Q=sAwnIOqIZBTfCe8*%$y6Z!fcc34Ala>{s$$-7J?*(296oG%ms_?nvWAC6|n+)u&2W2PH z3wyr6A-w2XX`S-jEvD4zGQD;WgAulfNK~L4$fIE7QvHAu#&a9`vr-YM5+{+XmYbSV z{f$OK`jGEh!`fbH>AeC0%y`tGMo>Q;)6}mozLOCjjU6CjZ$KM%&O?RYeL&~b@&@a^ z!VgD$zQ{`xRuHvh94afiedcr))AB_+=KjNXpUR+J!TByVtXtyt#`kGp&IDODor1@x zB)~pF_bWpw)aF;+M|*B6%Vs4E2guEM;95A%<|S*GvQFe$qn_TpusXnt0?&~d=)cXo z_Vk%7*Ke=Wl#Se%C%%9rsJ9#&QOGfq(Ad9)kFAuJ++ECjt~Xzv$r$JHRtaO`;FbBhr)GRJt6i&;EQJhvU0aeuk=cJ;wbOuLHWhFvtbtG(XMIh@1cMRFoIDF?@&j?Zv zo82;Uqzfs2rIw;T2~IHF;E5=N82F|F9L5>3PNzbOt~@frjtgAQt;bg5W8#WU03ZO`tO>`i15%BEP*aPy}V}Xn5+~+XOd( z9xy~)1V{ApMjKb}C>U`G?w1r{O>~l+5fX(E1{}j3Uz%|OPiTA=$KEdSFE$e z0(+UaY&1@qmacWO<5B6gul6i z_SJ(_XlcNRe@==*%pTF)Xk=N?JkNQWlVg3%UR2rHtp_m0>h=Dcab#;U75FpOX^-ylY@1 zX07`RHZl%kLT%}-7M4wxAj%)yvcQBxov=3g-Yby1gpdr{_{ArV*(?r>JQv975XS z1C%*@B^czV1AB{>E?p}Fw(k6S#YFcr8O50T!_|VK%1g(3GyzBPw<lw z5Z4B6kn1!(KUg0SZ7mbiZMo8sIz(=UIXwlck-K=FKZlLK3AimXG?lFiKPP}kVf|-@ zDIl&zRR;9%3EOn{;Ft+>oiiu@?$1~>QJ}kqrRovab^)a?#)EarL$p?l8Lu^crXGO| zqb1>1hPF91-A>1Oz11)>e*+f;mctQ4JCCNnNSJJHwbLPH?+v`XeT_I})9na`$0l4o z`?_IflTSTa^b_qbw4k<-Ocvypx~+|GIU)ea_^!~b=1ar`moH*A`}3Bns48s4-`w`K zZoa)z#G&TUU=a($M%kf29zy=%yPW>r5*4T+=6YZ@W^a5>j<4ly%XHH# z(+7x~K@z~NINOzh%4rqt+{*@zK(ZE?nDSw~VJagJVbIYAh33j$IA(+DL;5rVQ-kOXAOAz4djTT?} z85$7)0>sMD9foB&CSFJ2xr6-3a$8p%DG*9X0xh-a|54eT*6i9ZA2F{vq|QI5jftvN z!fd87h-4%&v;21)wNgNQ-pcawwqXeBUV30ckU=ppo0sZw0|!PNU@c7*-NS2!a>}6m zR{k_kJtmkBgoN1#m)H$Ej6(BE?C6AY%(i%qjen!UMxpJU9Zecmk+-$ zs6taQG^(`6v=Mlp!VM*V!%UEE@DW79jLI#Y{@FNF=7yUfFu(An6#AlpHJ%Ks3oC~I z58K+P{Lr68LIR9gT>%b#OL_wQL|~J-Cl2Sv!=+W3Yje=KsGN$kFgPuD><`IdO-~4Dq8_z2$K!tBT zZ{<+17MV^af)=4F_D3|O=J?!S;$=!VfAF7Ohr`fv!A&fEy(>+&J(mt-VIE@zUS*KN zFqkO3xe&MP@sI!lw~ZB>pfHVz0%i?~0Yo-zzKD1m9ZyRM2_%4W2={2j2W9d<{tpOr zfYZIRMe=PL|DQ5{i{Kb;=vz>*?OjBtMRu1Jg}2jHQzZ$(KS)&})K*=@K#~~_U!i0P z1AiE-0TF43o(BuMS`SEp)5sHDXjWoB^Ens}qD*;;lZ1RpSvOF^^hI-WIkQPA>E#1Gd}u_S-Gi$ z07!4`_qz9t*D~8g|2YezS{X&w$JBiR^9Twjyti)^7F7F zyz`mI{TR_p5)?Tfl`qMYJhz_7P0*EsKscjR&&z+L#TF~xsfDNOxJMwObba%oaDK=s z?lv;Nd6RsOm8Xpkp)tHOQR(6(=*A4*jWF_V4QJ?ndHvvT%ypZ$iIn9U+GHO$9tN2> zzij!h^I$CXf{K=qqRI5v>%>h`(Fmz?&pbrYXb07_jBgRY&%T7GVgh#3m){qt{JV#s zbk}@w%z?Hr-lBcMTISz{gSd1M6)R#b8F*#wxsD;Gg`X-JJMZIX{~xl12?F-RQB!1i zn`6y|la_ie;hbj+zlku^E(PI-LE+Y3@0+KNr9cVs1>)yUbhSsak@?8Vg3n0W^_SvE zP~@!)paHfhndUAIcob~Ozq5OxrXIJ(Zo{Zf^GFV%i}fkUQ|aUxDk5H+%b~SSz%#{9 zkroTp8#eW98f_v7vCiSJth+U>L_d5HlCsm;c z%8X@R9I)yqM$Zf|mHpo{qu=bnw0JR<$iPFAt?n4?vl_T-s(!Z7h51IV`xQyBj5?GT z*L1l{OcO!^+-)J>ksZzIkZl$``Z83LnT-}wrD~iGt70$>Y?#k4<6G)xZ!A#yXwvgn zqWJ#-hDn{etGjF*i%$TT)^=h&2=deO!W*3Vsa2t){_ObU!A6fCH+CIYpx@YI)aJ%g zj}z%ltJydDku}|UxWBo5e;(sNDuKL(W&b10a!B9SyzeTPZ@|B9Ufwhs##udz%Rt<` z(2H8OU!i|6H0T(8=j_;+z}YSYf)EBiR=V;`HH&)P?CG4X*qjs-+%d@{MmT=0p4?2K z)^nM@f^ozFSZpfjd0~LWwg}(9=runNbJcq%=BEy&u54$kRQ0Xi78BMrrhf_Yp8_pC z`K4hrp6IqTsGtu$ zDyW>1vrr*^!v%48PCTLlf2T>A{bHqzB~nof>uTdSkI#Sg>nxoqJ=6SpXg#&)Mi)`S zcH?vyax}75A02Z$1#XBk2yTK$HHlPbDqZ8)M=@dq*UxZ&pL5cIY$H)55vcH9EJSVP zRowELs2uRRwDwN2J)m?VxQqRFdj2o*7Jx}NsOr)jHxw__xWY_7bXkvv4Z^iS zTVb#PR6Y>LQ2eSqGV{U>=MB=jC=Q41=D9@l&(ids7)R)n-+_#xGQzDXtUsl)q7`@X znE{-$M+O@ve1lG&e@9b61N+20f2i-e{)XXm=iP2Gy|ayOb~1#9`P$KmJe_#vnB4q~#qWz?(% znWg{4wP5KdOdcSe>yTfBYKD|x@yOC2`A%_cs(iN5PsICqIPLNqH1Pt%pr6PeB(6i6 zA{ecn?e5NhjLwyyy~HHYlS|E8(jd_^E@F#rwC>uB$l>UbUz=3R+;adJXPt zWddtjZ36UWFAubJxuU}V&{9y7%e|7tn`!bsaVyPygzGTtBx;GDkZ9&mMnT4hf3i!w z4_O5L+LZ8wd4={w)oye=`=YVWcjF$bDMEnP_q@~SxjpS)2ZLW?-pK@5qxJZFVF5rH zS{8}*rDfs<>E=PSQnL&W#F34dE=N4eg5E&7amVlnCLQEauRL+2Ar@Me+9 zf$CMY(%mvm@$J?hO|Rm5Djyy!O*1eNtoj*M&&Jej;p)Gfmo=c}`O6%FzphUY!a#D- zQ<{{TChCQd8jQZMb>g9c+@&&1-4*6zj!L(;kwxc>!g&3i0?~54}&NqznFl zIh_zp6aRb;EHhtXXj7Jgphj@CU=eVv8j}$M3LsY96hm~LG)rYW8t9qb;3m7@)pIj9U*W(NVh9ywVZRQ3x#1UO2bJezZYX zna4a)Bxt!(#`Eo3Jzhr-Mc``3eTm{tEBAlwB{v4Sl6qQk0XE_-+)l*kPB|!3#Yp}` z&AFv0-K9AcysscVKrX-1t};)&+#a#Gk2mvFRX+xbmTHog88$ToZkc+7Ay5z?e%|-a zuBk}Dp*`t&GbD{*s4V5y#O~9pQ?^kONC8Zp9;V7N-=BX?a98Chv^cLkU`PIjVEJ; zR>+${2FbeOSDI=XTuM=YffGyMpZIoK3BudVf|3VCo|qpiz`yu78YThlHWr6N0{5tNF5BDeq|{IS}g= zS@6vXM@{`=N<(ODCTHBTj&!fmSjiH3^q5;rJJVxb&)8?NcYC~e=FD7Y(;3_J3F4|Z zGUK*->_UV5xXvX7o>3#Z)*MV{i=(oJ=fEAK4#?rYjeW_lK)X~Hm_jY@PrTo5dN6s; z=pl$1_sua46biH9(hZ_H^5LJ29aS19?i8%qH6(PkZ2k`0Ru9!B124X|g~MRt$F(f+ zNq5Vz(e1<}|LT@NqXf5GKXK<`Y95L7)?MAXBeg?PQaxTrOBn3QnoSQ<-q>(zJeHG@ zXwFwbq<})4=m(lqG+1snxnP|gGq2&00#{Z<7`8$$3xCFQCE^vvR(#k*>ob|0lCD|Xj7 z{zZQ<#|He8Ii{{m?&U*0euxKi$IV?DZ0Yu=*zZ0xeJl+vWqb{$mF}1kIS#JmadH!? zNR&)M>ci(txZhfWB^iSeG-m6t#qsy@n0iUUwBwf7Iq%c(O0)m{{Gcp!At#*M&FD>k z!3Q;9OStY0j%BL@D)7om0S$r%Q4UH|=8&!^xfkeg2iOY6dYTYGq1PzzcalrlaR2n&QbfZ+i|7O=GH=LCc;yPFwZ9q%z9Oe;Xmcqr50 z6LN<7x15rDZFT~dr+G{zs#Ef8uZ=Z6rs)lpFWf$NI@7$MFDu}D+DZ*aO;AlKZo*0G4Tf#5vbPbL7FC36ie{k@fATDt@C z`w(ANlz+QSKvy+@&3IG-nMW+0(&8A_Q%wPwpmi{ap?W3k6ZCK!N`a>l7&bCJI+Ftq zgh=T@^vUDkw1;G`D->iMPR2eLt95(W|)oY>_fM-DBu8%yf-n)R-#0YBX z(%!(Ti2w8h%o`vbV8p7~9-SpyLcFB~6eNV1-Bq0SPR%Jj@2t9-!`Yga+q*R_p8h~#rDd&{a zRE6s7MuNWKvqbXV%Z?hcU;~40f5tFpxFfXO4AcHxXy95x+Li9Ld9ZgC#QD^Va4!V= z14`=(>h0ekQp_YdYbwLS2HH9o(vsEh=VVRR-mAd6mrZ~Fcj`w$Ma9~rP)Fwz@PEWC z1AcPx_$?_n#HtgPPl^$!$0I8rf0#M<)A@b*ScUyhpJy2g_jTysdVy{Q=9_k@n-us2 z@pQYnil0qQ1nSAd4dcBI>ypX2MxLi*A*wN+pWKjCCxvE5s&%km*3|&cJ#|V3rw&B{ z`#uQf8{$x!^MPNkEA)I&@$;|G4rqd($DkJm(*76YmI<1DC*IK1SK)jUCUXSjQONt> zb#K57Q^7z+%JH4Zdp(3p)nwY8pDVprUJ^`jd6|OqK{>PJX+7bQ>+jPrh}h+YE^1(h z?w_lOx(=jGX#Acg9f=ga%7eV%=DEH_o#@hG?wcbogd;tEKx6tP%5}TxGkv0lO?#ou za&+*-WpL96oi`sp*H1V?s2q|<1%L6!#VJAkS^4BN(I6(XvkvBb@3x?B;&1Pr%T7Ja zvRfr?4Eza(>69CX@Ks3*GDFMsNfu4rtIdfKp58!I0FVA6CVvBIwfnGsS-#k9!0?@Z zV}o?-MN8ixP6M%^Ky(7D#+{5q&w~ZUX-#$dL4;8blgQ%sWmQDlEDXqVrtPGF6 zdQea>1ouLjUFWlDOqP1TS*b13=02dhAexS7_P+Zrdm6&h{wNR6*X3;-lAsqaH zmrK*tXXugQUBT?}2KC=^qML=R0(3xi&3x#{F?cWF^ z^aBt}@wAZjZ{lp`C$y$(966zs!_a*Tcznnmkmb61>G)uPrlI6&k>vOf%~zJnyOe)Q zijkgcA8vJ9PSOQ%6RRiL8J*f;!Q&y|bR3Pu z;rY?bZ`X=C&(l}?SQp+I;JqoxRW4F(q|y?p3}8qVt#(0&q)~((0vMLxsOvS^Co-rs@n4E`c7`^N z#1x7AdI98-g4p3Ut zJPV}1#-*+xfDYn3jPkULGxDJX%m$GZpnaS4goL?T%%^@P6`cw(A1t%~&JATA=S2Hv zh_?(8hd5r=27Z+fDe=_5KCLnh&AdG*0+ zks;%h{`x;;@SYqU?>;hc78wNNW>-Ujx4q<*7#o}Q2lvv6I)-lo)~oju*NIF|WWVjw zBv4QgtO20lEp1@>a_y)h>N0e(cq+ipU0hNbawd%_#LV@!slY$DGK zzZ5oKH62B0F$jaFABTAUY4B4@=O|#>N|5p}F`g~S|1Q(cHnELa1N+b&<&6eHmIr^FNx;OgX z8$bF?2EXe9mT$lEdS9PVFDw355`3Zg@9VA$LsYJEgB(=?dLKcr7&F7KyL+n=qOxhR zqE0FviJ!z`3FQcm#?QiYW^4) z{oJ*VVf+u-mdR+|G$PY?dg?-m22NUC(GfHsF-GE;pGhfoa6f0%njbEsy&BwbD<>0E z`5N8Xdq+zS-E=RR%cgDvwV4+o;fbL(YXs$bAb)pb>>d24)l&wnb?YZU2h=_3Ve~ED zH>d-JEFuN3ey!H?KHkcCi^+nTxR|`-RPT(;uo+}2X(s-02b?CVy!>Rn!(^ho&c2A%k!kt%WIiEMXbrsfxw z{{ZKJ5JJ6%rO;~*>G>zQ20zyH^;Vw}zOFHv#Tam_n$DDTue}>h?R!CHbh#Df4*{>G z8khvRGB@K&6_zQLBM5?|s36@X z-OUV0Nh2kVh;%ndcZ1R;9n#&*yqAyP-@BH7x)yiteV!A0@3YS}ZhY?ll>pKtJTo?g z5Y@%b4$dDVn>^y*2^LbLz3CNkJKiNOER02Fzl%BgHJ0!QrK8SqJI^n%>no}MnGF2g z@nvC4y4Ku7&nisvw0!c)FKln}Px4zYgFX;i9GpIwexlj@w|@v#)ZZ;m#};?)+1j1e z_s@;>etednzCnHQ*z_uhsan8#O<3syMIjikge?kI{1$3Vh>{LH`m8`n;{Q9{F0g64 zXfYOR6m)1JL3C^Nx=8VLP$rrxg)-%GWDO~|e}rMY{8B6Q^jo&EIAUtx7*9j}TWX`g zCglhMjV{3MUwcaLCqax^wydvd+l})2aC=aHwAgcfG~UO^!(;k6G;EU|(o0MS!3Bq? z=qD#^G0HW8WQWa6w(2;!9{yUut^#T8Wv_FY(F||wGG-e4;N{0|NaUqhgV4svPC=JT zv*@AR|EiLJP(<$4A$74YJ zzllk=h0l|Uj-b8xnJJbpeFF&KpGCl8xq`Ir6^Czh_Z!up9mVn5@uvJ^#t0oCeynPG z$EL`;243jPMxdz6#^N`*HInV-qR*ya18J_vAjGLkk^IG$2mX<|6%I$Ue9$QxGGbs% zqY1;CoFu;sw%@1~$j~Yv$|i5rTJul3_%aOPS<30X*1PQ!f@-5MIJd1kqAFGn_q5^N zihfBcwUVF+7i9f}$y#&rDB#V(WY3NYTI=ddqf;+i9!@Hhn1ACI*@}Br)v9N5%hA*O z-9ZO0Z$Otc;13$Y(RsP3d6DmQPspWi_qT^F&t5P7(ZDlK|ne=yRe&zF| z29cL@CNc7bGE{witaty0G~g1ylNA{v7U0?}=>xBA3H3mAz8+YT{vj=$UlE>Q{<5Xg z67=Jxg@z)jcYTF|(WD4j1cjSu%6}#$G0dv^1STZktQ4knj;#E$ommrNYvj&Nv!6yd zBzAu>q?qZH9nqY>i*h#K*Y_|3PiH8tp|S`f{p1x`N=-~D3_;Zq37O#~@JrRt-lz)j z1A1TxN99rJL9IWaOGJ9(OowHK}B6PguPf+bFD_4NkTr(=Q;0z?L zQvM0yiDkvY>vEOhtryt2{9-VE1z+muDuxzx^mjm9JIh0KB5<=aaS0v73)70d=SZ_`HUt)p-P zZP&j4L+$S9Ge_1jVN47_oQaW64B_k*}{PjuK4>pK#w)xKG49fV*bbV1$86Kbbg- zY0KZ^@P^C?^XP`#k+!pz#x3bQviP;Er{UtHH_!7K*x$Y$;Bo!}oUN*PlnBM@>`|O+ zh}FoxMPkFj2SRaCq?)qrT?xBh6GQy-lGE>8zNgKHm%Nv=_{T&yyc<5b=^#IxZ$Cs! zfF;*`Pis<r~pK`x3bZ*BfhXDuXiK$!FO2a_2-HI*?36!$-bU{ zEp3aeVM(d3u%`smTl-~P{=hw54m>q#$1K3$1pq@%FywP~lfUJe{wKh?gH!6s8 zF6+{r_LIjch@>+En;wB_r}6OfRUX@B#w^(HY45M zPO4Q#kKECeFv+N4sWBXAS_Y+d_uF=dz0M!mdhI zU|KL>`l>3`oehTxv7mUD2*a1R=Gzm)+I7Jk3Ds5XODf$oIpt^sWuj-|FaY_4(eFAT z>hlNP{o7_1(*THS2;1lH2%G=h1ow$YJ=D=|IG@3b`rCtDG+Q?Jlz+@Gupe$Qmnp$q zSe-d}+#l_uWFDJVi%+}ILyikez4IiB%6Vt>KMmq zUBF)3FBC}fA}AQVtbZYd*mC32{*R*dVabdlF8#y9g#s2qC*V<}ppoxz4!7RSKf@C9 z@$!v2cx;W#KV0l9ZNHO@ZQqyV1j$noHQq7j*V0*8VfQ~n>#-KODb7-qNQ||9qao!^ zasZBsSt)g3H3$b$-0VCnnZJB5qi$QjqCTtAUss#H_iu80i_8zh^?KmMPv@>Sbg=0l zB&thtQ*$9}XjLKxF?_&V{i|$|gnNB`jr>^l_TY2IGM%wJ;>#3}2s#8l0#PEr_^N_; zr=Rhi<%E`!^wKiL@d7XXsMf&1tbngDE2*6FqyZtFXNKAhIhtUqaWqVa+VYS0Kmnm3q=12> z4o~xXJg|K0{Bz`IcaEi2{Y^OngUTe5T<7l_vHp37tf3 z{|!t69^hZo)J-l6Ij$W~gh;dRoU&_Zd8&?=Ft3L3Nv8kY)xPD!SU!l=?^D2M1F^lF zF&rg&{zyrZXuHT(eWG2-(4arTiJROM;*YSrRVJvmCEhHTR>%}M6f#4rN3p)zZ_$j+ zR5t!#aT7**e_s4}h*~#3YZKL9ACM;bjJ@cWw9ad#ZR@I;V8<@=i8Tnv&h{_VUWb{r-F?(y))T1i4_qHAguk{o|FE6fuY} zlet%y0K2~r2R}6ZrH}g^uL9SLDc02I2L>6_mW_iw$pj>u?*tSx7E0cA`eKrF=#9&i zxy4W`_pO~!irfvQKJ1A>BV_#}!ooBeSY-PE)1GAx98xY4@aOYkDbOx&U4`R5s-!3M zpEeg8SG*l1!3CEawgyE5t13Nsj0Z)v@id$E`X>GDUZ&2LJ464WmoSJ8H9W$l!ax=69Y-^R#K@tLe+;VES8gDQ}S{UbCczVwB>b_UWfSMX^Va zC!wi#7%SlD@|*_$I1Bf$mcP6{Yd%a`yad)CD}z4ilHa61c+pB=b-a`n7$+i^c=ag2 ziLa5^=+Di+8ud{Kf*q;AWXjiLF^}5jB*!ogMbco>E{^L$D3V=yIeYZ_`^rZ)O)hcc zA~fYdK%KwDGacL7TOaODC^2RYG8OCP&xt5RiN87Oq99Ras^>bR(RlzgTnhLAZqb_} z>KIfz{Qrym2ds!L6t>`N3FKzzV9SH1ubf;+0{p0hT`F)|W9uCpJ1LyYJNHR!Vr7>9 zA_sFOlmgP~P{!@|Z7d-b8Ki~xj1W41VFQR7JCk8^>u@|zii^dffx(^kn9z^Oif5ny zr|Fer2a_9>4@}W`pfYMq_M4K0O+&j_TsQ*q7xwBpg20`lk3zDwez{`&3&{8~&vSzmo1^2| zZWUfA1gG;l(1HKSz;;VC zK&}U^#f4nl%$GcB*4w#%ri1p1kahQ+)fsobR?XO zmAqM_9q%z~l31{k+|SU7Z9Xt5I_^A%kvL8L+0TMF^75Tkr|v1!T`{ryb}HZ#Z1mj? z9EIW-sD^i}(0z;P-qX*O@qQTaJ&IT_>{eAP63)w=h-zT|BzM!(1#f@QDKV6b(JEnZ zc`Ob2cvMp%hj;0y{Cft&RU9n|)f$80I8XHoK|>&ZcjT~%$Zk51)~WJ+ttClQ)f9DV zWMw}k=v{yJ`h93@LTbe^OUpjf!7BIt8;3!T7!V%O1vlJ2EB!Yp4b6>cs>xyl{Bg${ z$*mJ+u7j|TJ>7w*64$B?7B=hYv`Zu9VQ&)1pNx*qraRd?z_&&ezzoaKFyQkku-CQX zZ(e`ceT0(27tLg3_pQVruNz-2^l7v!y;1zF_pFui^0DQe^XR#)+hYj>ejc8`bAUZ- zlTb7j;iRh)UY@$!zcB0PPBbdh9OOF$-|8LGS1$*vk=GV2>kqls*<|FmaFiea!%QBtzAX`L*%+GE z;pLJnp#<@8&{1w18B09uMss^gM$lZ`81o7DwHa%kID;ZPbxq2B`L!aINpqmDYlGdg zy^q>fs!iG^IHC0+t0G4^SU#I0dI5P(#!Ip1-A@4u%AEQ^P2zkPWuSjv)_)4xV%QZ< zef{>cVrzx_jAbvz%hAdGIu?OUF7HeFaA|@{Je9|Y2R3sjrZh7kv&Dii^wsHBUhRs< zcg}M!5678~@cw-l24({?RJxqYOyWVt9TrCyShN4((((Nx*s;`ZrMLh$zDY zX+rz699B2|!oKIOK~Tt>|5Yl#SVmj-8uQ6s0t{|PJLzYs-BJbw^3jRXN9D7OPC??A7h-`WIqXPRy>jjNw+X^e<34Nj@ z7A44fL(uQKf%_@oY+agr8>z<|B|0@I}x}Ac-#?U}i zfw>w=CYQ9xk`WWY%_gq_F>VslTX~pKw>C}T<-klYK4B&p(2mEtVyar-m-%+W^clZ0RfA{mRh)ZtHh$;+n;2&9^*z%En}$%{ru?R z{X{Bk4Kr_`MFS6@oLCj;MEPzanQ-VPel-7y&J-v${A#?`ATUWfd4@Wa*H(rzahvlV zJW=|)fwn=L>e<<_C^{j0{nnViRAnBw7|c1o1mxF?$1Dd9<~=Z zOP+7>-@w2HU(#D@@x+)mlA5I0+Dg~QAs8vw;m|GcVffNzIg1}-1tf1L=8yBoLcAoe zQd=o-Z!q+W6pS@!TTp8ebB$|WhBafLciKsl@~iSM9D24-h&=!a4SD2O)8FzI-^8ao zHl?MYZM}s(o>YGxTZ+m><AnPB=`pNB{)qvco{#lHN~%^%nUSGlN4YuW-Ta-|)Q%b!sKyC5*G%PnBZ1pW<~ zRD4aVG~h(#;E`ibo{tvofqBn@2s474G&M+BxxrTAL^tt#~<%s&<7OO(}NNmVE{F7u`U8xQnmySQwUR46+x{>yH3ugHA# zycWF^;i%@zM`_wN4Zo`C3iepGIs{5etLG@H4;=PmzgO*L-sNqMs_C{z60^i_OFsAP zOZd$k;4y13O)7iFP#jd&^wDLB=_KM`Pzq+wy`_jSTgV}(rWp^KBzGSe$T`zZB9c$2wg z-#WZhR7l^-F=Ay(?o8KezsSkrXLP$aBd0O>Gud122+~KJq;DSiE$2PM11)a_e;Ajt zdr2lc{<)MMPm8wp!+e=-%kSvtI(vi9>Rgz@WQ=DpiKnALxQ4)rM7N{$+z3eLmAR`L_TT*VTmfYK zp=WC=FkDfmufP6)G#jx1*f0xY10YbOR8+=7EFuR@ENBok)5dSK_tN&Zf?eWxXZt!M z5ZF=Q%5luQuUnV=$KwZ!vAacvpPF3`;YC8F&;1)Aq=oc$7_}3UOO_1eN)}R}wRVfE zhz-6P%z~E|FCD(i5MTfo-Gaffo8R72*57{5y05iy#UAW2Y24Ng8r6tQ3j=^wgfzgmO1l7-X7O&lsZ0~XyrOi2FbA==o3w`Eq{_C2z zB*97pT7I+xxN4Qdjq361RweFdK@Jz>^Fe2{O&S(PD63&Apk@bQe>KvT^+2dSDtvHZ>(x{F(ICW-#%`9jkHRc z;kv)t0L(|SO%V087E<~Yvy{s>yi4*WGQj}EW7OFzn|<&rP?8+gv`>?MPzD|R(6!C+ zR&L8M8?eKb@H z79s%0o7r!?&&U(7fKrs;yi%ibaA$Nnm<;d){p2|c{7N+Xpr-rqeGHcIGTH-zBLGO~ zeVy*$&AVeM2<(-}q=Py?dl7h-KxE{;w@F%eHx+T1QS!acVEa|nVd{t?>;Y#uNOLe& z1uoA0Hlwfquid(mYq7Zmi=-Un2FR`kbUfbmC(z^XY)ME*WxihgLt0nZrevOU1i9N! z8ugLkjQCf~e)fdZby2Bf(?6(02nvyl510Qui1;|H+VM-I2p!0*CYTf>>;(JBO7;q^ zPXjH+xS(~9I!IMkk#KQ{qFY54eWtON8_Ma!t$x5PYQ2REcC|>BGV@7TqTwYF$hiF0 z4c$n1+7XXq9JatZSA7VmZ%5~r&CkDkNKAbOzbz6A%`=|>NFHnJ;Eq5Nj6LIMfD-fi zWs8S3_`b|O4MiM4Stj9sNv59MF2XBWCf);VU66JdylK5gH{a_$cX}{1JsuIMjfXRc z_hWrru0B(cBcbfR>t;56+XeKb3 z3)P(;`Zn~=@R<7>Q)U>PbWptuzVK)?S`(mny_5c1w?hkBU>sQ8SAdCwWrt_&9oVTZ zQ1LtXI+uj_Wp62>FPeO=jtG7|&Lo-PqyX(VtC1+hi164@exhIkXU*jn0Zufq3rvfT zk_!wI_HEUoatFEjcV(Br{s-LxE2Jytw~xgDDPw|}x7Q*tGGx4|PmbDb(T@(ZzZ)UQ zT_$Rkw>P=w%Od>&rq7}w5B?aX?}y`D!dy62xnXv(M1zS|fJ1lS<*=n!v&;+GlWE?6 zC+=QoD`gl77vWyjh@MM~o$9eT(zw5vAb<(@_+e|L>20DFN}X30aqMp%hZ@StI6=pc zeL_6y5O!6f8!#scMX~4)_IJ^dy_`S+8&=4H4t)#VG~HMq(vcfOWy8;zq=rp!8pPqN z1^>zzO>pj0e?&m^7*yCYTUS8cJbz__p2S0CB>lhu*Aw)=idG3CA$VamsyO4h)MtZv zw;=PeWyqs8NnFlNMF8Q_!^K`71H6K&ZkrlVHOh{B?J9%JbgPO}(;Wi5o6`Fj`SiEg zNIFzamIP+9(iPr#NFY=0%fbT@UP(x?g`Z+flTho2vx5ab{_UVM-78_8aohRQt?Ry2 zN7c4;KIKYc(Hy9MkJSK`_xO5CGf{8w*u0B5B>9a-zl=uDF=U60#)z@~YWnKckA%{CK7ySVeF6nMO#Ex3i z%OZTJ5~e`jfwfzim5kx^kXQe~cZ4Js^wik4pH||~Fd?Fj@x@N5Bm+ z#}dZ8(*C*L|2wxt2bE!}S^t+>iQeUNRs-Bz^Tfi3J~QYk1$ft6E2jmst!49><6pbb zFLd9Q^yxf5H4Y+1wB(KF(w<5-XeUc%ODm;Jkj z`CC)XP~%TuAGXr)bQG5;AFlJ>*Z=Y`~iJ9@KmH7fqYJ*Sfpc(w8b>K~M|B zB6uuXi)<`{vd2Buy!=w~#8I#0Hv35j;qB9KUWjP2I8}z$7>F>VIb2EM9SObY6TYjY zBAqJ-EK#r@$D(~#he=!K1ACi?Db32B($0>BBv8_(RG&&NfPE7+MOxHuJVv%xaJ!RgQb1iyw)u?k_m=&(qE2oYQA4~0J zaefz&Gm~l>l=JjMOd2$tXDPZ>mmTL@m6)qM5qHFV%lnWYe{CwOMau4Cc$$ES8*)d; z5@cAQQ2X;&6{#mE$aRt%(POlj;`1t}2 zL*}A*>&bxvj5GU(rNTW*v+kkKk^S23DgH{1gRzY^$aVge+ijiCpfB)nej#_G+)w^|6TZS&v zZSE%CTsxdKtV}ZF`h81Uc-EMr5p^ zM#l4%_vr_%Fa5FvsDo&F!Lgg>#c_J7hLt(nqpaG8&-! z>)vO#Hf|d%bMv{+e_^wL@JQMRJdb`4@T}7;nYMSP*~fE;y2WDs_v;eQ%FfGl?nBNk zb4T7)PPWfh34lQK6ZJ%$j2ETv7c?RH&}8k=MhQukqd?!G)mI>_66X9d&^>2C^u2gX z!Nb|p94*tl^d%cbit}S9vhMx7!&%M%R_CAH%a6`LaJKiU^yB}UK7XaF^qSS0Eq^)8 z_S3JwuO{Q5#EPvUm&-{ydZ#8=BpPHA_GPP4a1HT%8>1;YM$}xCwL~q6n3~b#>13w5 zU&|`@i^Bs}bV@jvl@XHdlDx7xQr-zrd&s|H`9|45l1$e%M4AkEe}jTRYpNL?*${{n z2Q%RV2-O2>1OK8`FItk#zl9}h!5s4If7z*nk*3sg^utgp!mBY|RDV`f5evYkO~p)T zm+)c;^H|p?d|kbpb6ImE7Ulut+TfX%*P^4a`L4Xx-wh^q-=Mu+qxMn+0vIjY=HEzJ zSOf^oK0=+T^;&#n_g0h;W1IsF{Bd%~$NAaRGy1sqiJ!?USWdf)W;5%Yx#wO$%9#LH zI9jpeZ6L2h;Ll1YO|UQqa|R@7C-xSQ=NHpN2A_yu8O+6_hoQury}CJpa^0#zt`+sVqb2fQ5`F7Ed;C-pBF~`uD)i5fs1z<#EnGW3LUYRf+26ZxDY!f(I+j%~ zRpnt(4Ir|B%d(X1z}HzH$2PGWGEdKA63a1&<0L8(?Fy@Fb_PeQ((I!u;YEEtD1A~* z$VV2LOv4Uc4Ez{O5}xhp;?F1b2V`r5wK$I3)aWJ;mRck2Yb&;y37j!W+%V2mUY z=VKgm_XNGnDg5xO2P@C(y)Q*FsJC>x1H81|a#`UyM_L->wmp<&^`j@|=pux06swX7 zOcmm&c{|Gc90U-Y?q~*u;PRkU)mPa}no7hW4B#fAzwP?fuQ&eWGga$Ph5U^tAQw51eZ5_(z%e_ljIIC%7h$qf8J95BY zq$TN$?1tTeSsRr}`a?HVluK+w75*m#_ScWRBW7I46rM|f9_Fd$_lJjE(Mi~Zd2Zz^ ztKg@+QJkSJEs6B90`7qq0c)lYn>z$Iy()qTRtd>7M`$?F1)(t`z$p}xkUd@BGus(Y zM4VQ}b3QNu=-Dqh0iM1MTv6YqVX_$5C1w?q47G3n?sch-lPPkc)PMc$XU-40XOwZE>6z7q~ z`n{hUOgN=IF1K6M2TNYo4)?8o0gAFMTWK3~OYq{W*R4kdxT%QQLkimk9n?hujyo-} z9KYW~Tfv5t7LUbPYSbIv22mhR7gitkh=&3+k`gSVmIv~|Rf{Fv3L7bo(huWv4;{$+ zaN!kB-4jE-I;>ueNG$fmEWGz7v$!wxO8YM3i{c`~Ocdrlal9_deVGXbAS^-;1uq09^+}Oa z2kn=avJ0KJh3#-O_-ZBp$EN;k2@=2a6}mq^VnfbaplvOEBa9F20zRTfI%Dau@c<-5 zYK*idH&56XcVjM1(y@kEp&b_4R5Rak@S6uU}c} zr%F->HqRAC2LC1T{xd9fXvZ9}fC^9T%=z8QkB&NT@1M$g1w`$wGfFFOLP#;`FWwJU zE-qEL6DvEC+$rNS>}FNE=bjW>bZ(8NH%$+GY;MqqZk99m6lQOv#v?-YIyB9eBMWD^ z_~+NB6+{A>w_s-XgA{%pL>BC~(rW}bD7=7y{L#h1gB`g8jaWV@(5Yr#)LT*}@!#dI zEZ9K*^8#>kDBbK{E||@5J9ux`JekqF)v1{=>9*Ih`qP$Ksrf4}gIgk8hhGnrmIsM? z0WqWp(msW!pUW04SW$~5y1;ZP08fZ3rVynj{k)ng5d8C1>Z^T5uyJWSmySnYqDYA2 zj0c`ux#=aY-MVh)uyicU8p}egrE+6nS2S||&PPU&@Sw%F=MyWeu&;`<;UL zd-nGHQ9qosZ|esxIqK&7iaz6OL}hn~>!U&+7-YIZt|L^NLWxP=iWUbI=l)(rux#L) zXg-kV*dPrg!Pq<5O%UC%E`se*aGBu}dm9tXZChA7>K(kIf_an`!p^=u;XFmRkF=Xy z*w&)8|61SM0y$&flK-|J~GY+r(%473>cIf*2FS=auy8QUreSkAoS3l zAjxbXZp|tz=qAJn5C_bk8D&7LGj;p67!}?V@zp6M4|{&IC=11Jm^@bV>FfUjBf$JR z?t4k>K6L7$We>WbM_aJ_mO^%)e>S~S5E@$j7T%vPDsrWWo zzEgR-C&>Zi9OtiqG>HbIzauaaku=?^bls_OY?P=5{G~_43u9^owfLuKeMD1E2e%a;<3*v6Dz|Wqd2|Qd7lS)b%%m%NmLD6 zH!IbWtFo5`*R~}!OlbC_%z{mBly3c?SuZldOs(x1JJWp~Yv|p@pUI=I{N2tioN2A( zA>#B))=;x@)Y4GH{PhS`_#YRJTf>JId%lj#i=UL2*reoPc=`ny&yZs28TtbQf9*C+ zL$Vsa?LJj6sDuhD?Q*Elazdca72o~2sOEln==!`;3~enI!9-gze|wq_%rr2t7_jV_ z-AH9OPrx|rly(^%$vVmec!spSLViZRXYwl{;rWT&W`L$edu#<1EuIaE8?DmL-^Co4 z+8l1IwCw1%kp#rRc4qQzQ2?&F-X0ZdW^6&B2YPsmV;o$roW|0sX_Wi<*gb|G5K8sp zt0vd1jSHQqjq%Ib(I4;zfN3~#00xg3YLLfAa+PVg;(@b@PlifZ%hXDJ5ejI}=>67+ zFdKu$%XeBlMn1{qF`dX!YUv$@^R`ZPNk-c*XEZvrk=0^;#Q{Y+vR^(hzN$X}>ftbv z?D6VOu2z}2Kq&D&djNIjOQ{nAD<$P@moROP$sYb_*rg__o=7%dd3=F9dP}_@?qLj4T?MgTFK=^C1_7I*VWk%!LmR#7q(3T6{`*baz1KE9CU{u< z^K?5Y=i=YB&z2nI>EobUIPl_>{o~CbPO+zzj@ap$(yYN@By zwMeKADC3t#q4u9s#P4LWEpMqRJUe3WEN17Cx=Lh=PK2}p)M$Uck384C1<-IttgY{= zVR|?pu5eSUcn$^t%e_xai|AZ|$@Z55@=)RJ*zq~*9VC>8H~H2Y-xBhy`{~jcs@6IH zysQcAPWVNSz-sP3w;il=+(|U0tdEOvxUH=Cl_volOXfpsD3zS4w&uAB2HV{}s+m2d zGToZ~Tt6PAWJ!&cv3Gd;5UVo?L3I1`OMEQmo!DKX2c>w_2US2ENDriC;_1KE$F>kE z{OE3}e4dzuXWZm3<0ndyPL#1vNC9&m10mjKVnIklM=n=u15Vv3n=1(ZK7OSRy?mgG z_hVpja}fcs@8uWfR%KrsKB_-Aay) zW!VZPT!K{tSJR_5|6vmO1o$4p*y6r|>d@q6PzVn7>w)pj$_j~9c?9Wu zkLLX3M}^%LyyeUW8&_X+5*@Vdr>t%0f-)p>XG#}7o@nW1sfS3$#6pAitI@rplEBU8VWNe z=WdRs0H{aioWhyWPlTf~Upyh=HW6@4N3Q=7>CmhAA`u&e>ctFU(?g_DWK;7rESjtF3w!{B73m z?J9tC+_rFN~vy&zHl#vdK)2Au+{J=vzilCFEk%kQIf*5m~;}dnT zJSKVySl|_&P*n<^AR5|AmZUV_UF3UpwEDZ90w|_=AAYv!R=6kFzK6+dVQ7OHfhf6| zsK}kFsHE(LkRfZ~Z+S5gvz`X7cM%Pe+y~Hb48fy(=&9$gEb8YU)^XFyOs^F@>QBeA z6b&u_a!L+l$%6$b84c_p>}1cbX2Op!pD1fN?&A{&g3NB zTESvPaV5ERSRD%&5rb|3AQ6Hqa}1{eXWqhfCVv&_;2jybIiz5^hq;Y~_FD28d~N8P4e?W1$Y+*JE|f3c6pxh0ev4jk4zQe*PE<`7 z+aSa?Iej8OcW=6K%9Q4ODr>aO(0sb|IO1|VeIeY(%`jR+81t^XvdV54@8>B z-5?Z+wvTyM&+q}O8I%d^c&`ZbsM6)@}&c2H)2i=6tg$%;0wiU_xbdl+DTzFG5wBnSAaw zgEz_w4)b4jQ0g)LfXEW)4F;i0d^&)d;Sb$5Uu0TL`G9>`>c*brpl)}=<1ko&I3cWz_&{9R{bU6xcv@YB)J={6w!q?yR7qdzR0dyF z(G*q9EAwBmW~PIZ{LLQp_7ghx&0fXn$hacW%FsSvU$ zl%^{v^<}8SnaRCQZ;K90r^P3by{m(Kn16@-&JM^&vKxrM#=-L^+jH)k;MHqM^7H}F z)9cojhw6MCqqX(NQ4Kp8@iCPjZflK@XIB7|#9WpFlw&`W4oQjK8Nnp@Aj8&FY_xW2 z1D|eb3A32(Ebiw?-+7iuj*g;y=tl)1m(!*?0B%ix%t(-SMvoct`O5~O@%_V4f(3g2 zW;NGrQ2Ru_r`X`nw*E`<nLl+MhB4uuESRJ#L=Vvu#Ip{hpPUptMICx`Ns&EXnB? z-+B^nWMJg9+V)R@>5AS!TpbphKC=3TEe-f#V;@uI5wc+A;C*NI*%*J?3EVZjACCU_ zu4;=^z83z;U;jRIxhMQsTFD3`pWAvo*pWHHAD#y1LSA%tX~-`*06|tvIiMxB6^uop zf@thbO2qj>qd2gzsJ`B&Jv6OU>1ABwf$v_X+NhM9#<|+%>T@|O7^;doJoQ!cdWY>1 zEshD{GS2-a#e(>4@;cH7iYXpRw(DGxa`u>vZVA zkGkqOj`c6?Jk4a9`1aUA@zBZRJ)g86-kIO4x$%4w+Pd_|Zt}@D)?2uHFHc0A?hbif z>A!fBU}55c9zmJyUqZJ1U3Y&J$rmTkDfFGeITi3kMai^ zFY8+9ax#7&>gC&AR(MzAmzP(4P8^KXG81|{Uu?1`N8bR2&`m998A#dhw`j%Qw3PNw zLaK}p8~(VTHHZzmJPP)5dFc7f(#LW1{Ji>r=Q4QsgX5z=iRLYD1D5m?MoOE3p;}rQ z;2pj!pZc(=N@U>$vAET=#Fnr;Txq;IAk8;Q%>9N1VXP`|(0G5Pl@~PE94}%oxg4?W zuOnS_bT_rb=ULBU&hxoHPVEpfeQ|hi!P)wZP&E<$fKr%D(tg=vwZGjYW_E6eIQ+zF?>zX*EA@)*hmH7NWla}OP(|C@8l9_PaMG=!vMfC^F~~fH%}XFB zH-4>8j{Z5+p6wp}e-sZ;?z=j#vE}fD?|w8Y`be;L$>Tr-ycucYIVBfqARki;IE@XD z)0yJY>DrC=DAnDDd%k~xeF2OW!U1Cu$WX)s`-=>ZAM8$cQ{fMQ5pJtu%6+?V+r2LM zm&>wZX8R|QudjaySmUK|0LW8fAGs4Bj}1c{9(>f2ELSVIy-z3>Bn}eBkjs>Y@;A@Q z3ZHeFSFBhwLP0nj5!EFeZ9`+0X#oWJ_`fy`Bc)*EkEpU%63{d+opd98cv(G6s^v8Q z2LEJxB?6XIfMBs?&IpR>Xp@=*XZ+GcrN|mYoa8Q=@?k)=XG9=%X3j^Y>G6rE8YmNpKk=|A3%%GW z#3LJUrpgO4#&Xsm44I4N;3f`Mbjuf0k8p=*&Y+} z@ke*{Gxv5|Y^33)zBuT&PW>YYoZxQ-UuD$Nb`3Rc7;S7IgugRr6!xw->e*X+@02@AZ+(;m; zHI)5nBCsWF${X+QcUOz8`t}*H(}Ec=SEw_?P?`j!%}?s{5%dpgu#)+fcuq1 zBM{8X#@~*Zw#1uPe=q!E*D~YK#ET@4k<);E4=8H|lIkFDS{-l|F|~hVmI-k;C#ym} zq;9R~FWfy1In%$+?6_|7lv;ZKSGVx8N%(x?w_;2}3 zLtt1il`^gW<4D%jA| z)9;{j-u!~G@Zn5^dJGNn{J}@^g)6#Blgm`jL|;DoF>Zzp{RO0lZZ#G_RyYUTqZw_z zpQ2mGFtf`p?Rv|(*O}3GTwR493o+nMr}InfjokwOFAc=ViZ_nNr)h{>AWgj z61o97%!m6hhEf3VbqTmHeU|s>Cb@#3ziU21vX3$cKBHA{wOYZ%3i4Tsf0pJPwvl(F z6ToAg$z|R6eaJBoh3wYquYORgQ49&md~IKZPDVo`UuHIar(2@3r=M>S2;1cZ+&0O$ zP=y)*lKKD)o6mhO^a&@9>DxwdtTJdMnO~hja6@|aFkI|p!9QHDpHYW+rP9;qJ`p)b z0MDZ}Rn%R-XDjo$#mw12?DE$PzkDN00gqVDCEUqI}7u zu(4#1Y7A%+UzX)pX9pAHpX$n!R_0Mji0m3c?i7Eqwo|(NXOSo?gYzf>rt4g(Bv1W~ zm29|A=d&JQ^_`v8V_)uB0ssLG@`=D?CM)5nJz_WW zu{pBh3Az~cLC%ij$tF8)h$ag;N`<~h@+`D?gdknYdSek!E>tC4@7t!wwG{nh zDr8nVw;QUGv2aRUvtMTl`Nwp_ga^{-9>zI9vKmZe&o#vHlFH@@z_)RuyP4l_hUMh1Vpr^idDS2VvhA2(Y zFI{9<^m-YdA|m9eir+5p3ry~pL7mMPXHFd!&mtO7O&SFiu44j!xMed*A7oz)80H@X zy1NH{llv{*SNhkM@;MS2vA+fgZ#zB)Oij}^UJ_$Df4=`9kb#abtuL@Fgb}*lfPb6r zac28|h;~qW6*d|l*?#7et7d%SQ5qE`yNwA$C@@-Z%<96%$OQ8g#v`|&0zVH)4&EjK zyIf6uK=E~c5MtQR4fA!m(D)`-(xt7YZ1p%0$~X9nn0b^a%R}r zrzzi~pAwycdQEu^$Ap!rz*3XCMZ;jME#>d@)fw6oT`jCQ2a^$7>)Qh4vY>#byz|GQ zlq-)mlqi7u`xSF01HY>Tr?Ezb7<=MjRz~keAdqyh!hvPyByOeRWvWTNm!kFu>45r!o=( zk}4rRfP^3-A}x)Av`8s2gMwI;fJmd1bcY}eQX(MTNQ)rd&CK27`R;S?e;yytZ+5Kp zu6Mm_?Y*&2)2x5x3XcCWr)_~azvHZ&p|E~MGph}%F&xmzJ>#BB%+>e4EVtJy-(A2v zOXZ55v>oQnr%(|-?_FBqG=n|Zel|X9`so?wxq$1J&1&T738gK5$K-V9GQ)V0UF)1K zNT&S`#LZbR!)o&r*^#n@W}fR%S0UZ|zxTz3sM$*0-WqyOyt%Nak)YzT3%Te4^v_wE zsBlC1u@CmhP3wD;Ul)1z@&sfs`tKJaqyNIz@fv=Hti1Q4`0P+6arGC{M;IlgU&lzZ zoIQDoU-&H<66yN+jMxaV8wqyg%&zBZOk)GQOpE^75fE%`b1G-aJQsZ>U?>r66ZV9M z*eaAR+FcR!{i+5;m)_(<37^b$(_IkXKgxsSTh=K6*v(bTk@Y6EA$;N}i!VHLzylEc5%wHC-Cg(VDd% z%K{Mv)7#gX`@MNU9%#d#&VyMuLOIKzHV>S1&wsUyVSYQk&DAE}R?c#@LB8U6W505= zs5tj9LR?>ABVsvh|GS{)ntBRdzs+%1yV|BZ<+z4{Ro9PRQ}eQ{>z9@y7YG*dn6y!;?FTb4|4aYoqb(V#>^?18ju8#VekF7M|VY8G01N zl*ATbwE89-g9^3;ebMRh6;H$%uJHv|Nu*!;BRATbh+(ZW_OL1xTVZ4&A9&)%da)#| z;No;D5>{)y?IZycfnT($b%Ne(LdSL3v8_wh-9)fTUsV9oG53LbkIKb3cB}VF9`=9L zG#^ZV=J=>we}7qVKm^}x;5r-v|D@M=@17%BgG1DKjaSqA9gJZt<8;@&ui?p}J^yh^ z7fVYhnv$+_pPw^cy7U|$QU_Kkb@Rcr?{BD2ncLYX%4(xStDPqtoedGH8Ir!`lyZs$ z9Nmx6Eb4ywM-mzzr{^p+C&!8lkIN2=c&`>4Mc*J@$8RPBHe4>uey|TZ$$O1qHTZ42 z_m57}K&x%H%9e7B!5ecc=hhf-o3DZfIM5Rboh{}=8o^{U5y_`tDM_+_+V4+sn>At0 zY?SUbkGpOauy(asGM^XHGEC4kL!ac3T)|GB58nVUPX!@+O)wUR@rwa5!|p6^2!-Sg z>^U@}+EO&^q2G`Dt|~b2AS$XDc93C;dnuoiTZ#yWI}+5OT7+-LV|XM=qWO@_#2hj! z$E2r)QDPR-3oj`H<+XX9i{&&g%?w+|T(o9jbQfzx_1loU3|z*w;54v+t6Gv#zobtee#<6AyZC9y;tdXHMozG^h_c&{ zgbmgOY9>Nhj{~1Px|%?|7ePi2USt3AmQ`sspSA6hNX=F00>Y3nReQJ;|=Ga7*iXcg)Sjx`Mi00I&GiN2VeCgvVhDTvZzYZj=vozBM#XTH{PEUn-O@a&&3gaO(bQdSNuDO5U6}^Y6ov9nbwR(jTAML>5sN@E%YR zb^xhqFMEUnCB<$i$U{!=4QGzta4@(+q6X6Vo3m;);(_l5W0u`k`@^KZY!yHJVjpk6 z#05{kdj=Yu<)a;OhQ}ambM}y}R}#qJe`_j^Rw;t~Irs z+SfWw8;o>u;o9YJZpqVp$TwV!$zfWMtT->Y28%O$#>!Wd2V7y6!Vi)JhbP;Pe7%oh zmnvd}ZWyp_h87e|d1d|D%q)H3f!#Ma!7|R*PqmFaoyzL*YHHYLyj5hUJ5V@;qO5sM zIzGDa_EmE?&tvt(1ZZlmUJU-D2Iv8!S=~Olm^IxWhCDhMjO&11$2-Z*l(12J?8I0V zw|*zn9bMTr@m4!>2D*JgP~pnYXVtSaLI}J~!)34W_rFkfcr{rMQy~UF7$BLckT48S z@Mq+0UUZPjTd9TydN%#4xX9(X8HagNEV<15_NV@&zJi=}%D)l=v9X<_xkIZ=%%4ja zzh6L-)>F=NIK`4=j42J*YQiO6dKE0u=&%x;Ww;P2JeAYm4{570d+=Uc7W{>Kr%4@K z;CxFs*7Dt<1M3})%?*+Mvy@}1mQ&s#?jijA@R*Ap1F)~C5X%Rgj4EJjBTPO23aGPR zmrK2QL39U`_sZZ~)vBdA{8f6B#{N63>2&k_bpETZdef_UtF`7{>&34<=v%q3(fW^_ z>r;r2pce<)2lq1GtS%HEFqnKcG@NnZzDgad6nu+$^(3%f6*`hEHd6Z%$5KvbM5x}Uhlcf zl85B<7f?{NB%qxamBW69#!Pp0{=l_&9y*{7jUAsZqqdd13mqo3P*ud{7}t?9n;ZO5 zs@KqN*O6)Q^uoq1?@dXBU`b8by!U}@HjSBA?CT;m8be5y5@~YBq#eMa$~U6)`4@5; z3}c%@?*Gz=^dSq9lZJZ*2j8*Sw_nH;*5SUU@!S2#t~z0ui3$_=W=m|=thr>4m0^h@ z_bsA1la(nTl?2Vas>J8pf34NdKv(fyEFu5lgC9MiX-rIl2MfKKC%Xr>w z$bkRs#JxVfJf*Ci(ox&?0xO2szXCe3Z;pHJ`>V?yttm)CkWH;`#dNO${!T9t)udMA zovZnkzd#9SPYv+A+jdrdBhhuZ+;%P&TQ}x-MOKTG?Ky5aJv8aBRi2Bn2^>sCWP|$T%^vGfZ-SEcZC(Q!iHvZpXxQ%oQ{x~;#=azMx4tw7i(R9 z?cc0bmO|$0-`UXq%D>m(?x(>ZF#(PNbrJhZPW6JQo?*o8Tg6Ok#LTD6TEJs-NGiY{ zT0U`t!+d^MphNKX$jtk&ChWs}J|C8cXDjTc0-&n))>J7bfdcI7bMS{?iq|j`zVaY)J`7wFg6~322fxltY1_@4{qvnh;3y z2p=(M1j~Fo7)nanP=Tusn)Kdy@`rMF^SOQvOS7lmhE27?PA6BMi$+^&Pem-bO8|N)yxJ`Mw>K(Yrqw3psXS=8V>*}gH*vV2> z^r|UuYuGUB!GI&c*J!`tgxT5bMfJZa=bdr86>LuaKX#_aumpip$&Tt6Je1uz`}F9$ z<>}SC)gQmEx#ST?`~?@m?ACTKLTiGFd^JeVYm3_H zcVAp!)VpyfRDL_8RF zz1zW9glIWiUU|;KN}#*ECBX3V90(@1BUvs;qRwQt`z8jQqf2^sgYH9{h4ofSVvR@Z z{R_dV$X@mw{B!3+AZ&H)1mFD=IL{MATa?4Us%nZbuz4j2T{9QwUr^UuKg)KSJF8AV zyPf)cC5-Y+MUQxGISLNn9Ic-Hql`~T<~q3pi1ViSn^t9-#}}43je_Cec!(*a77-tI zF<64}_Q=t{ zxHi1hX+;;#ke+p`RwH@>K?o_HD$sw6uwE#BgUO(ROvJQ>PGc%BF|TsvL($<-#oaO=O^(D1*-B7S!gc7Ou5y5U^*q$dvTd#Yb^=H=5GJS>A%8!2k2zuwi4;a?h z1SL!3=ixYq)Cr%^LdpCSdX0iB1nqnww++H88CK(2yv+F= z8%m19o7(m2e0LS%i7@o7@w%hqihbS~cnxa3b4w)$uIbnF&91 z&F-z#5_RpFa*EKj3fLLYT);$=ap|Vn6}+m^iypfzgwZEA0~VXTuuu;k|DRhDNcGJpTVb8Bb`nH z7TkE_cgcCVq-c>lWZBWf?_OXX7Tw_ZnJq@t>Gw(O2Rww`$=aP`+_W97IB_kTCh3Fkw+Ex+h^M7F0YV?YNENsk?1=3B zL3lobqCRvsJal^qtMGY{(FYs8@*eK>>20C&`(1M#fNJ<6Qqza>D{zgwf zn580;Zi zP7ri+br>qBJr3FG^S%08_}{u1T<`PvY-ja@_bo`#@Ku7X^BxIJ=VE5{$>?xV z=sAkpB&aPlEJSPO2mH?8*x%np5)MTkFhS>nt2sb5FB+mf6Is-l8o-5*gUe|{sDjE5 z-8o^Klix<~;X((!s3c4RKfG`CUB0q!OO`;AXd9fkAx9PX#!G{>bRzqCgpsf|xxpFS zK~aK=us4A;zW$+y%Z8N~-YL_TB$9yMiyD?_D?Dfge{k0cit;#KDQJ$Bv@sX6`97>b|>@VL*P>;4<19Auc za=!8Nvn6H({u`CH_nm&zTBX*~&asQcYZhKWxI)hpE8@IJ>)Dc^$(R)+S-|G^L{q`T zN)~tu)+0Kqgr2_tkF7}6pXNVdU66kBTNexkyLh$C5FAaxfP3;aE{+}pPWkO$YzS}##QO*)8Lf9$MzQtA9e zQJ9p40U;ASoHcd#M6dIQJL|%>GHv79wDgN^598EIa3*z$oahiLDT{o;FBwg6W0EjO z?Gok|3YnRUU9GAu@=|R>G6^IlCxt7f%+y`s**1`p`-t`P ztKc5>`D{)$Jfb-`3=rs|c(Hs6(LEJSEX1#QX{Ad%Q$#!c!EFD^sOpd{^l zQDGm^G-Mo?qN);K1gC^iboM9}Dbjd5*4*Cs{;c6Eq#A$pzy-H_!KJYfvm;$W&!V^` zd0kaq!G^0B#+3b`^Zkh18!}up8jh$CvmBC42oNIwh7-AS7H9qIZZsn$UOk=MRGo+| zPLN$1MZKG_KK`gCTgRDLQJ>4MEfDX%(qOM(=&v_FUq7RIwdCVQ?L0NrH7yOd4oIAQ zgfJzeZFBn>bH#Qxey4~Y98cY_o$(uIgS~b_vfa?3B}j%<#ThrNbP8fEWQM-?_A6=1 zY$eD!pDHQ1?V4R(KSe6tWes9YB+vV)Z%UbYg|0d%z_(KZR`5*_tBx~0^siA0r$rBN zs*ccQ?|-$d8*>GL#VfUOe@>Zy9yAKF6OZPE%uMfhD~m68t1Z&sK>hE&>@t47UIUo) zT=ouc|J&RkF{)@O5p+rO=O;}M;Y$yVH|@#!N}QvM_Ai|dgjP72UQ22iyd1F>hhBEp zo$ciD>Gj@9<1Wqg6N&1&-I2*TxK%tw!tRK0TrH&U9AIo*Gs3YSn7^c|>KVhk;ivM7 z6Pj083&R?+r?>QS*7K@uSXOGwi;HvQ|6vte!_TIHSr9J~=WN?~2}RnfxjEZr1- znkP`ne^+TCany`TPdmKyCv_8}_29cE6SJ~I*{hIZh@hK8m;r*hclX&Qbvw!h!hY48 zr|3(K!NmZ`v{VR$3|fC{-1hkc8@hut@S0m&D0kjTTMBpa6XuphyV8xJ(x{Phr+JdB zXQNv(%V(V)J83)7$0bL;iZ6;g&g4}eRngGfY>*E}f)vCW?jwSKTywxhcwi}Z#^grO z*o;&mkUwuHzSVe}1ZzjUBas(=*LroFP|lxke9lx;>=E}Hc2M?G2p$eGXI)vd_1Q5e zd(QNhWb6~aPcA!c`c{q6c`~RJ?057t9U92;g>*uRT}~TZitO{kH#YE=2AxOY2d2Q| zbLSvbGb4@p;q$;`e`ZN{k3Za#&t!f;N=1&FRW&LsQ2?R zpFjiYHyptmP1bWiQKOYjDn^&st|tayr?xX*Qy{nn3C=!Laz^NL;Esx!O`qVz8eWh% zJ`{bQh}#sVxDJ}9D-J#vvG>cjdHY{>W0{Stw^B}X;#OB4P@3sZ<8DyvzxMJe+);&0 z*}x}xIl8C1C*S?b#*^RSKYO-`8A=O9#X37nh>k!5xH3?f9aQr8*%j2j;a(nyeGhUth=}lcr+EL293$x8@nU3BbY^qwWSbF&p#F;9Xl~SGJ?CFw zz1WZ&f>BzuYR1>;oVgyN*$$iTK;X!0)KD0>A+5_Fg?x$ad2aM>SCVt%^EF$l zJ@Dnu(|LX*)ob>b=#BA{srZ?s^OL(PlbP$sv2{~Vs=3!|)BEFz8vKQM<8w$*wC7e`t!E#B8$XdasshH&o-xi{@?6F99ZmJdt*u|tU-jbh%c>~epo4zXgNDI}D->=X+jX4ty|Ge|O4 z8hwf1fx@o@7c5%QoXzX8R1Ug*6AP$z;_WE4)7Q)o-28quV~zz1_YpvIJ@R$?N(qHm zU6|p8w)OBEeQq1>^K@_@Hgegje^KfD^s)i8>O#B0zb`(cAMHI%3&^x~urg}Gg)!uJ zz1tN3@EH4y2lRl!A+*qhYBb6o+CyCn# zKq22ZzK|st=&`zPN4IoiGS$HUExrK=)K`($W8K@UE<~;5$Y)C(-rr*-_5U50&{KWSs6HGZ#3a<--33$YSgDd zLatqUGQ}Evo3tWC|IRBW#BJL~hu21ReO1Ge@>Sa^1LKMG)(tmNyiip|c|jR4GKo{z zSTg499G7BDb&Pnd>+%4pupU_UL*Xf=Ic5a zRTMUSZoxKOM{$C$0Gn?XEcv*Vc6aE6VDc?HP1MX#k#NM&w_#J@*%5-qfsrj$bIkf7 z5gMpFKJ)F_%I4aP=lGAG;D5fDyyJ;pu|Scksi@EsC;5#2rT3l%Tcqo9?mNZ(#SCfB z_aT^Xca=!h)9K&{$gT>%2Lb^Xo}mf!_T%y|v(}e{ z3jCwMFRmM>Kl4PbT)iH{4)fWVk8a4Xs}MJUjXJnst5}why0o#{$(+=?cKH02IwfLL z(@i2TI^(*v2^b-@j_w^=IN3c^ZVSuL4?hDN>58M+a6 zzQsrl^V`cd$Fjh2*}U)4RayQPU2_7o`L-9pHA-NrnjgFUf&B}RdIiUdw=UBQnbf&e z`DNMc@$-}2b2QHx@~=JkB*8Hg?D;+Qc6YM?b>vlkR^C+`FP_DpO? zVq@d;ij({X&KYw?uWgm@&g-!Kun9+nF{#`Ni`|r-I%Rc|*KB%BM8h*i6r=?6ew6|W z-`7VO(f#;656pJ4Amh#FY8=kCb3>|NpkYV%l*f6eYWl!+3Zsl~n7)7h&)J^cnX6K^ z&Hl8`n6&)f{D!}fm1FVR_v49xn{|1N^@9EJ2m5Jf8sMs~n+o?TOm0Br@#Nt|+_Dn!=DgU(VOY@CUAAyhvFp+&EYs13am#g(N5UMGYdFt-asBz(k5$Hd=PSe7veJQ=pP zKzo-_6`rgI3;c^HC=V^z@k#8!bm7(;(xkv5N4w)XL%Hmi5TYf6v$Ss^OEIr!Bmk;W zK`m~!YExg^krkz@8859K*YP=7dr@djRWN|12aXL zVKUmz-|R1bJY6)p_5BS8Wt5`djOI5^;;<)Jz&^QNN_`1|Y4S(?OxTTv7^Gb?^S+q& zz$ECv-Pq;tYX;b%6ibSTrlI0jaqvlGHhQ?>pbf`>PkHjiiE;T%8J}5pcET)8L1@m1BmA-%1kXrP1>|kE&a53_MFF(k7rS^&jcuj5=!%~$m@2p37T^zH7T+ij zr?~d6BMFlTg%bjb~FVmBHYNe{A{x39mNWkzi8W=0e z`A2f1YthQw22HpCIk|Ab-EUFl#$a^HPz}gx8o$3Pa5$Eip3%C(m#xi%vF5m}MxF?8@zkIDDvM|?KqdsSBlx~t7uQmgf5 z$iH$f=T3yx9!;-8%QrgLbL;9xCMWOhlb&LIJ*(#v~Qbgku34xvPqaoHfzA-u&g6kDJGrx2$gn{H@^v}Rt`@*;?ixZr)QC*;eEgBa! z@zwR9;b-y6_i5q}k3?1;{IL6!O6H4_^7cKbtxM_@=sCsL2`H|MaAe66m`RfqDb`|P zkg1(C{?ksQ{J%H`kL$#pPXPeGzB?lWU>gn9qyA8=A-$#bjpL20`PW|+M)h{Oq$FC@ z*RaeT7kGiOo?T4WLf_Kqi?9$Jtzf{1D}OL~a%sd}^T!s^ln}_&vorQU6A~QAyqOER+QZC@seI`Pfygx6xUO;+u>=gIdFmusfNYf%O6EGed4J8X^lt z=}><#wrw;mq$Q%u*P@{*{0g&q!|<+Q(p%ajMaa$_qB+B%l^f+3@k8Ku|*))8FAA0ODq=dLQ&w=w=_c}+-gQ?e1wtQ)S7u|l5 zTXeKz=)LII!T`ufESrZRJ){-dKMU~<(VEZkK zYCki520!f%1~|(0!Yq>-fhwuQT6G!n$e+c%e)6nQ zc*w90zf(KpR#jU(o9N~&f1bz&RFUl*giFqkc&cvjAIlR?4CS}j!9b-I*q)KzzYYoh z$Z8F5>@~hjdL05~-QP!qgEKjt+*A01jLniARo`_gC7q1)~oY48oyREO# zZl^14tV_IH)Wi|wcjq~;0}=U8Ltf7mdFzrX|Ea$Q1)hpVUQ`HVdn(cqXRTY-@Rz=W}Em_RaEPGE)MkJjK=kHAk zXmTrQPwM-QJ(TTQR5fbjt>0_IMd_F=Z?rh*_}r_<+tE3aCVXOm9;*4~V|VEr{%xTU z*g}bw@C*$|um$3f>sHTlvaqI6-B4AQu&%j_WWkqD!e|DPbycFRLtrFgGZX~M=6$VZ4 zLR^3+LtrWhzaAV1A$8MzuCGN5|M&CzaM7$W!i_`L7IyRndV~?6(BF&{Ni|U}P^-Cz z`$yVxr^?0jP#L`1E2w)Eo5X7QvwmJIS_{^?<<^8F57MI`NG?v7pOq6Q)l9U@QRffa z7Xa0QD{y1opIEH^4Eksr8l7yo=()c>UEpI(zVwsgtcB_e32-yCbvkKTOL1I`Y|?Nt z!N5w$c^y-|m4?4>-A_P|h?9f)91z(NhBp=Dk7}2qE|L`_hNl8w{A?#YV)mC3`tv?N znY~71)UaGDKz3_VreAyefhsy@Pv!|N1KNiN*4vMIl*0+udNh;~VAODkYMyJyYX~e2 z`En;Z&cQR0+^p=+o$pQ^q$QgZFQiyD?wy-q6#q>N#s&%gM!)p)sK=NmDWD)~|I~jT zcO|L%bJ8ZpqoXOB=u`ek5SPgnEW!7hFCZ6rNFiN+EDKB?f3e%ZTepH-hzjQT)$#Y= z^ty7g7a5JQFfe7rjdYp9&Yk+V!kq+?>Aqxw*C^)ZymICawu}dhzJ!Kg8HoVo0hQWR z6llyXjuYwdUhNRprasgur1i*;yG5t<9HR9PBB?XcAUS)bNx9#+VeI;6r(=JEf`C}1 zwYTu>1)e7ZeGmPW#9a(5>;mIbg}jlK%UF2Y$XZ5P;n)JVh_e~CHu5WZuAU6;#bkir zuaWwy>DB%mL%;7f`o4n}KC09^U!vl+(C+@+kkrkMmI3~x6VI{iG@*n@_@+JN=8^L4 zK%WQ*Ebvkz0;^QWMoR^SM`$#TU~c6-N@VMZv%s0nc)sD8Y`&({BzzDeWd(u!T>*i&e)D3_%rcSj$bNq8e{q zdm;vK%;OqNY1JyN=g}vA%bta`-A-ott(%w6jWIiiuo7_&SqqVcs49~PDg(?E>fO4W zd5rr=4>1m^upO~9Ed_Un3tdjPvT>R>EBjA3NVkITZrx)W5iA;b;=iP);kvJLU-<1( z^Ekob7X~-T@EsVrrXW~O-j>BedUQID^whRAgTP>+&>i^Y6FpQ(3YF7>6&^NOA|pq@ zc74xz0-*$nMQ_ZHl2pYdBaqVT>ZBtFlORuj)^p382lHWju1NSEx7kAiVT@!JvFfYG&q$Jpi25 z^dXYzd$5Zy_mB794`93>CiBc@g@LszL0{Le#*}H%R`2{z<^elIL zf+HsY=GyS#=Mndztv=Au(BO?t6VjPR$Fa+R-{hmK6@+^)%GLT$C zM0K|cP)ZaS>U{yf%?$@C%YFV+d3?gVl*4;JZZ%}O5dJ0;Udj^AZfkOpfYBGCe^qO? z1rv=s@Y2jHC~u)a%G);S{oA$!J+Us^`rJO_oUq=yYl;QUIP1mK8XKHS8u7QP3m=Y<@Kjy9oc> zwNTM@x6est+{nr?OBO_v`Y@}^skP-m!W2G2adNG&X5)7LOvLf%ium9;@Awq8|9)uS zb>p#=@k^JRkMWC^f)g#gq@1!KT6sNmO^Ox(;5G{OuBiy44N%>mshv62W!c1D0B2Nn zY&((IsRQzZf-iaJxIK~9k?OMxAY7pdl)FlLb{1cZ24|Fy!e8qu8<#!Puze!&o|sCa zt^HxYA)~2`J*vRu)>?3^<-ju}TDpr^l*jXNZZ7h(k_=9QuizLso9G z#ZjMj?RD#?Sg+fA>WYt$z!t4xQ#-}Q{f_{h$a54(6`t7LQP=5+USD_2X67y;G0NZq zE6P<0(jwj>$kcf#{DoR0BgwJ1FZl1lM2#Y1Y8^qK^+=EfWeLG1qbM>-IY?7Vt-TU zQ+|Ihu1eIx$t*t`fqhZZZ(5l)z6xOZg;C@4Y^UFg+R@=om2qFh4?tRYL!_I=HCKp@ zh;uVwV`!5<$bgX73s<;o{je;Ft)z6ktW!AO=tS!kG~S;V>ZRZL&&x|f(e5pGGb8ZZ zE>pMsn{eXx6oe{28ebyyN4V$!5p}|L?glY!5QBTsnJ=tV~JdFnX|p13$J-vcz>t3vam8w*aA1ok0{CFCPoP~tiBCX zWGju=`j(w4HeRYHJe#(i`(g2P=X(BsJj$P#kvpjR5GVc19PDa@pKYU)eI=)>vq*)@ z-^uLCBsg?k^m_)t=Mc0wTcSZSkv?}Hq&>}c%vg-w6#qEO-69Jp7aH8ggMe^xNV$hV zU>B%q6`iZ0&bepqq$zL-OfW!~s26?1;q z9}&%Y<--9IqA_5g?;z_qA%EhkRk8H8x~*w+ik&T#SrCpAf8vT-uy6RtesR3j1S|2G zbT{F{2p6H>tNZ-v)Q6O(Uy?R^j3L(lbQka;kSzb-4>4&mlH6+ZIX1s9>dtJs<(Jul z%^$wkrz6=P_pr#ke+w)Dbqw|Z@FT0orvlvKqgy$zeYTyo4|8(wupB+7KI6__&K3dk ziZU>>;~cST#N9`OoXVtce0Zz;JiHxf$5y&}333`rt;=r)iJXN!9cM z8j`!gORWWtt&bS+q(KjE2LStkgY+y6+htDVv`M52rEylLX0fBc?MTgoiXZAYYg3Q* zUZsG!{Fwv71RG26)S`Jo2qrG(Ns=F5Y3a@@&&=N<9epdxB11Q20SIG&EWYbL>0u9? z`Zr9r5L`0#x}w`#N|)?#z5n%)`%_yqb26$iYDB434TXjh?hX9eIqAGAOLIiHHp@MR zuagcSisrOt#1evN7ar)Z!6y_;pK5%{AG+gPKTRHDr0UL|X4J_+Qfv-l<{yDU@j(NJ zpETj-?slI)e6BBlQfDYENRBOrH2(84Ks|sylKt+)a2-T_uO^OKjDNa zbuVQuf$#s}LOSc$w>!~>4<1Y7J!~`R_>8uDr1?)X7BS|p75=%YG126N1>}haxPLK9 zxK-NoV%dPWaY5;5nXs~>d7$MhsPniuFLeJ!XFl+nP54t49qze}`ZEEXS?L$n&WC>p z_o6T8h8fd;B??v^Ie?t~r&^%X#o-E~=rxT2v9kmII{b!I5~kj5O=|Lo_hYL;Ie z4(NMVv+kKv5C$hO`@Wj7yT!JlkKP~GMRL#)fsLFP8%PBH&=9kNNrYE{L_+z%bZ#bV zZ}f0i!`_?3O5;j#Iv5f$N^_|g=-|yr$J{NeaF@B#XXh|^jt)4(Qu~{^_yoVFY{y^8 ziKEj427K^)R)q*)j_?4t0`YJ|LtC`J^cC(aoGS-O1pVsaJPp|4rr9%yrh)8NVSqCh zjmq&A3z|Gqr#jL*S?|uB+`OE!vk{K@bLty-2$(p6D+^LOnlZRo|IYvs0FwGklf#uh zjJ9N`3+p)}3d7v$x2Eex8+ye2*oZLe2RtJh6lZ!CTu-B)g)3#+XJ36ndiBPk?`)q7Gd-0hN2Mu<&)=*HR4vTc%zI>5L-vr%~1dpC3PV!=DD z;TS@|B_XXR$G&;e2Meza|9Jjg;(rU44g^+BAe<8hNj0AlqlHkE@ZlA+R}2rsi8+%@ z9G&&-Pf!-4CK+W2CnrX1`0nLcVRfTk$E<Q8C6UEWP)3JGS>wnL2QanA?t4LgHW7WzUBaV__e{ zZyxvgV-+tQ-@{L$dJG?EEBPSDPdVH!UJJmo%a zjw$`{hs5MCoPk8zE417D5N}tm3B)kk6Y)#4X-528_814k=R`5XWkte&aqvtWI0n9$ zHv&nVu^DRF5;mSAoG(r{_*Y3M1kIA}* z5AsACUqkHvInALUq>7C1#&`IfmaFG?MXzDx0~E-?c$Ne}Jlr>M^#H*K&=FF=Z2tOn zx1HB^nd?(c1jh>zS~;*?u_@m#&XxdmFHr3&DSwT}74&J?0e1E{`-)BzE=rH81Gv_6 zVKC2ch4K*q`j9nhDE2q5_reMG3RSoA?MCoHL(A0@!$p57r^M$HXg$JMap3m?;bm>O z+BX4}(FW5?7fa(ybajKba7(LxnJpVn>e<0xTkivl&5s*&NOGa&($*X zM9LDc+;}z*-@4z1z-&ve%aUP_ykmRGFn8HEZM~jPs=JC}(AU0yWtY2hAt9Cw0mZo_7`$M_FEsWN)MDp zjybElO}H<`cULpt;XzhfD3L8c_Rr*Ar~)rg(+_7N3Ntm;=p5IoUAJbjvl0HfJ*S^6 z{;!~R0Ht5d>%(F6n}ZiXOuO;(h@dfa{xlUR$BX@`1T;eMB3O822q2lLyaZK{RuJRYScaAlBXkPVmC~fEcu4Ozm-VUM3r( zq0hpVL4llOeWmkhmU;1IB#KI11EoN$$qK7%9C6nHZ8(yp;FAl1@04o8E4>9wF#>>4 zQ?9c%F{93eg>EJ5D$xs-#uuH&an76pJM*wqKJ8bMtQmTR`qT${*sT!cV#ga-Ge(IbMS)6b_m`6Pn{kLpny^%+ATqy#Dy1@g0y_L=&fX z-JT9VnajSVs=2j}{CTvsHR<3<+QrkP{yP|P!?j<&ngy#M*l+1I;erbdX^CDvS_LLp zrQ6C#w6j?T6Fq9bi={DE`J?TBTgIjM$pSKLQr??U+$3i!qRf%Bp*qAl1gdxJD`$Vf zr;`8vt-~w~8ecdFHffx(Ak}-ufPx_JdK;J!Av*^4M3?+?s&+vJJ0!!2sUWDg?AVnb zjuL1TD6Jt6R$RJ%^iB^ ze@rbMWEyb8NhZ*pLIi88SFYPzpB4xrRmpg{fWw~rzsrz^Nb8mOEd-Dqz5q&plE+=n zvAyvaui4GNdwTFB<&hr|u2hH}5`w1tZ@~6Ze?kwI>KBp+?dxe2F#7ffK&WsJGdoGM zTWu;fQNx$MbLC-sjz;1vZLT<66^~szJLzh&!}3`g#Hn2ZsUBA# z`V|zXUm0EQbn5%wbxRZoNAZUqw$C8GmGigY#~LWk{o>z2N+TGcGw21DCw3nlv?-6_ zPqMSGA&INq3y_sdPS%|m#CLJ%2Cj)34q9NZ#N_OuH#RO`cSUlr429?=Ft^jc5bixW zU|-MS%hzn! z#0At4-$X-v1-GbRfqYSWr_SA&D;#4jjHF3Vs|IxsbGZH|yCXm`Q-VmRfH%is>CSLx z8k1sY)qsl@H^`xNGGMzd*)SLNwlf4*IJRhshvr1@V(jL|(d(46`MhwY+a<|H2mhsJ z=teL*kMsY&^~(Si&RETxgvofYaaMePClgz3Rp|X3g4Z5rIoO?7fzzr3JS8okyDWvb z+I1mh7|F&|e~=}FHT5JBKk%HVkqN7kD-^*9?BNDueUd(LKo4Xr4w=+_#~;4_v@rf$&owC80jU{y5wcjIn>WSjv5`o-L8wbTibJH5C8 zh>FC}#rwqEjP?c~DjLVdL3OU&r}M8Tg9_cazm`34=9X4YrA5pCj&gclO`*}~f99`9 z2xXMbPwkkqRAO*Ll}xp7R<;dz zxAk0nFW$P3k2G>!c>cmWAOY?ES%M*qT+TC4$1K66t`Z#>aSLUHL~&f^ z^ykxuq}xg9QUNSmggYKlLL2B2OLCj%g4ZbR2@jrDr>=@8ymX!Wp*nuZjj3=vaw@PS ztgS~a{uAv{)*28j7%K2z>mHcW?lr53)x$;Y_uQSPTi0CxqKp<2svi{Iue6p_O#r{^ zgPNi7-#8k1|F+erKberbsO_^KsZsFsio1U5dyH||23Ss_#196_D4I&dDU^p*aB0}~ z`?nFJ+Y2u&Qr@m+V9d(LznWdCZ|e&5ZDd3uEWkDe4lE^ZdnNB5Mq2ECB$)ki7wfA? zT&0-I+4^69-5Rm!u!yPWKcVD3c9C>*p?y29-LrL6L1m0w*|KtoE^#>bz(-|qp-SY* z9W2ar!qV80cd?>nT8CeLE2~Tc^1Coy=>N2H?f*>o?|%nFl0#7;hYoJ1PIoy}SW}`1 z$?Xs_6**H88MdL^)qTsMq*OM?C~P^5FjFesx0pi+8ItBa1Gqt+$RB~iyac`e`t74xu(L{0N9idJ z&#W6j)vvp@->hM@yz($SQaSj`E`t9X8}WI@4W~BGOKH}29lHhhH|T_Zx^`Ak{H;$) zeBhv}29PBXXeeY!+|cT^kZk)^5Vi%?F#D3P^%5P<6WLfxj_w^bY7uGq+9^l2ap=p# z;#bxB1#-IDZPDN7%JX$pl;pUqFPWHg2(JFzAj#f6s#ld%Bkbm z9nJu`1vn}(Es$WxzW3}CUY&-|`a1w1QufvJLtPK;n+m$hR0}_hMkvaXTi_!hFyp;` z(w_dTvF9YNCvSq?18`5&aSCZ{yCJRD**r~aFaDW#36_%A$@tKakz_r`3~k&2Ss18w zwg5U&XFN27S3R=BrF!yY*0b(LTJQWw+UZUSxQ?O%b>6zS+ppI+af7>IvXNIas&#=s z8u#@TK1+JT_)NLE|I&?Zrze@g-t%&b!pI6*7A|0N%G>cLUnmaX|IDn4@=A#%&h<-O z$?EOE+|uqYxp@2*q+5u02}aEjDqHwntw~~{zmN?czGg3K4EDC{9`ptO6sCF9qg_g0 zX0Kh=TIFsk=a133R|f^hMJ!Z0cgmVWaZNG>(_LXZSd+QX6z*wANw?dLIZW=E)$?O? z(K?EAMXt!yDp_{j^NoQYzAPo;xbaa#*T^`#)N6qP;@s7>9x9H5ghQ(YH|yVj^Ac(@ zrk@C$&xP9Bage+KMPVV73ne}{2lOma#zJR9 zC>)&V6kTLWU(!g|>KQlC*2kf3ttC;l!?#BIDhJ;JX@KD)fIWD~TU>-LOx6t-9m!gs ztjMc5SsPDk_a8Y~R|KAga1ir&AnI|qI4neY9=#7ix9gPNr(j1BAa7U^Y~ux~+79Ur zISo9YYKDL*?2r*_Gr(|gpWJzth|p^oBGT2UKlc?cM)m~Koy!yWKJ8xwS%LA_?p{u# z8#g<3OQ|#WTSONOP(XW~*)@EvIvx!=hL3ORe>L5Fn#Fuf-`y$D)VaZhWc^akz4_F= zS?her-PM3u#g^Y5U-F45byatuN2zj{^vA&zJCGFhCwBMBd3?fb!oXUD?)9~^PYD=@BGQAW{>bt!pZ}ZuI zyd|?S^3*YY`u6M>1(C-_1S^FNgtNE~O~XJ}lHW1l*+CH4HYDna+zIcCb8&lC@oCyyJ)5EDK6&EO*& zkpo$Rs4b`oW1ajq?FD<2A!EAlovhNl%h%9lUn}r>jy9q%u*bm+Ccr_jiv~{OkJyl0QR09iUhM7=lr? z7yT8=1=Og)(FM^AoRuBi?P<>hR?q)yxs?mf(o)PV$mca|V(%EeG1NwB$L;>PKm>hS zeKl-eTkemmW)B{|dwhRcgLE>6VWZ)Y_Gd|UU++?dG-P(e~L@zG&5vjAEW{*m|xq~LvCG3AncjU zIu0JU10d!LCj_gn>AoO=h6JguIr#!}oiGiTB!e^tUZ5)l1xpBWzFnr-$J?T|EO$qB z#t>3(kNd(z+>T{hh7lYj`8Z;Ngp;(mKiyDel?gfGK(=~(nJ_57Uli)(wJq*Gk-5ulRs^rQqB#ejMCDqV+ehfZB$yWb*?;aQG-+Vw3b zuFy5W`J72KF-=2q+_)zqQb8fHWzBMc{^eJzN9hX}(Zx&ma6Fs*0fGBj`Cf;VerD>7 zj_)x>wqn?A-o;yz%g;@OIn)_2K->%yPwEPr`$S4N?!#rp`C6*VS|91FhN_W{%Wd z-;;)Jjy-8Z4H^rmo>i^nPDf3lisJ|e0!&}u(0g~#@mAY5yu99g0zk11T1+{n&)UMC zhveLNu}e=K3d`VtbO54cFN7$;sBMhCz=^5_KVL{=YriMI!DYjU~QrE%9; z^jo!d-Fm18p+>cWT*1{(K0?*2Q%@8{R!8ThAiE_*b=SMl=1lJDU|tYA<>juF`xJT> zs*y1!md8+?Y|%~byVaD_()FApK7TBa4Q5W@@T~rXlnUnFg;YHu@<5*b&7pOQ4`A#% z$3M5$x0x{#eWp3J_aCpQNj6ZE=mLEy&@u+f$Ut?+({jZ$WvJPnB6H1bRJHsxM*43^x7s=KU4+$3a;1r`jx`t&pT6Eu4Xk-ON#4pDO@Mmce zlmS(ZKR;8zKWuiU&du|d_{F#-^Ih9OuqugB&y`@1(mNohw0v7NzBgeWDPw z3L-265zhQGTT^(}yj|4vea%W)0LD-!h)Tl@(#%lRouw(3HJO-RUyDt{*m#tceDg0c zq4bFDJ}{yRyVw5r2cRMF`8VGgN24<&#pTgPu362l-c+ftoz?u1w}KmyiW`TU#<=C4 zfr81YaCsrs-5}TB_{KTsxR9#YPl@_R0X0R*6Nj;OaK&^bOgz6ko}~$omvd^Ffvf7B zV6?B1DAhZp)~H0yFo~!)$xVteoK%>^>hCWwm>EixnsB5_P6(tUTEO?bJJd8d#m=7W^DMBX2$B(E5^!tVoZBSE5a5RF9?(3L= zp-^`W)Yiz%Oj^u5E$lFXDbZ@cvh4h>WEUTi1Nn6NKLP~U58nDW< zL_L zA4%vGx+yiPWpoIO!O-`+KBjNAeYlQaHsenFglUKs(ea((4a3wo&1^z6+S?q+gApgW zq$mj!JNQ-I^4gnb3I#Z8gfX^!2g$A9ZgnI{iB%UXt?1BfjMJ-#(!^(b;GQ1}>oN+u z$4lgeK&knPn_HJI{S1w)0JHl#7J&&>|Y@K^D?Dv&i z@}aP8ghiH$X>(HkK;Lh>LlUm9bP7Ow00vFmVJWBo+JGuJhbn_F?GBEISx6-7UXZ~Z z3^l_C&U)L)9EoBzck0G=q?t)-p6Fi?F>>!uxEy(hm>@c(&j{SgXpic>PMie9l_ptl zIdgBuyhtPlo@CG;VLYcI*E}8RM9BUel^%64Dj+jof?uMzkR&FJqs;D%>Yn3W)Tc^A z5fs#v5S*41H!h6cu;{JwN6pvG`yxh$;V6;T6x2*rV4JKcy>D5~IIllyBHjDK;N7M! zZu&w&7%PbWGp8kH2F;;!^cSn@W_>;c%?x_2EGudPl6N(LHiQaE$hUldt5reCwf$8N zt|%vDFEB7(0J+Mz-f=KZ_{Z1aULp(*0ER28{(TPtP_Z%?bvx7l-T;kDsejUgD9aE* zK!a)D-?Ae1zqtWvOYpy`0Zw301N+1ua%X1fvE6$prkDJx8Dx``>$!!4P3E_V*S4$2=UAp5o+Wtu6nP-CsWuf$al>>whmH z4%WcHQjW_CgXTZ(s=;da|GnXrPZ&rI5qTaEYV+TG!(mPT<_u8zA?hEZ{;nrKwEDXw uR?PH=1Nq@VAWit;tN$Hi{@;hid4ZVGjue8^b7vTM9Xn!eT6D-g=Klappgcza literal 0 HcmV?d00001 diff --git a/iosapp/ios-poc/Assets.xcassets/Contents.json b/iosapp/ios-poc/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/iosapp/ios-poc/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/Contents.json b/iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/Contents.json new file mode 100644 index 00000000..5cacf0fb --- /dev/null +++ b/iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "gertrude-icon1x.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gertrude-icon2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "gertrude-icon3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/gertrude-icon1x.png b/iosapp/ios-poc/Assets.xcassets/GertrudeIcon.imageset/gertrude-icon1x.png new file mode 100644 index 0000000000000000000000000000000000000000..d724975f352487ec34e9238dfe4a9a8f3c12f405 GIT binary patch literal 5886 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 + + + + UILaunchScreen + + UIColorName + white + UIImageName + GertrudeIcon + + + diff --git a/iosapp/ios-poc/Preview Content/Preview Assets.xcassets/Contents.json b/iosapp/ios-poc/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/iosapp/ios-poc/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iosapp/ios-poc/Previews.swift b/iosapp/ios-poc/Previews.swift new file mode 100644 index 00000000..0b1ded8f --- /dev/null +++ b/iosapp/ios-poc/Previews.swift @@ -0,0 +1,7 @@ +import App +import SwiftUI + + +#Preview("LoadingScreen") { + LoadingScreen() +} diff --git a/iosapp/ios-poc/ios-poc.entitlements b/iosapp/ios-poc/ios-poc.entitlements new file mode 100644 index 00000000..0f42515e --- /dev/null +++ b/iosapp/ios-poc/ios-poc.entitlements @@ -0,0 +1,16 @@ + + + + + com.apple.developer.family-controls + + com.apple.developer.networking.networkextension + + content-filter-provider + + com.apple.security.application-groups + + group.com.gertrude-skunk.ios-poc + + + diff --git a/iosapp/ios-poc/ios_pocApp.swift b/iosapp/ios-poc/ios_pocApp.swift new file mode 100644 index 00000000..eed38306 --- /dev/null +++ b/iosapp/ios-poc/ios_pocApp.swift @@ -0,0 +1,23 @@ +import App +import SwiftUI +import ComposableArchitecture + +@main +struct ios_pocApp: App { + let store: StoreOf + + init() { + self.store = Store(initialState: .init()) { + AppReducer() + } + } + + var body: some Scene { + WindowGroup { + ContentView(store: self.store) + .onAppear { + self.store.send(.appLaunched) + } + } + } +} diff --git a/iosapp/lib-ios/Package.resolved b/iosapp/lib-ios/Package.resolved new file mode 100644 index 00000000..ab0da880 --- /dev/null +++ b/iosapp/lib-ios/Package.resolved @@ -0,0 +1,123 @@ +{ + "originHash" : "7cd15ad1fa8aaf83ad148fa4bb78ed2b0b9608033ad6e39929da31d436a1ee24", + "pins" : [ + { + "identity" : "combine-schedulers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/combine-schedulers", + "state" : { + "revision" : "9fa31f4403da54855f1e2aeaeff478f4f0e40b13", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-case-paths", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-case-paths", + "state" : { + "revision" : "bc92c4b27f9a84bfb498cdbfdf35d5a357e9161f", + "version" : "1.5.6" + } + }, + { + "identity" : "swift-clocks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-clocks", + "state" : { + "revision" : "b9b24b69e2adda099a1fa381cda1eeec272d5b53", + "version" : "1.0.5" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections", + "state" : { + "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7", + "version" : "1.1.4" + } + }, + { + "identity" : "swift-composable-architecture", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-composable-architecture", + "state" : { + "revision" : "8013f1a72af8ccb2b1735d7aed831a8dc07c6fd0", + "version" : "1.15.0" + } + }, + { + "identity" : "swift-concurrency-extras", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-concurrency-extras", + "state" : { + "revision" : "6054df64b55186f08b6d0fd87152081b8ad8d613", + "version" : "1.2.0" + } + }, + { + "identity" : "swift-custom-dump", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-custom-dump", + "state" : { + "revision" : "82645ec760917961cfa08c9c0c7104a57a0fa4b1", + "version" : "1.3.3" + } + }, + { + "identity" : "swift-dependencies", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-dependencies", + "state" : { + "revision" : "0fc0255e780bf742abeef29dec80924f5f0ae7b9", + "version" : "1.4.1" + } + }, + { + "identity" : "swift-identified-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-identified-collections", + "state" : { + "revision" : "2f5ab6e091dd032b63dacbda052405756010dc3b", + "version" : "1.1.0" + } + }, + { + "identity" : "swift-navigation", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-navigation", + "state" : { + "revision" : "d1bdbd8a5d1d1dfd2e4bb1f5e2f6facb631404d4", + "version" : "2.2.1" + } + }, + { + "identity" : "swift-perception", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-perception", + "state" : { + "revision" : "bc67aa8e461351c97282c2419153757a446ae1c9", + "version" : "1.3.5" + } + }, + { + "identity" : "swift-syntax", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-syntax", + "state" : { + "revision" : "0687f71944021d616d34d922343dcef086855920", + "version" : "600.0.1" + } + }, + { + "identity" : "xctest-dynamic-overlay", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/xctest-dynamic-overlay", + "state" : { + "revision" : "770f990d3e4eececb57ac04a6076e22f8c97daeb", + "version" : "1.4.2" + } + } + ], + "version" : 3 +} diff --git a/iosapp/lib-ios/Package.swift b/iosapp/lib-ios/Package.swift new file mode 100644 index 00000000..a3556daa --- /dev/null +++ b/iosapp/lib-ios/Package.swift @@ -0,0 +1,38 @@ +// swift-tools-version: 5.10 + +import PackageDescription + +let package = Package( + name: "App", + platforms: [.macOS(.v13), .iOS(.v17)], + products: [ + .library(name: "App", targets: ["App"]), + .library(name: "Filter", targets: ["Filter"]), + ], + dependencies: [ + .package( + url: "https://github.com/pointfreeco/swift-composable-architecture", + from: "1.0.0" + ), + ], + targets: [ + .target( + name: "App", + dependencies: [ + .product(name: "ComposableArchitecture", package: "swift-composable-architecture"), + ] + ), + .target( + name: "Filter", + dependencies: [] + ), + .testTarget( + name: "AppTests", + dependencies: ["App"] + ), + .testTarget( + name: "FilterTests", + dependencies: ["Filter"] + ), + ] +) diff --git a/iosapp/lib-ios/Sources/App/App+Install.swift b/iosapp/lib-ios/Sources/App/App+Install.swift new file mode 100644 index 00000000..64b6e1b0 --- /dev/null +++ b/iosapp/lib-ios/Sources/App/App+Install.swift @@ -0,0 +1,130 @@ +import FamilyControls +import NetworkExtension +import os.log + +// @see https://developer.apple.com/documentation/familycontrols/familycontrolserror +public enum AuthFailureReason: Error, Equatable { + // The device isn't signed into a valid iCloud account (also? .individual?) + case invalidAccountType + /// Another authorized app already provides parental controls + case authorizationConflict + case unexpected(Unexpected) + case other(String) + /// Device must be connected to the network in order to enroll with parental controls + case networkError + /// The device must have a passcode set in order for an individual to enroll with parental controls + case passcodeRequired + /// The parent or guardian cancelled a request for authorization + case authorizationCanceled + + public enum Unexpected: Equatable { + /// The method's arguments are invalid + case invalidArgument + /// The system failed to set up the Family Control famework + case unavailable + /// A restriction prevents your app from using Family Controls on this device + case restricted + } +} + +public enum FilterInstallError: Error, Equatable { + case configurationInvalid + case configurationDisabled + /// another process modified the filter configuration + /// since the last time the app loaded the configuration + case configurationStale + /// removing the configuration isn't allowed + case configurationCannotBeRemoved + case configurationPermissionDenied + case configurationInternalError + case unexpected(String) +} + +// TODO: extract into @Dependency +func requestAuthorization() async -> Result { + // TODO: figure out SPM things... + #if os(iOS) + do { + #if DEBUG + try await AuthorizationCenter.shared.requestAuthorization(for: .individual) + #else + try await AuthorizationCenter.shared.requestAuthorization(for: .child) + #endif + } catch let familyError as FamilyControlsError { + switch familyError { + case .invalidAccountType: + return .failure(.invalidAccountType) + case .authorizationConflict: + return .failure(.authorizationConflict) + case .authorizationCanceled: + return .failure(.authorizationCanceled) + case .networkError: + return .failure(.networkError) + case .authenticationMethodUnavailable: + return .failure(.passcodeRequired) + case .restricted: + return .failure(.unexpected(.restricted)) + case .unavailable: + return .failure(.unexpected(.unavailable)) + case .invalidArgument: + return .failure(.unexpected(.invalidArgument)) + @unknown default: + return .failure(.other(String(reflecting: familyError))) + } + } catch { + return .failure(.other(String(reflecting: error))) + } + #endif + return .success(()) +} + +func saveConfiguration() async -> Result { + // not sure this is necessary, but doesn't seem to hurt and might ensure clean slate + try? await NEFilterManager.shared().removeFromPreferences() + + if NEFilterManager.shared().providerConfiguration == nil { + let newConfiguration = NEFilterProviderConfiguration() + newConfiguration.username = "IOSPoc" + newConfiguration.organization = "GertrudeSkunk" + #if os(iOS) + newConfiguration.filterBrowsers = true + #endif + newConfiguration.filterSockets = true + NEFilterManager.shared().providerConfiguration = newConfiguration + } + NEFilterManager.shared().isEnabled = true + do { + try await NEFilterManager.shared().saveToPreferences() + return .success(()) + } catch { + switch NEFilterManagerError(rawValue: (error as NSError).code) { + case .some(.configurationInvalid): + return .failure(.configurationInvalid) + case .some(.configurationDisabled): + return .failure(.configurationDisabled) + case .some(.configurationStale): + return .failure(.configurationStale) + case .some(.configurationCannotBeRemoved): + return .failure(.configurationCannotBeRemoved) + case .some(.configurationPermissionDenied): + return .failure(.configurationPermissionDenied) + case .some(.configurationInternalError): + return .failure(.configurationInternalError) + case .none: + return .failure(.unexpected(String(reflecting: error))) + @unknown default: + return .failure(.unexpected(String(reflecting: error))) + } + } +} + +func isRunning() async -> Bool { + do { + try await NEFilterManager.shared().loadFromPreferences() + return NEFilterManager.shared().isEnabled + } catch { + print("Error loading preferences: \(error)") + os_log("[G•] error loading preferences (isRunning()): %{public}s", String(reflecting: error)) + return false + } +} diff --git a/iosapp/lib-ios/Sources/App/App.swift b/iosapp/lib-ios/Sources/App/App.swift new file mode 100644 index 00000000..a0a8c74a --- /dev/null +++ b/iosapp/lib-ios/Sources/App/App.swift @@ -0,0 +1,116 @@ +import ComposableArchitecture + +@Reducer +public struct AppReducer { + @ObservableState + public struct State: Equatable { + public var appState: AppState + + public init(appState: AppState = .launching) { + self.appState = appState + } + } + + // TODO: figure out why i can't use a root store enum + public enum AppState: Equatable { + case launching + case welcome + case prereqs + case authorizing + case authorizationFailed(AuthFailureReason) + case authorized + case installFailed(FilterInstallError) + case postInstall + case running + } + + public enum Action: Equatable { + case appLaunched + case welcomeNextTapped + case startAuthorizationTapped + case authorizationFailed(AuthFailureReason) + case authorizationSucceeded + case authorizationFailedTryAgainTapped + case installFailed(FilterInstallError) + case installFailedTryAgainTapped + case installSucceeded + case installFilterTapped + case postInstallOkTapped + case setRunning(Bool) + } + + public var body: some Reducer { + Reduce { state, action in + switch action { + + case .appLaunched: + return .run { send in + await send(.setRunning(await isRunning())) + } + + case .setRunning(true): + state.appState = .running + return .none + + case .setRunning(false): + state.appState = .welcome + return .none + + case .welcomeNextTapped: + state.appState = .prereqs + return .none + + case .startAuthorizationTapped: + state.appState = .authorizing + return .run { send in + switch await requestAuthorization() { + case .success: + await send(.authorizationSucceeded) + case .failure(let reason): + await send(.authorizationFailed(reason)) + } + } + + case .authorizationSucceeded: + state.appState = .authorized + return .none + + case .authorizationFailed(let reason): + state.appState = .authorizationFailed(reason) + return .none + + case .authorizationFailedTryAgainTapped: + state.appState = .welcome + return .none + + case .installFilterTapped: + return .run { send in + switch await saveConfiguration() { + case .success: + await send(.installSucceeded) + case .failure(let error): + await send(.installFailed(error)) + } + } + + case .installFailed(let error): + state.appState = .installFailed(error) + return .none + + case .installFailedTryAgainTapped: + // TODO: clean up for retry + return .none + + case .installSucceeded: + state.appState = .postInstall + return .none + + case .postInstallOkTapped: + state.appState = .running + return .none + } + } + } + + public init() {} +} diff --git a/iosapp/lib-ios/Sources/App/AuthFailed.swift b/iosapp/lib-ios/Sources/App/AuthFailed.swift new file mode 100644 index 00000000..db4e4aac --- /dev/null +++ b/iosapp/lib-ios/Sources/App/AuthFailed.swift @@ -0,0 +1,64 @@ +import SwiftUI + +struct AuthFailed: View { + var reason: AuthFailureReason + var onTryAgain: () -> Void + + var body: some View { + VStack(spacing: 20) { + switch self.reason { + case .networkError: + Text( + "You must be connected to the internet in order to complete the parent/guardian authorization step." + ) + case .authorizationConflict: + Text( + "Failed to authorize due to conflict. You might already have another app managing parental controls. Disable that app to continue using Gertrude." + ) + case .invalidAccountType: + Text("Apple account error. Please confirm that:") + VStack(alignment: .leading) { + Text("The \(self.deviceType) user is logged into iCloud") + Text("The \(self.deviceType) user is under 18") + Text("The \(self.deviceType) user is enrolled in an Apple Family") + }.font(.footnote) + case .unexpected, .other: + // TODO: log, contact support, etc. + Text("An unexpected error occurred, please try again.") + case .passcodeRequired: + Text( + "Failed to authorize. A passcode is required in order to enable parental controls." + ) + case .authorizationCanceled: + Text("Failed to authorize. The parent/guardian canceled the authorization.") + } + Button("OK") { + self.onTryAgain() + } + } + } +} + +#Preview("No internet") { + AuthFailed(reason: .networkError, onTryAgain: {}) +} + +#Preview("Conflict") { + AuthFailed(reason: .authorizationConflict, onTryAgain: {}) +} + +#Preview("Invalid account") { + AuthFailed(reason: .invalidAccountType, onTryAgain: {}) +} + +#Preview("Unexpected/other") { + AuthFailed(reason: .unexpected(.restricted), onTryAgain: {}) +} + +#Preview("Canceled") { + AuthFailed(reason: .authorizationCanceled, onTryAgain: {}) +} + +#Preview("Need passcode") { + AuthFailed(reason: .passcodeRequired, onTryAgain: {}) +} diff --git a/iosapp/lib-ios/Sources/App/ContentView.swift b/iosapp/lib-ios/Sources/App/ContentView.swift new file mode 100644 index 00000000..a4dbf738 --- /dev/null +++ b/iosapp/lib-ios/Sources/App/ContentView.swift @@ -0,0 +1,161 @@ +import ComposableArchitecture +import SwiftUI + +public struct ContentView: View { + let store: StoreOf + + public init(store: StoreOf) { + self.store = store + } + + public var body: some View { + VStack { + switch self.store.appState { + case .launching: + EmptyView() + + case .welcome: + VStack(spacing: 15) { + Text("Welcome!") + .font(.title) + Text("Gertrude fills in the gaps in Apple’s parental controls, including:") + VStack(alignment: .leading) { + Text("- blocking GIFs in the #images iMessage texting app") + Text("- blocking GIFs in WhatsApp, Skype, and other messaging apps") + Text("- disabling internet image searching from Spotlight") + }.font(.footnote) + Button("Get Started ->") { + self.store.send(.welcomeNextTapped) + } + } + + case .authorizing: + LoadingScreen() + + case .authorized: + VStack(spacing: 20) { + Text("Authorization granted! One more step: install the content filter.") + Button("Install Filter") { + self.store.send(.installFilterTapped) + } + } + + case .authorizationFailed(let reason): + AuthFailed(reason: reason) { + self.store.send(.authorizationFailedTryAgainTapped) + } + + case .prereqs: + VStack(spacing: 20) { + Text("In order to safely use Gertrude") + VStack(alignment: .leading) { + Text("- the \(self.deviceType) user must be logged into iCloud") + Text("- the \(self.deviceType) user must be under 18") + Text("- the \(self.deviceType) user must be part of an Apple Family") + Text("- the \(self.deviceType) user must be restricted from deleting apps") + }.font(.footnote) + Button("Start authorization") { + self.store.send(.startAuthorizationTapped) + } + } + + case .installFailed(let error): + VStack(spacing: 20) { + Text("Filter setup failed with an error:") + Group { + switch error { + case .configurationInvalid: + Text("Configuration is invalid.") + case .configurationDisabled: + Text("Configuration is disabled.") + case .configurationStale: + Text("Configuration is stale.") + case .configurationCannotBeRemoved: + Text("Configuration can not be removed.") + case .configurationPermissionDenied: + Text("Permission denied.") + case .configurationInternalError: + Text("Internal error.") + case .unexpected(let underlying): + Text("Unexpected error: \(underlying)") + } + }.font(.footnote) + Button("Try again") { + self.store.send(.installFailedTryAgainTapped) + } + } + + case .postInstall: + VStack(spacing: 20) { + Text("Filter installed successfully!") + Text("Good to know:") + VStack(alignment: .leading, spacing: 12) { + Text( + "Previously loaded GIFs will still be visible, so if you want to test that the filter is working, try searching for a new GIF." + ) + Text("You can quit this app now—it will keep blocking even when not running.") + Text( + "Use Screen Time restrictions to make sure this \(self.deviceType) user can’t delete apps. Deleting the app removes the content filter." + ) + Text("Questions? Drop us a line at https://gertrude.app/contact.") + + }.font(.footnote) + Button("OK") { + self.store.send(.postInstallOkTapped) + } + } + + case .running: + VStack(spacing: 20) { + Text("Gertrude is blocking GIFs and image searches.") + VStack(alignment: .leading, spacing: 12) { + Text("You can quit this app now—it will keep blocking even when not running.") + Text("Questions? Drop us a line at https://gertrude.app/contact.") + + }.font(.footnote) + } + } + } + .padding() + } +} + +extension View { + var deviceType: String { + #if os(iOS) + UIDevice.current.userInterfaceIdiom == .pad ? "iPad" : "iPhone" + #else + "iPhone" + #endif + } +} + +// previews + +#Preview("Welcome") { + app(state: .welcome) +} + +#Preview("Prereqs") { + app(state: .prereqs) +} + +#Preview("Install Fail") { + app(state: .installFailed(.configurationPermissionDenied)) +} + +#Preview("Post-install") { + app(state: .postInstall) +} + +#Preview("Running") { + app(state: .running) +} + +private func app(state: AppReducer.AppState) -> some View { + ContentView( + store: Store(initialState: .init(appState: state)) { + AppReducer() + } + ) +} diff --git a/iosapp/lib-ios/Sources/App/LoadingScreen.swift b/iosapp/lib-ios/Sources/App/LoadingScreen.swift new file mode 100644 index 00000000..4e86a142 --- /dev/null +++ b/iosapp/lib-ios/Sources/App/LoadingScreen.swift @@ -0,0 +1,26 @@ +import SwiftUI + +public struct LoadingScreen: View { + @State private var rotation = 0.0 + + public var body: some View { + Image("GertrudeIcon", bundle: Bundle.main) + .frame(width: 20, height: 20) + .opacity(0.5) + .rotationEffect(.degrees(rotation)) + .onAppear { + withAnimation( + .linear(duration: 1) + .speed(1.2).repeatForever(autoreverses: false) + ) { + rotation = 360.0 + } + } + } + + public init() {} +} + +#Preview { + LoadingScreen() +} diff --git a/iosapp/lib-ios/Sources/Filter/Filter.swift b/iosapp/lib-ios/Sources/Filter/Filter.swift new file mode 100644 index 00000000..fa448142 --- /dev/null +++ b/iosapp/lib-ios/Sources/Filter/Filter.swift @@ -0,0 +1,24 @@ +public func decideFlow(hostname: String?, url: String?, sourceId: String?) -> Bool { + if sourceId?.contains("HashtagImagesExtension") == true { + return false + } else if sourceId?.contains("com.apple.Spotlight") == true { + return false + } + + if url?.contains("tenor.co") == true { + return false + } + + if let target = url ?? hostname { + if target.contains("cdn2.smoot.apple.com") { + return false + } else if target.contains("tenor.co") { + return false + } else if target.contains("giphy.com") { + return false + } else if target.contains("media.fosu2-1.fna.whatsapp.net") { + return false + } + } + return true +} diff --git a/iosapp/lib-ios/Tests/AppTests/AppTests.swift b/iosapp/lib-ios/Tests/AppTests/AppTests.swift new file mode 100644 index 00000000..ab2d035a --- /dev/null +++ b/iosapp/lib-ios/Tests/AppTests/AppTests.swift @@ -0,0 +1,8 @@ +import App +import XCTest + +final class AppTests: XCTestCase { + func testPlaceholder() throws { + XCTAssertTrue(true) + } +} diff --git a/iosapp/lib-ios/Tests/FilterTests/FilterTests.swift b/iosapp/lib-ios/Tests/FilterTests/FilterTests.swift new file mode 100644 index 00000000..47af8f0d --- /dev/null +++ b/iosapp/lib-ios/Tests/FilterTests/FilterTests.swift @@ -0,0 +1,23 @@ +import Filter +import XCTest + +final class FilterTests: XCTestCase { + func testDecideFlow() throws { + let cases: [(host: String?, url: String?, src: String, allow: Bool)] = [ + (host: nil, url: nil, src: "HashtagImagesExtension", allow: false), + (host: nil, url: nil, src: ".com.apple.Spotlight", allow: false), + (host: nil, url: nil, src: "com.widget", allow: true), + (host: "cdn2.smoot.apple.com", url: nil, src: "com.widget", allow: false), + (host: "media.tenor.co", url: nil, src: "com.widget", allow: false), + (host: "wa.tenor.co", url: nil, src: "com.widget", allow: false), + (host: "api.tenor.com", url: nil, src: "AL798K98FX.com.skype.skype", allow: false), + (host: "giphy.com", url: nil, src: "com.widget", allow: false), + (host: "media0.giphy.com", url: nil, src: "com.widget", allow: false), + (host: "media.fosu2-1.fna.whatsapp.net", url: nil, src: "", allow: false), + ] + + for (host, url, src, expected) in cases { + XCTAssertEqual(decideFlow(hostname: host, url: url, sourceId: src), expected) + } + } +} diff --git a/justfile b/justfile index 426ca09e..29795412 100644 --- a/justfile +++ b/justfile @@ -21,6 +21,11 @@ codegen: codegen-typescript codegen-swift xcode: @open macapp/Xcode/Gertrude.xcodeproj +# ios + +watch-ios: + @just watch-build iosapp/lib-ios + # api watch-api: