diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml index fd481bf343..3d3ba3c8af 100644 --- a/.github/workflows/alpha.yml +++ b/.github/workflows/alpha.yml @@ -89,7 +89,7 @@ jobs: run: | app_version="$(cut -d ' ' -f 3 < Configuration/Version.xcconfig)" bundle exec fastlane increment_build_number_for_version version:$app_version app_identifier:"com.duckduckgo.mobile.ios.alpha" - bundle exec fastlane release_alpha groups:"${{ env.destination }}" + bundle exec fastlane release_alpha groups:["${{ env.destination }}"] build_version="$(xcodebuild -configuration Alpha -showBuildSettings | grep CURRENT_PROJECT_VERSION | tr -d 'CURRENT_PROJECT_VERSION =')" echo "dsyms_path=${{ github.workspace }}/DuckDuckGo-Alpha.app.dSYM.zip" >> $GITHUB_ENV echo "app_version=${app_version}" >> $GITHUB_ENV diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 3fc6578624..f76b16274a 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -1,6 +1,6 @@ name: PR Checks -on: +on: push: branches: [ develop, "release/**" ] pull_request: @@ -13,13 +13,11 @@ jobs: runs-on: ubuntu-latest steps: - - name: Check out the code - uses: actions/checkout@v3 - - - name: Run SwiftLint on all files - uses: norio-nomura/action-swiftlint@3.2.1 + - uses: actions/checkout@v3 + - name: SwiftLint + uses: docker://norionomura/swiftlint:0.53.0 with: - args: --strict --force-exclude + args: swiftlint --reporter github-actions-logging --strict shellcheck: @@ -44,6 +42,9 @@ jobs: runs-on: macos-13 timeout-minutes: 30 + outputs: + commit_author: ${{ steps.fetch_commit_author.outputs.commit_author }} + steps: - name: Check out the code uses: actions/checkout@v3 @@ -112,6 +113,16 @@ jobs: | sort -u -k 1,2 \ | xargs -L 1 ./scripts/report-failed-unit-test.sh -s ${{ vars.APPLE_CI_FAILING_TESTS_FAILED_TESTS_SECTION_ID }} + - name: Fetch latest commit author + if: always() && github.ref_name == 'develop' + id: fetch_commit_author + env: + GH_TOKEN: ${{ github.token }} + run: | + head_commit=$(git rev-parse HEAD) + author=$(gh api https://api.github.com/repos/${{ github.repository }}/commits/${head_commit} --jq .author.login) + echo "commit_author=${author}" >> $GITHUB_OUTPUT + release-build: name: Make Release Build @@ -174,24 +185,35 @@ jobs: -configuration "Release" \ | xcbeautify - asana: + create-asana-task: name: Create Asana Task needs: [swiftlint, unit-tests, shellcheck, release-build] - if: failure() && github.ref_name == 'develop' - - env: - WORKFLOW_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} - + if: failure() && github.ref_name == 'develop' && github.run_attempt == 1 + runs-on: ubuntu-latest steps: - name: Create Asana Task - uses: malmstein/github-asana-action@master + uses: duckduckgo/BrowserServicesKit/.github/actions/asana-failed-pr-checks@main + with: + action: create-task + asana-access-token: ${{ secrets.ASANA_ACCESS_TOKEN }} + asana-section-id: ${{ vars.APPLE_CI_FAILING_TESTS_IOS_POST_MERGE_SECTION_ID }} + commit-author: ${{ needs.unit-tests.outputs.commit_author }} + + close-asana-task: + name: Close Asana Task + needs: [swiftlint, unit-tests, shellcheck, release-build] + + if: success() && github.ref_name == 'develop' && github.run_attempt > 1 + + runs-on: ubuntu-latest + + steps: + - name: Close Asana Task + uses: duckduckgo/BrowserServicesKit/.github/actions/asana-failed-pr-checks@main with: - asana-pat: ${{ secrets.ASANA_ACCESS_TOKEN }} - asana-project: ${{ vars.APPLE_CI_FAILING_TESTS_PROJECT_ID }} - asana-section: ${{ vars.APPLE_CI_FAILING_TESTS_IOS_POST_MERGE_SECTION_ID }} - asana-task-name: 'PR Check is failing on develop' - action: create-asana-task - asana-task-description: PR Checks conducted after merging have failed. See ${{ env.WORKFLOW_URL }}. Follow the steps on https://app.asana.com/0/1202500774821704/1205317064731691 to resolve this issue. + action: close-task + asana-access-token: ${{ secrets.ASANA_ACCESS_TOKEN }} + asana-section-id: ${{ vars.APPLE_CI_FAILING_TESTS_IOS_POST_MERGE_SECTION_ID }} diff --git a/Configuration/Version.xcconfig b/Configuration/Version.xcconfig index e513c6b471..86866ee7eb 100644 --- a/Configuration/Version.xcconfig +++ b/Configuration/Version.xcconfig @@ -1 +1 @@ -MARKETING_VERSION = 7.91.1 +MARKETING_VERSION = 7.92.0 diff --git a/Core/AppPrivacyConfigurationDataProvider.swift b/Core/AppPrivacyConfigurationDataProvider.swift index 9243d613f2..56755c581d 100644 --- a/Core/AppPrivacyConfigurationDataProvider.swift +++ b/Core/AppPrivacyConfigurationDataProvider.swift @@ -23,8 +23,8 @@ import BrowserServicesKit final public class AppPrivacyConfigurationDataProvider: EmbeddedDataProvider { public struct Constants { - public static let embeddedDataETag = "\"30f2a2ffc762a0b87627dc218ba71b7e\"" - public static let embeddedDataSHA = "985db4a0b3bb35e7b116ace9bcffbfed40275a10ec39bbbb52d84de76a6769c9" + public static let embeddedDataETag = "\"54efb258435567856e087913f93d43df\"" + public static let embeddedDataSHA = "d0f9c70c5baba23a0966b277f8b4c949ecf01612558a50d2bda720fe1919b43f" } public var embeddedDataEtag: String { diff --git a/Core/AppTrackerDataSetProvider.swift b/Core/AppTrackerDataSetProvider.swift index eb85b243d0..edcbbad058 100644 --- a/Core/AppTrackerDataSetProvider.swift +++ b/Core/AppTrackerDataSetProvider.swift @@ -23,8 +23,8 @@ import BrowserServicesKit final public class AppTrackerDataSetProvider: EmbeddedDataProvider { public struct Constants { - public static let embeddedDataETag = "\"c9a18e593a4f5f8d32a18db294497226\"" - public static let embeddedDataSHA = "6264eb92240fee69aeebb14aa333bdc8d76b2818fb7f44f0acb1fb0373d50af4" + public static let embeddedDataETag = "\"a1bb76901a395eb251cd6f30f54037f1\"" + public static let embeddedDataSHA = "53cad742076d1382fba8db0e508307668eb0609738d526cb16cbc623b50410fc" } public var embeddedDataEtag: String { diff --git a/Core/NetworkProtectionNotificationIdentifier.swift b/Core/NetworkProtectionNotificationIdentifier.swift new file mode 100644 index 0000000000..66a29dcebd --- /dev/null +++ b/Core/NetworkProtectionNotificationIdentifier.swift @@ -0,0 +1,28 @@ +// +// NetworkProtectionNotificationIdentifier.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +public enum NetworkProtectionNotificationIdentifier: String { + case reconnecting = "network-protection.notification.reconnecting" + case reconnected = "network-protection.notification.reconnected" + case connectionFailure = "network-protection.notification.connection-failure" + case superseded = "network-protection.notification.superseded" + case test = "network-protection.notification.test" +} diff --git a/Core/UIViewControllerExtension.swift b/Core/UIViewControllerExtension.swift index da622a8980..f37bca411b 100644 --- a/Core/UIViewControllerExtension.swift +++ b/Core/UIViewControllerExtension.swift @@ -27,7 +27,7 @@ extension UIViewController { } var isPad: Bool { - return traitCollection.horizontalSizeClass == .regular + return UIDevice.current.userInterfaceIdiom == .pad } @objc func buildActivities() -> [UIActivity] { diff --git a/Core/UserAgentManager.swift b/Core/UserAgentManager.swift index 811293ca45..577922f317 100644 --- a/Core/UserAgentManager.swift +++ b/Core/UserAgentManager.swift @@ -85,8 +85,16 @@ public class DefaultUserAgentManager: UserAgentManager { } struct UserAgent { + + private enum DefaultPolicy: String { + + case ddg + case ddgFixed + case closest + + } - private struct Constants { + private enum Constants { // swiftlint:disable line_length static let fallbackWekKitVersion = "605.1.15" static let fallbackSafariComponent = "Safari/\(fallbackWekKitVersion)" @@ -96,6 +104,16 @@ struct UserAgent { static let uaOmitSitesConfigKey = "omitApplicationSites" static let uaOmitDomainConfigKey = "domain" + + static let defaultPolicyConfigKey = "defaultPolicy" + static let ddgDefaultSitesConfigKey = "ddgDefaultSites" + static let ddgFixedSitesConfigKey = "ddgFixedSites" + + static let closestUserAgentConfigKey = "closestUserAgent" + static let ddgFixedUserAgentConfigKey = "ddgFixedUserAgent" + + static let uaVersionsKey = "versions" + static let uaStateKey = "state" // swiftlint:enable line_length } @@ -110,12 +128,15 @@ struct UserAgent { private let versionComponent: String private let safariComponent: String private let applicationComponent = "DuckDuckGo/\(AppVersion.shared.majorVersionNumber)" + private let statistics: StatisticsStore + private let isTesting: Bool = ProcessInfo().arguments.contains("testing") - init(defaultAgent: String = Constants.fallbackDefaultAgent) { + init(defaultAgent: String = Constants.fallbackDefaultAgent, statistics: StatisticsStore = StatisticsUserDefaults()) { versionComponent = UserAgent.createVersionComponent(fromAgent: defaultAgent) baseAgent = UserAgent.createBaseAgent(fromAgent: defaultAgent, versionComponent: versionComponent) baseDesktopAgent = UserAgent.createBaseDesktopAgent(fromAgent: defaultAgent, versionComponent: versionComponent) safariComponent = UserAgent.createSafariComponent(fromAgent: baseAgent) + self.statistics = statistics } private func omitApplicationSites(forConfig config: PrivacyConfiguration) -> [String] { @@ -124,24 +145,160 @@ struct UserAgent { return omitApplicationObjs.map { $0[Constants.uaOmitDomainConfigKey] ?? "" } } - - public func agent(forUrl url: URL?, isDesktop: Bool, + + private func defaultPolicy(forConfig config: PrivacyConfiguration) -> DefaultPolicy { + let uaSettings = config.settings(for: .customUserAgent) + guard let policy = uaSettings[Constants.defaultPolicyConfigKey] as? String else { return .ddg } + + return DefaultPolicy(rawValue: policy) ?? .ddg + } + + private func ddgDefaultSites(forConfig config: PrivacyConfiguration) -> [String] { + let uaSettings = config.settings(for: .customUserAgent) + let defaultSitesObjs = uaSettings[Constants.ddgDefaultSitesConfigKey] as? [[String: String]] ?? [] + + return defaultSitesObjs.map { $0[Constants.uaOmitDomainConfigKey] ?? "" } + } + + private func ddgFixedSites(forConfig config: PrivacyConfiguration) -> [String] { + let uaSettings = config.settings(for: .customUserAgent) + let fixedSitesObjs = uaSettings[Constants.ddgFixedSitesConfigKey] as? [[String: String]] ?? [] + + return fixedSitesObjs.map { $0[Constants.uaOmitDomainConfigKey] ?? "" } + } + + private func closestUserAgentVersions(forConfig config: PrivacyConfiguration) -> [String] { + let uaSettings = config.settings(for: .customUserAgent) + let closestUserAgent = uaSettings[Constants.closestUserAgentConfigKey] as? [String: Any] ?? [:] + let versions = closestUserAgent[Constants.uaVersionsKey] as? [String] ?? [] + return versions + } + + private func ddgFixedUserAgentVersions(forConfig config: PrivacyConfiguration) -> [String] { + let uaSettings = config.settings(for: .customUserAgent) + let fixedUserAgent = uaSettings[Constants.ddgFixedUserAgentConfigKey] as? [String: Any] ?? [:] + let versions = fixedUserAgent[Constants.uaVersionsKey] as? [String] ?? [] + return versions + } + + public func agent(forUrl url: URL?, + isDesktop: Bool, privacyConfig: PrivacyConfiguration = ContentBlocking.shared.privacyConfigurationManager.privacyConfig) -> String { + + guard privacyConfig.isEnabled(featureKey: .customUserAgent) else { return oldLogic(forUrl: url, + isDesktop: isDesktop, + privacyConfig: privacyConfig) } + + if ddgDefaultSites(forConfig: privacyConfig).contains(where: { domain in + url?.isPart(ofDomain: domain) ?? false + }) { return oldLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) } + + if ddgFixedSites(forConfig: privacyConfig).contains(where: { domain in + url?.isPart(ofDomain: domain) ?? false + }) { return ddgFixedLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) } + + if closestUserAgentVersions(forConfig: privacyConfig).contains(statistics.atbWeek ?? "") { + if canUseClosestLogic { + return closestLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + } else { + return oldLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + } + } + + if ddgFixedUserAgentVersions(forConfig: privacyConfig).contains(statistics.atbWeek ?? "") { + return ddgFixedLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + } + + switch defaultPolicy(forConfig: privacyConfig) { + case .ddg: return oldLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + case .ddgFixed: return ddgFixedLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + case .closest: + if canUseClosestLogic { + return closestLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + } else { + return oldLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + } + } + } + + private func oldLogic(forUrl url: URL?, + isDesktop: Bool, + privacyConfig: PrivacyConfiguration) -> String { let omittedSites = omitApplicationSites(forConfig: privacyConfig) let customUAEnabled = privacyConfig.isEnabled(featureKey: .customUserAgent) let omitApplicationComponent = !customUAEnabled || omittedSites.contains { domain in url?.isPart(ofDomain: domain) ?? false } - + let resolvedApplicationComponent = !omitApplicationComponent ? applicationComponent : nil + if isDesktop { return concatWithSpaces(baseDesktopAgent, resolvedApplicationComponent, safariComponent) } else { return concatWithSpaces(baseAgent, resolvedApplicationComponent, safariComponent) } } - + + private func ddgFixedLogic(forUrl url: URL?, + isDesktop: Bool, + privacyConfig: PrivacyConfiguration) -> String { + let omittedSites = omitApplicationSites(forConfig: privacyConfig) + let omitApplicationComponent = omittedSites.contains { domain in + url?.isPart(ofDomain: domain) ?? false + } + let resolvedApplicationComponent = !omitApplicationComponent ? applicationComponent : nil + + if canUseClosestLogic { + var defaultSafari = closestLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + // If the UA should have DuckDuckGo append it prior to Safari + if let resolvedApplicationComponent { + if let index = defaultSafari.range(of: "Safari")?.lowerBound { + defaultSafari.insert(contentsOf: resolvedApplicationComponent + " ", at: index) + } + } + return defaultSafari + } else { + return oldLogic(forUrl: url, isDesktop: isDesktop, privacyConfig: privacyConfig) + } + } + + private func closestLogic(forUrl url: URL?, + isDesktop: Bool, + privacyConfig: PrivacyConfiguration) -> String { + if isDesktop { + return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15" + } + return "Mozilla/5.0 (" + deviceProfile + ") AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1" + } + + private var canUseClosestLogic: Bool { + guard let webKitVersion else { return false } + return webKitVersion.versionCompare("605.1.15") != .orderedAscending + } + + private var webKitVersion: String? { + let components = baseAgent.components(separatedBy: "AppleWebKit/") + + if components.count > 1 { + let versionComponents = components[1].components(separatedBy: " ") + return versionComponents.first + } + + return nil + } + + var deviceProfile: String { + let regex = try? NSRegularExpression(pattern: "\\((.*?)\\)") + if let match = regex?.firstMatch(in: baseAgent, range: NSRange(baseAgent.startIndex..., in: baseAgent)) { + let range = Range(match.range(at: 1), in: baseAgent) + if let range = range { + return String(baseAgent[range]) + } + } + return "iPhone; CPU iPhone OS 16_6 like Mac OS X" + } + private func concatWithSpaces(_ elements: String?...) -> String { return elements .compactMap { $0 } @@ -205,3 +362,26 @@ struct UserAgent { } } + +private extension StatisticsStore { + + var atbWeek: String? { + guard let atb else { return nil } + let trimmed = String(atb.dropFirst()) + + if let hyphenIndex = trimmed.firstIndex(of: "-") { + return String(trimmed.prefix(upTo: hyphenIndex)) + } else { + return trimmed + } + } + +} + +private extension String { + + func versionCompare(_ otherVersion: String) -> ComparisonResult { + compare(otherVersion, options: .numeric) + } + +} diff --git a/Core/ios-config.json b/Core/ios-config.json index 5d3b95fa24..b9847b8298 100644 --- a/Core/ios-config.json +++ b/Core/ios-config.json @@ -1,6 +1,6 @@ { "readme": "https://github.com/duckduckgo/privacy-configuration", - "version": 1695742642039, + "version": 1695828991975, "features": { "adClickAttribution": { "readme": "https://help.duckduckgo.com/duckduckgo-help-pages/privacy/web-tracking-protections/#3rd-party-tracker-loading-protection", @@ -313,6 +313,66 @@ { "domain": "roll20.net", "reason": "Performance issue for too many fields." + }, + { + "domain": "amazon.ca", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.cn", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.co.jp", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.com", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.com.au", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.com.mx", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.co.uk", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.de", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.es", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.eu", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.fr", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.in", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.it", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.nl", + "reason": "Performance issue, infinite loop." + }, + { + "domain": "amazon.sa", + "reason": "Performance issue, infinite loop." } ], "state": "enabled", @@ -338,7 +398,7 @@ "minSupportedVersion": "7.75.0" } }, - "hash": "0050520033bd94b10474e9d2f649f8f9" + "hash": "c427670d1be007f3bd4af4c0e83addfb" }, "clickToLoad": { "exceptions": [ @@ -7362,6 +7422,10 @@ { "domain": "paramountplus.com", "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1085" + }, + { + "domain": "theverge.com", + "reason": "https://github.com/duckduckgo/privacy-configuration/issues/1326" } ], "settings": { @@ -7394,7 +7458,7 @@ ] }, "state": "enabled", - "hash": "d999feeb71ba8e37839b7ed5e267d365" + "hash": "aab19f2fd45ded0765912ee266c309df" }, "userAgentRotation": { "settings": { diff --git a/Core/trackerData.json b/Core/trackerData.json index f15dd18e3a..3de737a946 100644 --- a/Core/trackerData.json +++ b/Core/trackerData.json @@ -1,6 +1,6 @@ { "_builtWith": { - "tracker-radar": "57775dc368381de2672ec8875583340037a13847ef33ffd176974a8f2d7e7ac9-4013b4e91930c643394cb31c6c745356f133b04f", + "tracker-radar": "6eb8582c70d4e62ccb4b23113fc8bfdeb9b945b8ba986a60e71ab693af87e755-4013b4e91930c643394cb31c6c745356f133b04f", "tracker-surrogates": "d61691a2fdf9f4dc062a8d248fd1e78c20b5b892" }, "readme": "https://github.com/duckduckgo/tracker-blocklists", @@ -482,7 +482,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -493,7 +493,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -539,7 +539,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -2417,7 +2417,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -2428,7 +2428,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -2472,7 +2472,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -2483,7 +2483,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -2593,8 +2593,10 @@ "amazon.dev": { "domain": "amazon.dev", "owner": { - "name": "amazon.dev", - "displayName": "amazon.dev" + "name": "Amazon Technologies, Inc.", + "displayName": "Amazon.com", + "privacyPolicy": "https://www.amazon.com/gp/help/customer/display.html?nodeId=468496", + "url": "http://www.amazon.com/" }, "prevalence": 0.0842, "fingerprinting": 0, @@ -2608,7 +2610,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -2747,7 +2749,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -2758,7 +2760,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3077,7 +3079,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3204,7 +3206,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3328,7 +3330,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3712,7 +3714,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3723,7 +3725,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3734,7 +3736,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3745,7 +3747,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3811,7 +3813,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3863,7 +3865,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -3874,7 +3876,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -4011,7 +4013,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -4362,7 +4364,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -4397,7 +4399,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -4848,7 +4850,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -4859,7 +4861,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5061,7 +5063,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5103,7 +5105,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5126,7 +5128,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5161,7 +5163,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5190,7 +5192,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5478,7 +5480,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5595,7 +5597,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5606,7 +5608,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5617,7 +5619,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5628,7 +5630,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5665,7 +5667,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -5720,7 +5722,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -6256,7 +6258,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -6415,7 +6417,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -6731,7 +6733,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -6742,7 +6744,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -6866,7 +6868,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7062,7 +7064,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7098,7 +7100,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7109,7 +7111,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7120,7 +7122,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7703,7 +7705,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7714,7 +7716,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7725,7 +7727,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7801,7 +7803,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7924,7 +7926,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -7935,7 +7937,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8013,7 +8015,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8024,7 +8026,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8139,7 +8141,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8282,7 +8284,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8293,7 +8295,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8819,7 +8821,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8830,7 +8832,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -8871,7 +8873,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -9287,7 +9289,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -9897,7 +9899,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -9908,7 +9910,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -9919,7 +9921,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -9959,7 +9961,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10001,7 +10003,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10075,7 +10077,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10143,7 +10145,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10154,7 +10156,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10202,7 +10204,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10328,7 +10330,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10488,7 +10490,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10499,7 +10501,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10510,7 +10512,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10537,7 +10539,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10587,7 +10589,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -10634,7 +10636,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -11113,7 +11115,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -11153,7 +11155,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -11846,7 +11848,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -11933,7 +11935,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -11944,7 +11946,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12176,7 +12178,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12216,7 +12218,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12227,7 +12229,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12238,7 +12240,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12249,7 +12251,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12575,7 +12577,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12586,7 +12588,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -12597,7 +12599,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -14520,7 +14522,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -15205,7 +15207,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -15280,7 +15282,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -15331,7 +15333,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16153,7 +16155,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16164,7 +16166,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16192,7 +16194,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16411,7 +16413,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16719,7 +16721,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16730,7 +16732,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16915,7 +16917,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -16964,7 +16966,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -17238,7 +17240,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -17249,7 +17251,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -17812,7 +17814,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -18124,7 +18126,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -18263,7 +18265,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -18613,7 +18615,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -18843,7 +18845,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20032,7 +20034,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20253,7 +20255,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20264,7 +20266,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20275,7 +20277,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20383,7 +20385,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20860,7 +20862,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20889,7 +20891,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20900,7 +20902,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20911,7 +20913,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -20975,7 +20977,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21055,7 +21057,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21103,7 +21105,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21114,7 +21116,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21159,7 +21161,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21170,7 +21172,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21205,7 +21207,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21216,7 +21218,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21349,7 +21351,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21440,7 +21442,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21911,7 +21913,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21922,7 +21924,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -21933,7 +21935,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22003,7 +22005,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22014,7 +22016,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22167,7 +22169,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22178,7 +22180,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22220,7 +22222,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22231,7 +22233,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22242,7 +22244,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22512,7 +22514,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22523,7 +22525,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22584,7 +22586,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22642,7 +22644,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22653,7 +22655,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22753,7 +22755,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22776,7 +22778,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -22787,7 +22789,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23128,7 +23130,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23232,7 +23234,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23629,7 +23631,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23704,7 +23706,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23715,7 +23717,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23759,7 +23761,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23770,7 +23772,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23781,7 +23783,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23792,7 +23794,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23872,7 +23874,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23905,7 +23907,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -23956,7 +23958,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24092,7 +24094,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24221,7 +24223,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24232,7 +24234,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24479,7 +24481,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24490,7 +24492,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24501,7 +24503,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24782,7 +24784,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24817,7 +24819,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24858,7 +24860,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24974,7 +24976,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -24985,7 +24987,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25014,7 +25016,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25110,7 +25112,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25167,7 +25169,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25178,7 +25180,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25299,7 +25301,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25456,7 +25458,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25482,7 +25484,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25493,7 +25495,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25556,7 +25558,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25567,7 +25569,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25578,7 +25580,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25809,7 +25811,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25836,7 +25838,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25847,7 +25849,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25858,7 +25860,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25888,7 +25890,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25899,7 +25901,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25927,7 +25929,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -25938,7 +25940,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26026,7 +26028,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26074,7 +26076,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26085,7 +26087,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26096,7 +26098,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26107,7 +26109,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26118,7 +26120,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26129,7 +26131,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26201,7 +26203,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26212,7 +26214,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26266,7 +26268,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26468,7 +26470,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26776,7 +26778,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26787,7 +26789,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -26798,7 +26800,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -27049,7 +27051,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -27060,7 +27062,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -27425,7 +27427,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -28282,7 +28284,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -28412,7 +28414,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -28423,7 +28425,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -28556,7 +28558,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -28639,7 +28641,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -28650,7 +28652,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -29010,7 +29012,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -29306,7 +29308,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -29317,7 +29319,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -29443,7 +29445,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -29454,7 +29456,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -31188,7 +31190,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -31418,6 +31420,55 @@ "categories": [], "default": "ignore" }, + "opencmp.net": { + "domain": "opencmp.net", + "owner": { + "name": "opencmp.net", + "displayName": "opencmp.net" + }, + "prevalence": 0.0116, + "fingerprinting": 2, + "cookies": 0, + "categories": [], + "default": "ignore", + "rules": [ + { + "rule": "opencmp\\.net\\/tcf-v2\\/platforms\\/legacy\\/cmp-latest\\.js", + "fingerprinting": 2, + "cookies": 0 + } + ] + }, + "axept.io": { + "domain": "axept.io", + "owner": { + "name": "axept.io", + "displayName": "axept.io" + }, + "prevalence": 0.0192, + "fingerprinting": 1, + "cookies": 0.0191, + "categories": [], + "default": "ignore", + "rules": [ + { + "rule": "axept\\.io\\/sdk\\.js", + "fingerprinting": 1, + "cookies": 0.0167 + }, + { + "rule": "axept\\.io\\/sdk-slim\\.js", + "fingerprinting": 1, + "cookies": 0.00241 + }, + { + "rule": "axept\\.io\\/v1\\/analytics\\/evts", + "fingerprinting": 0, + "cookies": 0, + "comment": "pixel" + } + ] + }, "veoxa.com": { "domain": "veoxa.com", "owner": { @@ -31443,7 +31494,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -31536,6 +31587,25 @@ } ] }, + "medietall.no": { + "domain": "medietall.no", + "owner": { + "name": "medietall.no", + "displayName": "medietall.no" + }, + "prevalence": 0.0152, + "fingerprinting": 1, + "cookies": 0.015, + "categories": [], + "default": "ignore", + "rules": [ + { + "rule": "medietall\\.no\\/analytics\\.v2\\.js", + "fingerprinting": 1, + "cookies": 0.015 + } + ] + }, "ad-delivery.net": { "domain": "ad-delivery.net", "owner": { @@ -32584,7 +32654,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32595,7 +32665,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32606,7 +32676,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32617,7 +32687,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32628,7 +32698,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32639,7 +32709,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32650,7 +32720,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32661,7 +32731,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32672,7 +32742,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32683,7 +32753,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32694,7 +32764,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32705,7 +32775,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32716,7 +32786,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32727,7 +32797,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32738,7 +32808,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32749,7 +32819,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32760,7 +32830,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32771,7 +32841,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32782,7 +32852,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32793,7 +32863,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32804,7 +32874,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32815,7 +32885,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32826,7 +32896,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32837,7 +32907,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32848,7 +32918,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32859,7 +32929,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32870,7 +32940,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32881,7 +32951,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32892,7 +32962,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32903,7 +32973,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32914,7 +32984,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32925,7 +32995,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32936,7 +33006,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32947,7 +33017,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32958,7 +33028,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32969,7 +33039,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32980,7 +33050,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -32991,7 +33061,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33002,7 +33072,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33013,7 +33083,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33024,7 +33094,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33035,7 +33105,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33046,7 +33116,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33057,7 +33127,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33068,7 +33138,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33079,7 +33149,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33090,7 +33160,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33101,7 +33171,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33112,7 +33182,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33123,7 +33193,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33134,7 +33204,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33145,7 +33215,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33156,7 +33226,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33167,7 +33237,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33178,7 +33248,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33189,7 +33259,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33200,7 +33270,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33211,7 +33281,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33222,7 +33292,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33233,7 +33303,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33244,7 +33314,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33255,7 +33325,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33266,7 +33336,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33277,7 +33347,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33288,7 +33358,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33299,7 +33369,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33310,7 +33380,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33321,7 +33391,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33332,7 +33402,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33343,7 +33413,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33354,7 +33424,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33365,7 +33435,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33376,7 +33446,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33387,7 +33457,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33398,7 +33468,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33409,7 +33479,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33420,7 +33490,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33431,7 +33501,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33442,7 +33512,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33453,7 +33523,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33464,7 +33534,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33475,7 +33545,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33486,7 +33556,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33497,7 +33567,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33508,7 +33578,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33519,7 +33589,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33530,7 +33600,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33541,7 +33611,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33552,7 +33622,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33563,7 +33633,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33574,7 +33644,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33585,7 +33655,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33596,7 +33666,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33607,7 +33677,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33618,7 +33688,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33629,7 +33699,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33640,7 +33710,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33651,7 +33721,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33662,7 +33732,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33673,7 +33743,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33684,7 +33754,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33695,7 +33765,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33706,7 +33776,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33717,7 +33787,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33728,7 +33798,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33739,7 +33809,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33750,7 +33820,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33761,7 +33831,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33772,7 +33842,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33783,7 +33853,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33794,7 +33864,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33805,7 +33875,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33816,7 +33886,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33827,7 +33897,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33838,7 +33908,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33849,7 +33919,18 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, + "fingerprinting": 1, + "cookies": 0.01, + "default": "block" + }, + "excitingtub.com": { + "domain": "excitingtub.com", + "owner": { + "name": "Leven Labs, Inc. DBA Admiral", + "displayName": "Admiral" + }, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33860,7 +33941,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33871,7 +33952,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33882,7 +33963,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33893,7 +33974,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33904,7 +33985,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33915,7 +33996,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33926,7 +34007,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33937,7 +34018,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33948,7 +34029,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33959,7 +34040,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33970,7 +34051,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33981,7 +34062,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -33992,7 +34073,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34003,7 +34084,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34014,7 +34095,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34025,7 +34106,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34036,7 +34117,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34047,7 +34128,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34058,7 +34139,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34069,7 +34150,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34080,7 +34161,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34091,7 +34172,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34102,7 +34183,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34113,7 +34194,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34124,7 +34205,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34135,7 +34216,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34146,7 +34227,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34157,7 +34238,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34168,7 +34249,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34179,7 +34260,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34190,7 +34271,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34201,7 +34282,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34212,7 +34293,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34223,7 +34304,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34234,7 +34315,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34245,7 +34326,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34256,7 +34337,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34267,7 +34348,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34278,7 +34359,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34289,7 +34370,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34300,7 +34381,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34311,7 +34392,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34322,7 +34403,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34333,7 +34414,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34344,7 +34425,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34355,7 +34436,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34366,7 +34447,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34377,7 +34458,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34388,7 +34469,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34399,7 +34480,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34410,7 +34491,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34421,7 +34502,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34432,7 +34513,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34443,7 +34524,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34454,7 +34535,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34465,7 +34546,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34476,7 +34557,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34487,7 +34568,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34498,7 +34579,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34509,7 +34590,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34520,7 +34601,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34531,7 +34612,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34542,7 +34623,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34553,7 +34634,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34564,7 +34645,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34575,7 +34656,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34586,7 +34667,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34597,7 +34678,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34608,7 +34689,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34619,7 +34700,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34630,7 +34711,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34641,7 +34722,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34652,7 +34733,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34663,7 +34744,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34674,7 +34755,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34685,7 +34766,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34696,7 +34777,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34707,7 +34788,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34718,7 +34799,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34729,7 +34810,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34740,7 +34821,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34751,7 +34832,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34762,7 +34843,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34773,7 +34854,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34784,7 +34865,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34795,7 +34876,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34806,7 +34887,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34817,7 +34898,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34828,7 +34909,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34839,7 +34920,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34850,7 +34931,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34861,7 +34942,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34872,7 +34953,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34883,7 +34964,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34894,7 +34975,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34905,7 +34986,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34916,7 +34997,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34927,7 +35008,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34938,7 +35019,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34949,7 +35030,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34960,7 +35041,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34971,7 +35052,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34982,7 +35063,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -34993,7 +35074,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35004,7 +35085,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35015,7 +35096,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35026,7 +35107,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35037,7 +35118,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35048,7 +35129,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35059,7 +35140,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35070,7 +35151,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35081,7 +35162,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35092,7 +35173,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35103,7 +35184,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35114,7 +35195,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35125,7 +35206,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35136,7 +35217,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35147,7 +35228,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35158,7 +35239,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35169,7 +35250,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35180,7 +35261,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35191,7 +35272,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35202,7 +35283,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35213,7 +35294,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35224,7 +35305,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35235,7 +35316,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35246,7 +35327,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35257,7 +35338,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35268,7 +35349,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35279,7 +35360,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35290,7 +35371,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35301,7 +35382,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35312,7 +35393,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35323,7 +35404,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35334,7 +35415,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35345,7 +35426,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35356,7 +35437,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35367,7 +35448,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35378,7 +35459,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35389,7 +35470,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35400,7 +35481,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35411,7 +35492,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35422,7 +35503,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35433,7 +35514,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35444,7 +35525,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35455,7 +35536,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35466,7 +35547,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35477,7 +35558,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35488,7 +35569,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35499,7 +35580,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35510,7 +35591,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35521,7 +35602,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35532,7 +35613,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35543,7 +35624,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35554,7 +35635,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35565,7 +35646,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35576,7 +35657,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35587,7 +35668,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35598,7 +35679,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35609,7 +35690,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35620,7 +35701,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35631,7 +35712,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35642,7 +35723,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35653,7 +35734,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35664,7 +35745,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35675,7 +35756,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35686,7 +35767,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35697,7 +35778,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35708,7 +35789,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35719,7 +35800,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35730,7 +35811,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35741,7 +35822,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35752,7 +35833,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35763,7 +35844,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35774,7 +35855,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35785,7 +35866,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35796,7 +35877,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35807,7 +35888,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35818,7 +35899,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35829,7 +35910,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35840,7 +35921,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35851,7 +35932,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35862,7 +35943,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35873,7 +35954,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35884,7 +35965,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35895,7 +35976,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35906,7 +35987,18 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, + "fingerprinting": 1, + "cookies": 0.01, + "default": "block" + }, + "slinksuggestion.com": { + "domain": "slinksuggestion.com", + "owner": { + "name": "Leven Labs, Inc. DBA Admiral", + "displayName": "Admiral" + }, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35917,7 +36009,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35928,7 +36020,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35939,7 +36031,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35950,7 +36042,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35961,7 +36053,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35972,7 +36064,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35983,7 +36075,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -35994,7 +36086,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36005,7 +36097,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36016,7 +36108,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36027,7 +36119,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36038,7 +36130,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36049,7 +36141,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36060,7 +36152,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36071,7 +36163,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36082,7 +36174,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36093,7 +36185,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36104,7 +36196,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36115,7 +36207,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36126,7 +36218,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36137,7 +36229,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36148,7 +36240,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36159,7 +36251,18 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, + "fingerprinting": 1, + "cookies": 0.01, + "default": "block" + }, + "strangersponge.com": { + "domain": "strangersponge.com", + "owner": { + "name": "Leven Labs, Inc. DBA Admiral", + "displayName": "Admiral" + }, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36170,7 +36273,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36181,7 +36284,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36192,7 +36295,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36203,7 +36306,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36214,7 +36317,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36225,7 +36328,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36236,7 +36339,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36247,7 +36350,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36258,7 +36361,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36269,7 +36372,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36280,7 +36383,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36291,7 +36394,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36302,7 +36405,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36313,7 +36416,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36324,7 +36427,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36335,7 +36438,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36346,7 +36449,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36357,7 +36460,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36368,7 +36471,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36379,7 +36482,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36390,7 +36493,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36401,7 +36504,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36412,7 +36515,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36423,7 +36526,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36434,7 +36537,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36445,7 +36548,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36456,7 +36559,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36467,7 +36570,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36478,7 +36581,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36489,7 +36592,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36500,7 +36603,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36511,7 +36614,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36522,7 +36625,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36533,7 +36636,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36544,7 +36647,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36555,7 +36658,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36566,7 +36669,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36577,7 +36680,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36588,7 +36691,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36599,7 +36702,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36610,7 +36713,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36621,7 +36724,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36632,7 +36735,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36643,7 +36746,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36654,7 +36757,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36665,7 +36768,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36676,7 +36779,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36687,7 +36790,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36698,7 +36801,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36709,7 +36812,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36720,7 +36823,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36731,7 +36834,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36742,7 +36845,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36753,7 +36856,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36764,7 +36867,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36775,7 +36878,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36786,7 +36889,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36797,7 +36900,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36808,7 +36911,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -36819,7 +36922,7 @@ "name": "Leven Labs, Inc. DBA Admiral", "displayName": "Admiral" }, - "prevalence": 0.0137, + "prevalence": 0.0138, "fingerprinting": 1, "cookies": 0.01, "default": "block" @@ -37542,6 +37645,7 @@ "amazon.com.mx", "amazon.com.tr", "amazon.de", + "amazon.dev", "amazon.es", "amazon.fr", "amazon.in", @@ -37618,7 +37722,7 @@ "zappos.com", "zapposcouture.com" ], - "prevalence": 22.3, + "prevalence": 21.8, "displayName": "Amazon.com" }, "Alliance for Audited Media": { @@ -39040,13 +39144,6 @@ "prevalence": 0.0361, "displayName": "Alibaba" }, - "amazon.dev": { - "domains": [ - "amazon.dev" - ], - "prevalence": 0, - "displayName": "amazon.dev" - }, "Amplitude": { "domains": [ "amplitude.com" @@ -40445,6 +40542,7 @@ "radian6.com", "relateiq.com", "salesforce-communities.com", + "salesforce-sites.com", "salesforce.com", "salesforceiq.com", "salesforceliveagent.com", @@ -40461,7 +40559,7 @@ "visualforce.com", "weinvoiceit.com" ], - "prevalence": 8.34, + "prevalence": 7.23, "displayName": "Salesforce.com" }, "Crazy Egg, Inc.": { @@ -42179,17 +42277,27 @@ "tripadvisor.be", "tripadvisor.ca", "tripadvisor.ch", + "tripadvisor.cl", + "tripadvisor.co", + "tripadvisor.co.id", + "tripadvisor.co.il", "tripadvisor.co.nz", "tripadvisor.co.uk", "tripadvisor.co.za", "tripadvisor.com", + "tripadvisor.com.ar", "tripadvisor.com.au", "tripadvisor.com.br", + "tripadvisor.com.gr", "tripadvisor.com.hk", "tripadvisor.com.mx", "tripadvisor.com.my", + "tripadvisor.com.pe", "tripadvisor.com.ph", "tripadvisor.com.sg", + "tripadvisor.com.tr", + "tripadvisor.com.tw", + "tripadvisor.com.ve", "tripadvisor.de", "tripadvisor.dk", "tripadvisor.es", @@ -42204,7 +42312,7 @@ "tripadvisor.ru", "tripadvisor.se" ], - "prevalence": 0.116, + "prevalence": 0.0981, "displayName": "TripAdvisor" }, "Prospect One": { @@ -43469,10 +43577,13 @@ }, "Nextdoor, Inc.": { "domains": [ + "nextdoor.ca", "nextdoor.co.uk", - "nextdoor.com" + "nextdoor.com", + "nextdoor.de", + "nextdoor.nl" ], - "prevalence": 0.274, + "prevalence": 0.322, "displayName": "Nextdoor" }, "Nine Entertainment Co.": { @@ -46597,6 +46708,20 @@ "prevalence": 0.0041, "displayName": "Telstra" }, + "opencmp.net": { + "domains": [ + "opencmp.net" + ], + "prevalence": 0, + "displayName": "opencmp.net" + }, + "axept.io": { + "domains": [ + "axept.io" + ], + "prevalence": 0, + "displayName": "axept.io" + }, "J S WEB PRODUCTION": { "domains": [ "ad2perf.com", @@ -46622,6 +46747,13 @@ "prevalence": 0.0014, "displayName": "Adtraction Marketing" }, + "medietall.no": { + "domains": [ + "medietall.no" + ], + "prevalence": 0, + "displayName": "medietall.no" + }, "easyAd Deutschland GmbH": { "domains": [ "ad-delivery.net", @@ -46994,6 +47126,7 @@ "evanescentedge.com", "eventexistence.com", "exampleshake.com", + "excitingtub.com", "exhibitsneeze.com", "expansioneggnog.com", "exuberantedge.com", @@ -47292,6 +47425,7 @@ "sixscissors.com", "skillfuldrop.com", "skisofa.com", + "slinksuggestion.com", "slopesoap.com", "smashquartz.com", "smashsurprise.com", @@ -47334,6 +47468,7 @@ "stomachscience.com", "straightnest.com", "strangeclocks.com", + "strangersponge.com", "strangesink.com", "stretchsister.com", "stretchsneeze.com", @@ -47423,7 +47558,7 @@ "zipperxray.com", "zlp6s.pw" ], - "prevalence": 0.0137, + "prevalence": 0.0138, "displayName": "Admiral" } }, @@ -48064,6 +48199,7 @@ "amazon.com.mx": "Amazon Technologies, Inc.", "amazon.com.tr": "Amazon Technologies, Inc.", "amazon.de": "Amazon Technologies, Inc.", + "amazon.dev": "Amazon Technologies, Inc.", "amazon.es": "Amazon Technologies, Inc.", "amazon.fr": "Amazon Technologies, Inc.", "amazon.in": "Amazon Technologies, Inc.", @@ -48317,6 +48453,7 @@ "evanescentedge.com": "Leven Labs, Inc. DBA Admiral", "eventexistence.com": "Leven Labs, Inc. DBA Admiral", "exampleshake.com": "Leven Labs, Inc. DBA Admiral", + "excitingtub.com": "Leven Labs, Inc. DBA Admiral", "exhibitsneeze.com": "Leven Labs, Inc. DBA Admiral", "expansioneggnog.com": "Leven Labs, Inc. DBA Admiral", "exuberantedge.com": "Leven Labs, Inc. DBA Admiral", @@ -48615,6 +48752,7 @@ "sixscissors.com": "Leven Labs, Inc. DBA Admiral", "skillfuldrop.com": "Leven Labs, Inc. DBA Admiral", "skisofa.com": "Leven Labs, Inc. DBA Admiral", + "slinksuggestion.com": "Leven Labs, Inc. DBA Admiral", "slopesoap.com": "Leven Labs, Inc. DBA Admiral", "smashquartz.com": "Leven Labs, Inc. DBA Admiral", "smashsurprise.com": "Leven Labs, Inc. DBA Admiral", @@ -48657,6 +48795,7 @@ "stomachscience.com": "Leven Labs, Inc. DBA Admiral", "straightnest.com": "Leven Labs, Inc. DBA Admiral", "strangeclocks.com": "Leven Labs, Inc. DBA Admiral", + "strangersponge.com": "Leven Labs, Inc. DBA Admiral", "strangesink.com": "Leven Labs, Inc. DBA Admiral", "stretchsister.com": "Leven Labs, Inc. DBA Admiral", "stretchsneeze.com": "Leven Labs, Inc. DBA Admiral", @@ -49718,7 +49857,6 @@ "wpn.com": "Alibaba Group", "ykimg.com": "Alibaba Group", "youku.com": "Alibaba Group", - "amazon.dev": "amazon.dev", "amplitude.com": "Amplitude", "amung.us": "whos.amung.us Inc", "waust.at": "whos.amung.us Inc", @@ -50338,6 +50476,7 @@ "radian6.com": "Salesforce.com, Inc.", "relateiq.com": "Salesforce.com, Inc.", "salesforce-communities.com": "Salesforce.com, Inc.", + "salesforce-sites.com": "Salesforce.com, Inc.", "salesforce.com": "Salesforce.com, Inc.", "salesforceiq.com": "Salesforce.com, Inc.", "salesforceliveagent.com": "Salesforce.com, Inc.", @@ -51076,17 +51215,27 @@ "tripadvisor.be": "TripAdvisor LLC", "tripadvisor.ca": "TripAdvisor LLC", "tripadvisor.ch": "TripAdvisor LLC", + "tripadvisor.cl": "TripAdvisor LLC", + "tripadvisor.co": "TripAdvisor LLC", + "tripadvisor.co.id": "TripAdvisor LLC", + "tripadvisor.co.il": "TripAdvisor LLC", "tripadvisor.co.nz": "TripAdvisor LLC", "tripadvisor.co.uk": "TripAdvisor LLC", "tripadvisor.co.za": "TripAdvisor LLC", "tripadvisor.com": "TripAdvisor LLC", + "tripadvisor.com.ar": "TripAdvisor LLC", "tripadvisor.com.au": "TripAdvisor LLC", "tripadvisor.com.br": "TripAdvisor LLC", + "tripadvisor.com.gr": "TripAdvisor LLC", "tripadvisor.com.hk": "TripAdvisor LLC", "tripadvisor.com.mx": "TripAdvisor LLC", "tripadvisor.com.my": "TripAdvisor LLC", + "tripadvisor.com.pe": "TripAdvisor LLC", "tripadvisor.com.ph": "TripAdvisor LLC", "tripadvisor.com.sg": "TripAdvisor LLC", + "tripadvisor.com.tr": "TripAdvisor LLC", + "tripadvisor.com.tw": "TripAdvisor LLC", + "tripadvisor.com.ve": "TripAdvisor LLC", "tripadvisor.de": "TripAdvisor LLC", "tripadvisor.dk": "TripAdvisor LLC", "tripadvisor.es": "TripAdvisor LLC", @@ -51712,8 +51861,11 @@ "newscorpaustralia.com": "News Limited", "newsroom.bi": "newsroom.bi", "nextday.media": "P B.V.", + "nextdoor.ca": "Nextdoor, Inc.", "nextdoor.co.uk": "Nextdoor, Inc.", "nextdoor.com": "Nextdoor, Inc.", + "nextdoor.de": "Nextdoor, Inc.", + "nextdoor.nl": "Nextdoor, Inc.", "9cdn.net": "Nine Entertainment Co.", "9nation.com.au": "Nine Entertainment Co.", "9news.com.au": "Nine Entertainment Co.", @@ -53006,6 +53158,8 @@ "shop.pe": "Add Shoppers", "telstra.com": "Telstra Corporation Limited", "telstra.com.au": "Telstra Corporation Limited", + "opencmp.net": "opencmp.net", + "axept.io": "axept.io", "ad2perf.com": "J S WEB PRODUCTION", "moxielinks.com": "J S WEB PRODUCTION", "veoxa.com": "J S WEB PRODUCTION", @@ -53013,6 +53167,7 @@ "sooqr.nl": "Sooqr", "adtr.io": "Adtraction Marketing AB", "adtraction.com": "Adtraction Marketing AB", + "medietall.no": "medietall.no", "ad-delivery.net": "easyAd Deutschland GmbH", "easyad.com": "easyAd Deutschland GmbH", "easyad.info": "easyAd Deutschland GmbH", diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 09f0139bf4..0025da68e4 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -319,7 +319,6 @@ 83E2D2B4253CC16B005605F5 /* httpsMobileV2BloomSpec.json in Resources */ = {isa = PBXBuildFile; fileRef = 83E2D2B1253CC16B005605F5 /* httpsMobileV2BloomSpec.json */; }; 83EDCC411F86B89C005CDFCD /* StatisticsLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83EDCC3F1F86B895005CDFCD /* StatisticsLoaderTests.swift */; }; 84E341961E2F7EFB00BDBA6F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84E341951E2F7EFB00BDBA6F /* AppDelegate.swift */; }; - 84E3419B1E2F7EFB00BDBA6F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84E341991E2F7EFB00BDBA6F /* Main.storyboard */; }; 84E341A01E2F7EFB00BDBA6F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84E3419E1E2F7EFB00BDBA6F /* LaunchScreen.storyboard */; }; 85010502292FB1000033978F /* FireproofFaviconUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85010501292FB1000033978F /* FireproofFaviconUpdater.swift */; }; 85010504292FFB080033978F /* FireproofFaviconUpdaterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85010503292FFB080033978F /* FireproofFaviconUpdaterTests.swift */; }; @@ -341,6 +340,8 @@ 8505836E219F424500ED4EDB /* RoundedRectangleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F143C32B1E4A9A4800CFDE3A /* RoundedRectangleView.swift */; }; 8505836F219F424500ED4EDB /* UIViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1DE78591E5CD2A70058895A /* UIViewExtension.swift */; }; 85058370219F424500ED4EDB /* SearchBarExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F143C3451E4AA32D00CFDE3A /* SearchBarExtension.swift */; }; + 850ABD012AC3961100A733DF /* MainViewController+Segues.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850ABD002AC3961100A733DF /* MainViewController+Segues.swift */; }; + 850ABD032AC4D46C00A733DF /* SuggestionTray.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 850ABD022AC4D46C00A733DF /* SuggestionTray.storyboard */; }; 8512EA4F24ED30D20073EE19 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8512EA4E24ED30D20073EE19 /* WidgetKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 8512EA5124ED30D20073EE19 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8512EA5024ED30D20073EE19 /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 8512EA5424ED30D20073EE19 /* Widgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8512EA5324ED30D20073EE19 /* Widgets.swift */; }; @@ -464,6 +465,7 @@ 85D598872927F84C00FA3B1B /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 85D598862927F84C00FA3B1B /* Crashes */; }; 85DB12EB2A1FE2A4000A4A72 /* LockScreenWidgets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DB12EA2A1FE2A4000A4A72 /* LockScreenWidgets.swift */; }; 85DB12ED2A1FED0C000A4A72 /* AppDelegate+AppDeepLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DB12EC2A1FED0C000A4A72 /* AppDelegate+AppDeepLinks.swift */; }; + 85DDE0402AC6FF65006ABCA2 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DDE03F2AC6FF65006ABCA2 /* MainView.swift */; }; 85DF714624F7FE6100C89288 /* Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F143C2E41E4A4CD400CFDE3A /* Core.framework */; }; 85DFEDED24C7CCA500973FE7 /* AppWidthObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DFEDEC24C7CCA500973FE7 /* AppWidthObserver.swift */; }; 85DFEDEF24C7EA3B00973FE7 /* SmallOmniBarState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85DFEDEE24C7EA3B00973FE7 /* SmallOmniBarState.swift */; }; @@ -746,6 +748,7 @@ EE0153ED2A6FF9E6002A8B26 /* NetworkProtectionRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE0153EC2A6FF9E6002A8B26 /* NetworkProtectionRootView.swift */; }; EE0153EF2A70021E002A8B26 /* NetworkProtectionInviteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE0153EE2A70021E002A8B26 /* NetworkProtectionInviteView.swift */; }; EE276BEA2A77F823009167B6 /* NetworkProtectionRootViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE276BE92A77F823009167B6 /* NetworkProtectionRootViewController.swift */; }; + EE3766DE2AC5945500AAB575 /* NetworkProtectionUNNotificationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3766DD2AC5945500AAB575 /* NetworkProtectionUNNotificationPresenter.swift */; }; EE3B226B29DE0F110082298A /* MockInternalUserStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3B226A29DE0F110082298A /* MockInternalUserStoring.swift */; }; EE3B226C29DE0FD30082298A /* MockInternalUserStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE3B226A29DE0F110082298A /* MockInternalUserStoring.swift */; }; EE41BD192A729E9C00546C57 /* NetworkProtectionInviteViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE41BD182A729E9C00546C57 /* NetworkProtectionInviteViewModelTests.swift */; }; @@ -758,11 +761,13 @@ EE50053029C3BA0800AE0773 /* InternalUserStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE50052F29C3BA0800AE0773 /* InternalUserStore.swift */; }; EE72CA852A862D000043B5B3 /* NetworkProtectionDebugViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE72CA842A862D000043B5B3 /* NetworkProtectionDebugViewController.swift */; }; EE7917912A83DE93008DFF28 /* CombineTestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE7917902A83DE93008DFF28 /* CombineTestUtilities.swift */; }; + EE7A92872AC6DE4700832A36 /* NetworkProtectionNotificationIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE7A92862AC6DE4700832A36 /* NetworkProtectionNotificationIdentifier.swift */; }; EE8594992A44791C008A6D06 /* NetworkProtectionTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE8594982A44791C008A6D06 /* NetworkProtectionTunnelController.swift */; }; EE8E568A2A56BCE400F11DCA /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = EE8E56892A56BCE400F11DCA /* NetworkProtection */; }; EEEB80A32A421CE600386378 /* NetworkProtectionPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEEB80A22A421CE600386378 /* NetworkProtectionPacketTunnelProvider.swift */; }; EEF0F8CC2ABC832300630031 /* NetworkProtectionDebugFeatures.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF0F8CB2ABC832200630031 /* NetworkProtectionDebugFeatures.swift */; }; EEFAB4672A73C230008A38E4 /* NetworkProtectionTestUtils in Frameworks */ = {isa = PBXBuildFile; productRef = EEFAB4662A73C230008A38E4 /* NetworkProtectionTestUtils */; }; + EEFC6A602AC0F2F80065027D /* UserText.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFC6A5F2AC0F2F80065027D /* UserText.swift */; }; EEFD562F2A65B6CA00DAEC48 /* NetworkProtectionInviteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFD562E2A65B6CA00DAEC48 /* NetworkProtectionInviteViewModel.swift */; }; EEFE9C732A603CE9005B0A26 /* NetworkProtectionStatusViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEFE9C722A603CE9005B0A26 /* NetworkProtectionStatusViewModelTests.swift */; }; F103073B1E7C91330059FEC7 /* BookmarksDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = F103073A1E7C91330059FEC7 /* BookmarksDataSource.swift */; }; @@ -1322,7 +1327,6 @@ 83EDCC3F1F86B895005CDFCD /* StatisticsLoaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatisticsLoaderTests.swift; sourceTree = ""; }; 84E341921E2F7EFB00BDBA6F /* DuckDuckGo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DuckDuckGo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 84E341951E2F7EFB00BDBA6F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 84E3419A1E2F7EFB00BDBA6F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 84E3419F1E2F7EFB00BDBA6F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 84E341A11E2F7EFB00BDBA6F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 84E341A61E2F7EFB00BDBA6F /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1341,6 +1345,8 @@ 850559D123CF710C0055C0D5 /* WebCacheManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebCacheManagerTests.swift; sourceTree = ""; }; 85058365219AE9EA00ED4EDB /* HomePageConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomePageConfiguration.swift; sourceTree = ""; }; 85058367219C49E000ED4EDB /* HomeViewSectionRenderers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewSectionRenderers.swift; sourceTree = ""; }; + 850ABD002AC3961100A733DF /* MainViewController+Segues.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainViewController+Segues.swift"; sourceTree = ""; }; + 850ABD022AC4D46C00A733DF /* SuggestionTray.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = SuggestionTray.storyboard; sourceTree = ""; }; 8512BCBF2061B6110085E862 /* global.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = global.swift; sourceTree = ""; }; 8512EA4D24ED30D20073EE19 /* WidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 8512EA4E24ED30D20073EE19 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; @@ -1464,6 +1470,7 @@ 85D33FCF25C97B6E002B91A6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 85DB12EA2A1FE2A4000A4A72 /* LockScreenWidgets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockScreenWidgets.swift; sourceTree = ""; }; 85DB12EC2A1FED0C000A4A72 /* AppDelegate+AppDeepLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+AppDeepLinks.swift"; sourceTree = ""; }; + 85DDE03F2AC6FF65006ABCA2 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; 85DFEDEC24C7CCA500973FE7 /* AppWidthObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppWidthObserver.swift; sourceTree = ""; }; 85DFEDEE24C7EA3B00973FE7 /* SmallOmniBarState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallOmniBarState.swift; sourceTree = ""; }; 85DFEDF024C7EEA400973FE7 /* LargeOmniBarState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeOmniBarState.swift; sourceTree = ""; }; @@ -1514,7 +1521,6 @@ 981685442521EEEF00FA91A1 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Bookmarks.strings; sourceTree = ""; }; 981685452521EEF000FA91A1 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Feedback.strings; sourceTree = ""; }; 981685462521EEF000FA91A1 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Home.strings; sourceTree = ""; }; - 981685472521EEF000FA91A1 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Main.strings; sourceTree = ""; }; 981685482521EEF100FA91A1 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/OmniBar.strings; sourceTree = ""; }; 981685492521EEF100FA91A1 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Authentication.strings; sourceTree = ""; }; 9816854A2521EEF100FA91A1 /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1619,7 +1625,6 @@ 9866DB8C251CA8F300612E3A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DB8D251CA8F300612E3A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Feedback.strings; sourceTree = ""; }; 9866DB8E251CA8F400612E3A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Home.strings; sourceTree = ""; }; - 9866DB8F251CA8F400612E3A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Main.strings; sourceTree = ""; }; 9866DB90251CA8F400612E3A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/OmniBar.strings; sourceTree = ""; }; 9866DB91251CA8F400612E3A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/Authentication.strings; sourceTree = ""; }; 9866DB92251CA8F400612E3A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = bg.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1638,7 +1643,6 @@ 9866DBA3251CA91700612E3A /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DBA4251CA91700612E3A /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Feedback.strings; sourceTree = ""; }; 9866DBA5251CA91800612E3A /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Home.strings; sourceTree = ""; }; - 9866DBA6251CA91800612E3A /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Main.strings; sourceTree = ""; }; 9866DBA7251CA91800612E3A /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/OmniBar.strings; sourceTree = ""; }; 9866DBA8251CA91800612E3A /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Authentication.strings; sourceTree = ""; }; 9866DBA9251CA91800612E3A /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1657,7 +1661,6 @@ 9866DBBA251CA92A00612E3A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DBBB251CA92A00612E3A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Feedback.strings; sourceTree = ""; }; 9866DBBC251CA92A00612E3A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Home.strings; sourceTree = ""; }; - 9866DBBD251CA92A00612E3A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Main.strings; sourceTree = ""; }; 9866DBBE251CA92B00612E3A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/OmniBar.strings; sourceTree = ""; }; 9866DBBF251CA92B00612E3A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Authentication.strings; sourceTree = ""; }; 9866DBC0251CA92B00612E3A /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1676,7 +1679,6 @@ 9866DBD1251CA93800612E3A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DBD2251CA93900612E3A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Feedback.strings; sourceTree = ""; }; 9866DBD3251CA93900612E3A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Home.strings; sourceTree = ""; }; - 9866DBD4251CA93900612E3A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Main.strings; sourceTree = ""; }; 9866DBD5251CA93900612E3A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/OmniBar.strings; sourceTree = ""; }; 9866DBD6251CA93900612E3A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Authentication.strings; sourceTree = ""; }; 9866DBD7251CA93900612E3A /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1695,7 +1697,6 @@ 9866DBE8251CA94E00612E3A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DBE9251CA94E00612E3A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Feedback.strings; sourceTree = ""; }; 9866DBEA251CA94F00612E3A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Home.strings; sourceTree = ""; }; - 9866DBEB251CA94F00612E3A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Main.strings; sourceTree = ""; }; 9866DBEC251CA94F00612E3A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/OmniBar.strings; sourceTree = ""; }; 9866DBED251CA94F00612E3A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Authentication.strings; sourceTree = ""; }; 9866DBEE251CA94F00612E3A /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1714,7 +1715,6 @@ 9866DBFF251CA96200612E3A /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DC00251CA96200612E3A /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Feedback.strings; sourceTree = ""; }; 9866DC01251CA96200612E3A /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Home.strings; sourceTree = ""; }; - 9866DC02251CA96200612E3A /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Main.strings; sourceTree = ""; }; 9866DC03251CA96300612E3A /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/OmniBar.strings; sourceTree = ""; }; 9866DC04251CA96300612E3A /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Authentication.strings; sourceTree = ""; }; 9866DC05251CA96300612E3A /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1733,7 +1733,6 @@ 9866DC16251CA99A00612E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DC17251CA99B00612E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Feedback.strings; sourceTree = ""; }; 9866DC18251CA99B00612E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Home.strings; sourceTree = ""; }; - 9866DC19251CA99B00612E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = ""; }; 9866DC1A251CA99B00612E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/OmniBar.strings; sourceTree = ""; }; 9866DC1B251CA99B00612E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Authentication.strings; sourceTree = ""; }; 9866DC1C251CA99C00612E3A /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1752,7 +1751,6 @@ 9866DC2D251CA9B000612E3A /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DC2E251CA9B000612E3A /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Feedback.strings; sourceTree = ""; }; 9866DC2F251CA9B000612E3A /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Home.strings; sourceTree = ""; }; - 9866DC30251CA9B000612E3A /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Main.strings; sourceTree = ""; }; 9866DC31251CA9B000612E3A /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/OmniBar.strings; sourceTree = ""; }; 9866DC32251CA9B000612E3A /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Authentication.strings; sourceTree = ""; }; 9866DC33251CA9B000612E3A /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1771,7 +1769,6 @@ 9866DC44251CA9BF00612E3A /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DC45251CA9BF00612E3A /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Feedback.strings; sourceTree = ""; }; 9866DC46251CA9C000612E3A /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Home.strings; sourceTree = ""; }; - 9866DC47251CA9C000612E3A /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Main.strings; sourceTree = ""; }; 9866DC48251CA9C000612E3A /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/OmniBar.strings; sourceTree = ""; }; 9866DC49251CA9C000612E3A /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Authentication.strings; sourceTree = ""; }; 9866DC4A251CA9C000612E3A /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1790,7 +1787,6 @@ 9866DC5B251CA9CE00612E3A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DC5C251CA9CE00612E3A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Feedback.strings; sourceTree = ""; }; 9866DC5D251CA9CE00612E3A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Home.strings; sourceTree = ""; }; - 9866DC5E251CA9CE00612E3A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Main.strings; sourceTree = ""; }; 9866DC5F251CA9CF00612E3A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/OmniBar.strings; sourceTree = ""; }; 9866DC60251CA9CF00612E3A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Authentication.strings; sourceTree = ""; }; 9866DC61251CA9CF00612E3A /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1809,7 +1805,6 @@ 9866DC72251CA9E200612E3A /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DC73251CA9E300612E3A /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/Feedback.strings; sourceTree = ""; }; 9866DC74251CA9E300612E3A /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/Home.strings; sourceTree = ""; }; - 9866DC75251CA9E300612E3A /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/Main.strings; sourceTree = ""; }; 9866DC76251CA9E300612E3A /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/OmniBar.strings; sourceTree = ""; }; 9866DC77251CA9E300612E3A /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/Authentication.strings; sourceTree = ""; }; 9866DC78251CA9E300612E3A /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1828,7 +1823,6 @@ 9866DC89251CA9F500612E3A /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DC8A251CA9F500612E3A /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Feedback.strings; sourceTree = ""; }; 9866DC8B251CA9F500612E3A /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Home.strings; sourceTree = ""; }; - 9866DC8C251CA9F500612E3A /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Main.strings; sourceTree = ""; }; 9866DC8D251CA9F500612E3A /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/OmniBar.strings; sourceTree = ""; }; 9866DC8E251CA9F500612E3A /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Authentication.strings; sourceTree = ""; }; 9866DC8F251CA9F500612E3A /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1847,7 +1841,6 @@ 9866DCA0251CAA0500612E3A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DCA1251CAA0500612E3A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Feedback.strings; sourceTree = ""; }; 9866DCA2251CAA0500612E3A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Home.strings; sourceTree = ""; }; - 9866DCA3251CAA0500612E3A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Main.strings; sourceTree = ""; }; 9866DCA4251CAA0500612E3A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/OmniBar.strings; sourceTree = ""; }; 9866DCA5251CAA0500612E3A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Authentication.strings; sourceTree = ""; }; 9866DCA6251CAA0600612E3A /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1866,7 +1859,6 @@ 9866DCB7251CAA2600612E3A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DCB8251CAA2600612E3A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Feedback.strings; sourceTree = ""; }; 9866DCB9251CAA2600612E3A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Home.strings; sourceTree = ""; }; - 9866DCBA251CAA2600612E3A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Main.strings; sourceTree = ""; }; 9866DCBB251CAA2600612E3A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/OmniBar.strings; sourceTree = ""; }; 9866DCBC251CAA2700612E3A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Authentication.strings; sourceTree = ""; }; 9866DCBD251CAA2700612E3A /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1885,7 +1877,6 @@ 9866DCCE251CAA3300612E3A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DCCF251CAA3400612E3A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Feedback.strings; sourceTree = ""; }; 9866DCD0251CAA3400612E3A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Home.strings; sourceTree = ""; }; - 9866DCD1251CAA3400612E3A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Main.strings; sourceTree = ""; }; 9866DCD2251CAA3400612E3A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/OmniBar.strings; sourceTree = ""; }; 9866DCD3251CAA3400612E3A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/Authentication.strings; sourceTree = ""; }; 9866DCD4251CAA3400612E3A /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1904,7 +1895,6 @@ 9866DCE5251CAA4800612E3A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Bookmarks.strings; sourceTree = ""; }; 9866DCE6251CAA4800612E3A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Feedback.strings; sourceTree = ""; }; 9866DCE7251CAA4800612E3A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Home.strings; sourceTree = ""; }; - 9866DCE8251CAA4900612E3A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Main.strings; sourceTree = ""; }; 9866DCE9251CAA4900612E3A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/OmniBar.strings; sourceTree = ""; }; 9866DCEA251CAA4900612E3A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Authentication.strings; sourceTree = ""; }; 9866DCEB251CAA4900612E3A /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/PrivacyDashboard.strings; sourceTree = ""; }; @@ -1954,13 +1944,6 @@ 9866DD66251CB10600612E3A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Home.strings; sourceTree = ""; }; 9866DD68251CB10700612E3A /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Home.strings; sourceTree = ""; }; 9866DD6A251CB10800612E3A /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Home.strings; sourceTree = ""; }; - 9866DD74251CB11A00612E3A /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Main.strings; sourceTree = ""; }; - 9866DD76251CB11B00612E3A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Main.strings; sourceTree = ""; }; - 9866DD7A251CB11E00612E3A /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Main.strings; sourceTree = ""; }; - 9866DD7C251CB11F00612E3A /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Main.strings; sourceTree = ""; }; - 9866DD7E251CB12000612E3A /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Main.strings; sourceTree = ""; }; - 9866DD80251CB12100612E3A /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Main.strings; sourceTree = ""; }; - 9866DD82251CB12200612E3A /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Main.strings; sourceTree = ""; }; 9866DD84251CB12700612E3A /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Authentication.strings; sourceTree = ""; }; 9866DD86251CB12800612E3A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Authentication.strings; sourceTree = ""; }; 9866DD8A251CB12B00612E3A /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Authentication.strings; sourceTree = ""; }; @@ -2332,6 +2315,7 @@ EE0153EC2A6FF9E6002A8B26 /* NetworkProtectionRootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionRootView.swift; sourceTree = ""; }; EE0153EE2A70021E002A8B26 /* NetworkProtectionInviteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionInviteView.swift; sourceTree = ""; }; EE276BE92A77F823009167B6 /* NetworkProtectionRootViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionRootViewController.swift; sourceTree = ""; }; + EE3766DD2AC5945500AAB575 /* NetworkProtectionUNNotificationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionUNNotificationPresenter.swift; sourceTree = ""; }; EE3B226A29DE0F110082298A /* MockInternalUserStoring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockInternalUserStoring.swift; sourceTree = ""; }; EE3B98EA2A9634CC002F63A0 /* DuckDuckGoAlpha.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DuckDuckGoAlpha.entitlements; sourceTree = ""; }; EE3B98EB2A963515002F63A0 /* WidgetsExtensionAlpha.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetsExtensionAlpha.entitlements; sourceTree = ""; }; @@ -2346,10 +2330,12 @@ EE50052F29C3BA0800AE0773 /* InternalUserStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InternalUserStore.swift; sourceTree = ""; }; EE72CA842A862D000043B5B3 /* NetworkProtectionDebugViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugViewController.swift; sourceTree = ""; }; EE7917902A83DE93008DFF28 /* CombineTestUtilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CombineTestUtilities.swift; sourceTree = ""; }; + EE7A92862AC6DE4700832A36 /* NetworkProtectionNotificationIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionNotificationIdentifier.swift; sourceTree = ""; }; EE8594982A44791C008A6D06 /* NetworkProtectionTunnelController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionTunnelController.swift; sourceTree = ""; }; EEB8FDB92A990AEE00EBEDCF /* Configuration-Alpha.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Configuration-Alpha.xcconfig"; path = "Configuration/Configuration-Alpha.xcconfig"; sourceTree = ""; }; EEEB80A22A421CE600386378 /* NetworkProtectionPacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionPacketTunnelProvider.swift; sourceTree = ""; }; EEF0F8CB2ABC832200630031 /* NetworkProtectionDebugFeatures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionDebugFeatures.swift; sourceTree = ""; }; + EEFC6A5F2AC0F2F80065027D /* UserText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserText.swift; sourceTree = ""; }; EEFD562E2A65B6CA00DAEC48 /* NetworkProtectionInviteViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionInviteViewModel.swift; sourceTree = ""; }; EEFE9C722A603CE9005B0A26 /* NetworkProtectionStatusViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionStatusViewModelTests.swift; sourceTree = ""; }; F103073A1E7C91330059FEC7 /* BookmarksDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarksDataSource.swift; sourceTree = ""; }; @@ -2604,13 +2590,14 @@ 02025665298818B200E694E7 /* PacketTunnelProvider */ = { isa = PBXGroup; children = ( + EE3766DC2AC5940A00AAB575 /* NetworkProtection */, EE3B98EC2A963538002F63A0 /* PacketTunnelProviderAlpha.entitlements */, 02025670298818CB00E694E7 /* ProxyServer */, 02025666298818B200E694E7 /* AppTrackingProtectionPacketTunnelProvider.swift */, 02025B1429884EA500E694E7 /* DDGObserverFactory.swift */, 02025668298818B200E694E7 /* Info.plist */, 02025669298818B200E694E7 /* PacketTunnelProvider.entitlements */, - EEEB80A22A421CE600386378 /* NetworkProtectionPacketTunnelProvider.swift */, + EEFC6A5F2AC0F2F80065027D /* UserText.swift */, ); path = PacketTunnelProvider; sourceTree = ""; @@ -4344,6 +4331,15 @@ name = Root; sourceTree = ""; }; + EE3766DC2AC5940A00AAB575 /* NetworkProtection */ = { + isa = PBXGroup; + children = ( + EEEB80A22A421CE600386378 /* NetworkProtectionPacketTunnelProvider.swift */, + EE3766DD2AC5945500AAB575 /* NetworkProtectionUNNotificationPresenter.swift */, + ); + path = NetworkProtection; + sourceTree = ""; + }; EE3B226929DE0EE10082298A /* FeatureFlags */ = { isa = PBXGroup; children = ( @@ -4380,6 +4376,14 @@ name = NetworkProtection; sourceTree = ""; }; + EE7A92852AC6DE2500832A36 /* NetworkProtection */ = { + isa = PBXGroup; + children = ( + EE7A92862AC6DE4700832A36 /* NetworkProtectionNotificationIdentifier.swift */, + ); + name = NetworkProtection; + sourceTree = ""; + }; EECD94B22A28B8580085C66E /* NetworkProtection */ = { isa = PBXGroup; children = ( @@ -4655,6 +4659,7 @@ F143C2E51E4A4CD400CFDE3A /* Core */ = { isa = PBXGroup; children = ( + EE7A92852AC6DE2500832A36 /* NetworkProtection */, 4B470ED4299C484B0086EBDC /* AppTrackingProtection */, F1CE42A71ECA0A520074A8DF /* Bookmarks */, 837774491F8E1ECE00E17A29 /* ContentBlocker */, @@ -4964,29 +4969,31 @@ F1C5ECFA1E37B15B00C599A4 /* Main */ = { isa = PBXGroup; children = ( + 310742A52848CD780012660B /* BackForwardMenuHistoryItem.swift */, + 6AC6DAB228804F97002723C0 /* BarsAnimator.swift */, 8563A03B1F9288D600F04442 /* BrowserChromeManager.swift */, 9865DFF822A8220D00D27829 /* FavoritesOverlay.swift */, + 854A012E2A5563A400FCC628 /* FindInPage.xib */, 988F3DD2237DE8D900AEE34C /* ForgetDataAlert.swift */, 8C4838B4221C8F7F008A6739 /* GestureToolbarButton.swift */, - 84E341991E2F7EFB00BDBA6F /* Main.storyboard */, + 8577A1C4255D2C0D00D43FCD /* HitTestingToolbar.swift */, + 85DDE03F2AC6FF65006ABCA2 /* MainView.swift */, F17669D61E43401C003D3222 /* MainViewController.swift */, 981CA7E92617797500E119D5 /* MainViewController+AddFavoriteFlow.swift */, 1E4F4A59297193DE00625985 /* MainViewController+CookiesManaged.swift */, 8546A5492A672959003929BF /* MainViewController+Email.swift */, 85F2FFCC2211F615006BB258 /* MainViewController+KeyCommands.swift */, - 98EF177C21837E35006750C1 /* new_tab_dark.json */, - 85371D232121B9D400920548 /* new_tab.json */, + 850ABD002AC3961100A733DF /* MainViewController+Segues.swift */, 9880723525FA4E440039EF4B /* menu_dark.json */, 9880723625FA4E450039EF4B /* menu_light.json */, - 8540BD5323D8D5080057FDD2 /* PreserveLoginsAlert.swift */, - 851DFD86212C39D300D95F20 /* TabSwitcherButton.swift */, 9880722925FA497B0039EF4B /* MenuButton.swift */, - 310742A52848CD780012660B /* BackForwardMenuHistoryItem.swift */, - 85864FBB24D31EF300E756FF /* SuggestionTrayViewController.swift */, - 8577A1C4255D2C0D00D43FCD /* HitTestingToolbar.swift */, - 6AC6DAB228804F97002723C0 /* BarsAnimator.swift */, + 98EF177C21837E35006750C1 /* new_tab_dark.json */, + 85371D232121B9D400920548 /* new_tab.json */, 31B2F11E287846320040427A /* NoMicPermissionAlert.swift */, - 854A012E2A5563A400FCC628 /* FindInPage.xib */, + 8540BD5323D8D5080057FDD2 /* PreserveLoginsAlert.swift */, + 850ABD022AC4D46C00A733DF /* SuggestionTray.storyboard */, + 85864FBB24D31EF300E756FF /* SuggestionTrayViewController.swift */, + 851DFD86212C39D300D95F20 /* TabSwitcherButton.swift */, ); name = Main; sourceTree = ""; @@ -5676,7 +5683,6 @@ 85A313972028E78A00327D00 /* release_notes.txt in Resources */, 9865DFFD22A84CF300D27829 /* FavoriteHomeCell.xib in Resources */, 1EE411FE2858B9300003FE64 /* dark-shield.json in Resources */, - 84E3419B1E2F7EFB00BDBA6F /* Main.storyboard in Resources */, 1E16260B296845120004127F /* cookie-banner-illustration-animated.json in Resources */, AA4D6AD323DE4D27007E8790 /* AppIconPurple29x29@2x.png in Resources */, AA4D6AA123DE4CC4007E8790 /* AppIconBlue60x60@3x.png in Resources */, @@ -5718,6 +5724,7 @@ 0262085B2A37915D006CB755 /* ios_blocklist_075.json in Resources */, 020108A529A681E300644F9D /* AppTP.xcassets in Resources */, AA4D6A9323DE49A5007E8790 /* AppIconBlack76x76@2x.png in Resources */, + 850ABD032AC4D46C00A733DF /* SuggestionTray.storyboard in Resources */, 1E908BF229827C480008C8F3 /* autoconsent-bundle.js in Resources */, F143C2B21E49D78C00CFDE3A /* Assets.xcassets in Resources */, AA4D6AA323DE4CC4007E8790 /* AppIconBlue40x40@3x.png in Resources */, @@ -5962,6 +5969,7 @@ 4BEF656D2989C2FC00B650CB /* EventType.swift in Sources */, 02025AAC2988229800E694E7 /* GCDHTTPProxyServer.swift in Sources */, 02025AAD2988229800E694E7 /* NWUDPSocket.swift in Sources */, + EE3766DE2AC5945500AAB575 /* NetworkProtectionUNNotificationPresenter.swift in Sources */, 02025AAE2988229800E694E7 /* RawTCPSocketProtocol.swift in Sources */, 02025AAF2988229800E694E7 /* NWTCPSocket.swift in Sources */, 02025AB12988229800E694E7 /* RawSocketFactory.swift in Sources */, @@ -6005,6 +6013,7 @@ 02025AEB2988229800E694E7 /* Utils.swift in Sources */, 02025AEC2988229800E694E7 /* AppTrackingProtectionPacketTunnelProvider.swift in Sources */, 02025B1029884DC500E694E7 /* AppTrackerDataParser.swift in Sources */, + EEFC6A602AC0F2F80065027D /* UserText.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6220,6 +6229,7 @@ 1EDE39D22705D4A200C99C72 /* FileSizeDebugViewController.swift in Sources */, 85047C772A0D5D3D00D2FF3F /* SyncSettingsViewController+SyncDelegate.swift in Sources */, 4B6484EA27FD1E350050A7A1 /* MacBrowserWaitlistView.swift in Sources */, + 85DDE0402AC6FF65006ABCA2 /* MainView.swift in Sources */, 980891A72237D5D800313A70 /* FeedbackPresenter.swift in Sources */, 989B337522D7EF2100437824 /* EmptyCollectionReusableView.swift in Sources */, 8524CC94246C5C8900E59D45 /* DaxDialogViewController.swift in Sources */, @@ -6277,6 +6287,7 @@ 85449EFD23FDA71F00512AAF /* KeyboardSettings.swift in Sources */, 980891A222369ADB00313A70 /* FeedbackUserText.swift in Sources */, 988F3DD3237DE8D900AEE34C /* ForgetDataAlert.swift in Sources */, + 850ABD012AC3961100A733DF /* MainViewController+Segues.swift in Sources */, 9817C9C321EF594700884F65 /* AutoClear.swift in Sources */, 310C4B47281B60E300BA79A9 /* AutofillLoginDetailsViewModel.swift in Sources */, 85EE7F572246685B000FE757 /* WebContainerViewController.swift in Sources */, @@ -6677,6 +6688,7 @@ 85F21DC621145DD5002631A6 /* global.swift in Sources */, F41C2DA326C1925700F9A760 /* BookmarksAndFolders.xcdatamodeld in Sources */, F4F6DFBA26EFF28A00ED7E12 /* BookmarkObjects.swift in Sources */, + EE7A92872AC6DE4700832A36 /* NetworkProtectionNotificationIdentifier.swift in Sources */, 836A941D247F23C600BF8EF5 /* UserAgentManager.swift in Sources */, 4B83397329AFB8D2003F7EA9 /* AppTrackingProtectionFeedbackModel.swift in Sources */, 85CA53A824BB343700A6288C /* Favicons.swift in Sources */, @@ -6838,38 +6850,6 @@ name = MainInterface.storyboard; sourceTree = ""; }; - 84E341991E2F7EFB00BDBA6F /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 84E3419A1E2F7EFB00BDBA6F /* Base */, - 9866DB8F251CA8F400612E3A /* bg */, - 9866DBA6251CA91800612E3A /* hr */, - 9866DBBD251CA92A00612E3A /* cs */, - 9866DBD4251CA93900612E3A /* da */, - 9866DBEB251CA94F00612E3A /* nl */, - 9866DC02251CA96200612E3A /* et */, - 9866DC19251CA99B00612E3A /* de */, - 9866DC30251CA9B000612E3A /* el */, - 9866DC47251CA9C000612E3A /* hu */, - 9866DC5E251CA9CE00612E3A /* it */, - 9866DC75251CA9E300612E3A /* lv */, - 9866DC8C251CA9F500612E3A /* lt */, - 9866DCA3251CAA0500612E3A /* pl */, - 9866DCBA251CAA2600612E3A /* ro */, - 9866DCD1251CAA3400612E3A /* sk */, - 9866DCE8251CAA4900612E3A /* sl */, - 9866DD74251CB11A00612E3A /* fi */, - 9866DD76251CB11B00612E3A /* fr */, - 9866DD7A251CB11E00612E3A /* pt */, - 9866DD7C251CB11F00612E3A /* ru */, - 9866DD7E251CB12000612E3A /* es */, - 9866DD80251CB12100612E3A /* sv */, - 9866DD82251CB12200612E3A /* tr */, - 981685472521EEF000FA91A1 /* nb */, - ); - name = Main.storyboard; - sourceTree = ""; - }; 84E3419E1E2F7EFB00BDBA6F /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( @@ -8928,7 +8908,7 @@ repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 80.2.1; + version = 80.4.1; }; }; C14882EB27F211A000D59F0C /* XCRemoteSwiftPackageReference "SwiftSoup" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 43633b0a35..10ef7c2de8 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,8 +15,8 @@ "repositoryURL": "https://github.com/DuckDuckGo/BrowserServicesKit", "state": { "branch": null, - "revision": "e955f958201a91ef353c55236361e095357e9505", - "version": "80.2.1" + "revision": "9dea0583dc6269971fb4728bd3efa1ed53f88306", + "version": "80.4.1" } }, { diff --git a/DuckDuckGo/AppDelegate.swift b/DuckDuckGo/AppDelegate.swift index 9f347056c7..3aa43b1fd5 100644 --- a/DuckDuckGo/AppDelegate.swift +++ b/DuckDuckGo/AppDelegate.swift @@ -87,7 +87,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { Configuration.setURLProvider(AppConfigurationURLProvider()) CrashCollection.start { - Pixel.fire(pixel: .dbCrashDetected, withAdditionalParameters: $0, includedParameters: [.appVersion]) + Pixel.fire(pixel: .dbCrashDetected, withAdditionalParameters: $0, includedParameters: []) } clearTmp() @@ -209,19 +209,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate { syncService.initializeIfNeeded() self.syncService = syncService - let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main) - - guard let main = storyboard.instantiateInitialViewController(creator: { coder in - MainViewController(coder: coder, - bookmarksDatabase: self.bookmarksDatabase, - bookmarksDatabaseCleaner: self.syncDataProviders.bookmarksAdapter.databaseCleaner, - appTrackingProtectionDatabase: self.appTrackingProtectionDatabase, - syncService: self.syncService, - syncDataProviders: self.syncDataProviders) - }) else { - fatalError("Could not load MainViewController") - } - + let main = MainViewController(bookmarksDatabase: bookmarksDatabase, + bookmarksDatabaseCleaner: syncDataProviders.bookmarksAdapter.databaseCleaner, + appTrackingProtectionDatabase: appTrackingProtectionDatabase, + syncService: syncService, + syncDataProviders: syncDataProviders) + main.loadViewIfNeeded() + window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = main window?.makeKeyAndVisible() @@ -677,9 +671,16 @@ extension AppDelegate: UNUserNotificationCenterDelegate { didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { if response.actionIdentifier == UNNotificationDefaultActionIdentifier { - if response.notification.request.identifier == WindowsBrowserWaitlist.notificationIdentitier { + let identifier = response.notification.request.identifier + if identifier == WindowsBrowserWaitlist.notificationIdentitier { presentWindowsBrowserWaitlistSettingsModal() } + +#if NETWORK_PROTECTION + if NetworkProtectionNotificationIdentifier(rawValue: identifier) != nil { + presentNetworkProtectionStatusSettingsModal() + } +#endif } completionHandler() @@ -689,7 +690,14 @@ extension AppDelegate: UNUserNotificationCenterDelegate { let waitlistViewController = WindowsWaitlistViewController(nibName: nil, bundle: nil) presentSettings(with: waitlistViewController) } - + +#if NETWORK_PROTECTION + private func presentNetworkProtectionStatusSettingsModal() { + let networkProtectionRoot = NetworkProtectionRootViewController() + presentSettings(with: networkProtectionRoot) + } +#endif + private func presentSettings(with viewController: UIViewController) { guard let window = window, let rootViewController = window.rootViewController as? MainViewController else { return } @@ -697,11 +705,10 @@ extension AppDelegate: UNUserNotificationCenterDelegate { // Give the `clearNavigationStack` call time to complete. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.5) { - rootViewController.performSegue(withIdentifier: "Settings", sender: nil) + rootViewController.segueToSettings() let navigationController = rootViewController.presentedViewController as? UINavigationController navigationController?.popToRootViewController(animated: false) navigationController?.pushViewController(viewController, animated: true) } } - } diff --git a/DuckDuckGo/AppTPHomeViewModel.swift b/DuckDuckGo/AppTPHomeViewModel.swift index b0b34dd723..3102d29ccc 100644 --- a/DuckDuckGo/AppTPHomeViewModel.swift +++ b/DuckDuckGo/AppTPHomeViewModel.swift @@ -87,7 +87,7 @@ class AppTPHomeViewModel: ObservableObject { guard let window = UIApplication.shared.windows.filter({ $0.isKeyWindow }).first, let rootViewController = window.rootViewController as? MainViewController else { return } - rootViewController.performSegue(withIdentifier: "Settings", sender: nil) + rootViewController.segueToSettings() let navigationController = rootViewController.presentedViewController as? UINavigationController navigationController?.popToRootViewController(animated: false) navigationController?.pushViewController(AppTPActivityHostingViewController(appTrackingProtectionDatabase: self.appTPDatabase), diff --git a/DuckDuckGo/AutofillListItemTableViewCell.swift b/DuckDuckGo/AutofillListItemTableViewCell.swift index f531ff4aa6..209ed903d8 100644 --- a/DuckDuckGo/AutofillListItemTableViewCell.swift +++ b/DuckDuckGo/AutofillListItemTableViewCell.swift @@ -118,10 +118,6 @@ class AutofillListItemTableViewCell: UITableViewCell { contentStackView.bottomAnchor.constraint(equalTo: margins.bottomAnchor) ]) } - - override func setSelected(_ selected: Bool, animated: Bool) { - super.setSelected(selected, animated: animated) - } private func setupContentView(with item: AutofillLoginListItemViewModel) { titleLabel.text = item.title diff --git a/DuckDuckGo/Base.lproj/Bookmarks.storyboard b/DuckDuckGo/Base.lproj/Bookmarks.storyboard index 92aa58dab4..8db08cb51a 100644 --- a/DuckDuckGo/Base.lproj/Bookmarks.storyboard +++ b/DuckDuckGo/Base.lproj/Bookmarks.storyboard @@ -1,9 +1,9 @@ - + - + @@ -83,7 +83,7 @@ - + diff --git a/DuckDuckGo/Base.lproj/Main.storyboard b/DuckDuckGo/Base.lproj/Main.storyboard index 4f452a66c9..2d4d19fe5a 100644 --- a/DuckDuckGo/Base.lproj/Main.storyboard +++ b/DuckDuckGo/Base.lproj/Main.storyboard @@ -1,11 +1,10 @@ - + - + - @@ -44,9 +43,6 @@ @@ -64,9 +60,6 @@ - - - @@ -115,9 +108,6 @@ - - - @@ -192,148 +182,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -342,8 +197,5 @@ - - - diff --git a/DuckDuckGo/Base.lproj/Settings.storyboard b/DuckDuckGo/Base.lproj/Settings.storyboard index a84d95d565..2bfc09156f 100644 --- a/DuckDuckGo/Base.lproj/Settings.storyboard +++ b/DuckDuckGo/Base.lproj/Settings.storyboard @@ -13,7 +13,7 @@ - + diff --git a/DuckDuckGo/BookmarksViewController.swift b/DuckDuckGo/BookmarksViewController.swift index 224604a171..78a5dca1d0 100644 --- a/DuckDuckGo/BookmarksViewController.swift +++ b/DuckDuckGo/BookmarksViewController.swift @@ -105,15 +105,13 @@ class BookmarksViewController: UIViewController, UITableViewDelegate { var favoritesController: FavoritesViewController? - fileprivate var onDidAppearAction: () -> Void = {} - - init?(coder: NSCoder, - bookmarksDatabase: CoreDataDatabase, - bookmarksSearch: BookmarksStringSearch, - parentID: NSManagedObjectID? = nil, - favicons: Favicons = Favicons.shared, - syncService: DDGSyncing, - syncDataProviders: SyncDataProviders + required init?(coder: NSCoder, + bookmarksDatabase: CoreDataDatabase, + bookmarksSearch: BookmarksStringSearch, + parentID: NSManagedObjectID? = nil, + favicons: Favicons = Favicons.shared, + syncService: DDGSyncing, + syncDataProviders: SyncDataProviders ) { self.bookmarksDatabase = bookmarksDatabase self.searchDataSource = SearchBookmarksDataSource(searchEngine: bookmarksSearch) @@ -181,10 +179,6 @@ class BookmarksViewController: UIViewController, UITableViewDelegate { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - - onDidAppearAction() - onDidAppearAction = {} - tableView.reloadData() } @@ -226,10 +220,8 @@ class BookmarksViewController: UIViewController, UITableViewDelegate { refreshAll() } - func openEditFormWhenPresented(bookmark: BookmarkEntity) { - onDidAppearAction = { [weak self] in - self?.performSegue(withIdentifier: "AddOrEditBookmarkFolder", sender: bookmark.objectID) - } + func openEditFormForBookmark(_ bookmark: BookmarkEntity) { + performSegue(withIdentifier: "AddOrEditBookmarkFolder", sender: bookmark.objectID) } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { diff --git a/DuckDuckGo/BrowserChromeManager.swift b/DuckDuckGo/BrowserChromeManager.swift index d14af209d9..183f4b87d0 100644 --- a/DuckDuckGo/BrowserChromeManager.swift +++ b/DuckDuckGo/BrowserChromeManager.swift @@ -32,7 +32,7 @@ protocol BrowserChromeDelegate: AnyObject { var barsMaxHeight: CGFloat { get } var omniBar: OmniBar! { get } - var tabsBar: UIView! { get } + var tabBarContainer: UIView { get } } class BrowserChromeManager: NSObject, UIScrollViewDelegate { diff --git a/DuckDuckGo/DaxDialogs.swift b/DuckDuckGo/DaxDialogs.swift index b26f149fc9..5e346d62c1 100644 --- a/DuckDuckGo/DaxDialogs.swift +++ b/DuckDuckGo/DaxDialogs.swift @@ -73,7 +73,7 @@ final class DaxDialogs { case .siteIsMajorTracker, .siteOwnedByMajorTracker: settings.browsingMajorTrackingSiteShown = flag settings.browsingWithoutTrackersShown = flag - } + } } struct BrowsingSpec: Equatable { diff --git a/DuckDuckGo/HomeViewController.swift b/DuckDuckGo/HomeViewController.swift index f1d31543bb..f938dca3c1 100644 --- a/DuckDuckGo/HomeViewController.swift +++ b/DuckDuckGo/HomeViewController.swift @@ -51,7 +51,7 @@ class HomeViewController: UIViewController { delegate?.home(self, searchTransitionUpdated: percent) chromeDelegate?.omniBar.alpha = percent - chromeDelegate?.tabsBar.alpha = percent + chromeDelegate?.tabBarContainer.alpha = percent } } diff --git a/DuckDuckGo/KeychainItemsDebugViewController.swift b/DuckDuckGo/KeychainItemsDebugViewController.swift index dc46a1cb80..8caa29ec13 100644 --- a/DuckDuckGo/KeychainItemsDebugViewController.swift +++ b/DuckDuckGo/KeychainItemsDebugViewController.swift @@ -115,10 +115,6 @@ private enum SecClass: CaseIterable { class KeychainItemsDebugViewController: UITableViewController { - override func viewDidLoad() { - super.viewDidLoad() - } - override func numberOfSections(in tableView: UITableView) -> Int { return SecClass.allCases.count } diff --git a/DuckDuckGo/MainView.swift b/DuckDuckGo/MainView.swift new file mode 100644 index 0000000000..c22ef7a3f8 --- /dev/null +++ b/DuckDuckGo/MainView.swift @@ -0,0 +1,335 @@ +// +// MainView.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +class MainViewFactory { + + private let coordinator: MainViewCoordinator + + var superview: UIView { + coordinator.superview + } + + private init(_ superview: UIView) { + coordinator = MainViewCoordinator(superview: superview) + } + + static func createViewHierarchy(_ superview: UIView) -> MainViewCoordinator { + let factory = MainViewFactory(superview) + + factory.createViews() + factory.disableAutoresizingOnViewAndImmediateSubviews(superview) + factory.constrainViews() + + return factory.coordinator + } + + private func disableAutoresizingOnViewAndImmediateSubviews(_ view: UIView) { + view.translatesAutoresizingMaskIntoConstraints = false + view.subviews.forEach { + $0.translatesAutoresizingMaskIntoConstraints = false + } + } + +} + +/// Create functions. The lightweight subclases of UIView make it easier to debug to the UI. +extension MainViewFactory { + + private func createViews() { + createLogoBackground() + createContentContainer() + createSuggestionTrayContainer() + createNotificationBarContainer() + createStatusBackground() + createTabBarContainer() + createNavigationBarContainer() + createProgressView() + createToolbar() + } + + private func createProgressView() { + coordinator.progress = ProgressView() + superview.addSubview(coordinator.progress) + } + + class NavigationBarContainer: UIView { } + private func createNavigationBarContainer() { + coordinator.navigationBarContainer = NavigationBarContainer() + superview.addSubview(coordinator.navigationBarContainer) + } + + class NotificationBarContainer: UIView { } + private func createNotificationBarContainer() { + coordinator.notificationBarContainer = NotificationBarContainer() + superview.addSubview(coordinator.notificationBarContainer) + } + + class ContentContainer: UIView { } + private func createContentContainer() { + coordinator.contentContainer = ContentContainer() + superview.addSubview(coordinator.contentContainer) + } + + class StatusBackgroundView: UIView { } + private func createStatusBackground() { + coordinator.statusBackground = StatusBackgroundView() + superview.addSubview(coordinator.statusBackground) + } + + class TabBarContainer: UIView { } + private func createTabBarContainer() { + coordinator.tabBarContainer = TabBarContainer() + superview.addSubview(coordinator.tabBarContainer) + } + + class SuggestionTrayContainer: UIView { } + private func createSuggestionTrayContainer() { + coordinator.suggestionTrayContainer = SuggestionTrayContainer() + coordinator.suggestionTrayContainer.isHidden = true + coordinator.suggestionTrayContainer.backgroundColor = .clear + superview.addSubview(coordinator.suggestionTrayContainer) + } + + private func createToolbar() { + + coordinator.toolbar = HitTestingToolbar() + coordinator.toolbarBackButton = UIBarButtonItem(title: UserText.keyCommandBrowserBack, image: UIImage(named: "BrowsePrevious")) + coordinator.toolbarForwardButton = UIBarButtonItem(title: UserText.keyCommandBrowserForward, image: UIImage(named: "BrowseNext")) + coordinator.toolbarFireButton = UIBarButtonItem(title: UserText.actionForgetAll, image: UIImage(named: "Fire")) + coordinator.toolbarTabSwitcherButton = UIBarButtonItem(title: UserText.tabSwitcherAccessibilityLabel, image: UIImage(named: "Add-24")) + coordinator.lastToolbarButton = UIBarButtonItem(title: UserText.actionOpenBookmarks, image: UIImage(named: "Book-24")) + superview.addSubview(coordinator.toolbar) + + coordinator.toolbar.setItems([ + coordinator.toolbarBackButton!, + .flexibleSpace(), + coordinator.toolbarForwardButton!, + .flexibleSpace(), + coordinator.toolbarFireButton!, + .flexibleSpace(), + coordinator.toolbarTabSwitcherButton!, + .flexibleSpace(), + coordinator.lastToolbarButton!, + ], animated: true) + } + + class LogoBackgroundView: UIView { } + private func createLogoBackground() { + coordinator.logoContainer = LogoBackgroundView() + coordinator.logo = UIImageView(image: UIImage(named: "Logo")) + coordinator.logoText = UIImageView(image: UIImage(named: "TextDuckDuckGo")) + + coordinator.logoContainer.backgroundColor = .clear + coordinator.logoContainer.addSubview(coordinator.logo) + coordinator.logoContainer.addSubview(coordinator.logoText) + superview.addSubview(coordinator.logoContainer) + + disableAutoresizingOnViewAndImmediateSubviews(coordinator.logoContainer) + } + +} + +/// Add constraint functions +extension MainViewFactory { + + private func constrainViews() { + constrainLogoBackground() + constrainContentContainer() + constrainSuggestionTrayContainer() + constrainNotificationBarContainer() + constrainStatusBackground() + constrainTabBarContainer() + constrainNavigationBarContainer() + constrainProgress() + constrainToolbar() + } + + private func constrainProgress() { + let progress = coordinator.progress! + let navigationBarContainer = coordinator.navigationBarContainer! + NSLayoutConstraint.activate([ + progress.constrainView(navigationBarContainer, by: .trailing), + progress.constrainView(navigationBarContainer, by: .leading), + progress.constrainAttribute(.height, to: 3), + progress.constrainView(navigationBarContainer, by: .top, to: .bottom), + ]) + } + + private func constrainNavigationBarContainer() { + let navigationBarContainer = coordinator.navigationBarContainer! + + coordinator.constraints.navigationBarContainerTop = navigationBarContainer.constrainView(superview.safeAreaLayoutGuide, by: .top) + + NSLayoutConstraint.activate([ + navigationBarContainer.constrainView(superview, by: .centerX), + navigationBarContainer.constrainView(superview, by: .width), + coordinator.constraints.navigationBarContainerTop, + navigationBarContainer.constrainAttribute(.height, to: 52), + ]) + } + + private func constrainTabBarContainer() { + let tabBarContainer = coordinator.tabBarContainer! + + coordinator.constraints.tabBarContainerTop = tabBarContainer.constrainView(superview.safeAreaLayoutGuide, by: .top) + + NSLayoutConstraint.activate([ + tabBarContainer.constrainView(superview, by: .leading), + tabBarContainer.constrainView(superview, by: .trailing), + tabBarContainer.constrainAttribute(.height, to: 40), + coordinator.constraints.tabBarContainerTop, + ]) + } + + private func constrainStatusBackground() { + let statusBackground = coordinator.statusBackground! + let navigationBarContainer = coordinator.navigationBarContainer! + NSLayoutConstraint.activate([ + statusBackground.constrainView(superview, by: .width), + statusBackground.constrainView(superview, by: .centerX), + statusBackground.constrainView(superview, by: .top), + statusBackground.constrainView(navigationBarContainer, by: .bottom), + ]) + } + + private func constrainNotificationBarContainer() { + let notificationBarContainer = coordinator.notificationBarContainer! + let contentContainer = coordinator.contentContainer! + let navigationBarContainer = coordinator.navigationBarContainer! + + coordinator.constraints.notificationContainerTop = notificationBarContainer.constrainView(navigationBarContainer, by: .top, to: .bottom) + coordinator.constraints.notificationContainerHeight = notificationBarContainer.constrainAttribute(.height, to: 0) + + NSLayoutConstraint.activate([ + notificationBarContainer.constrainView(superview, by: .width), + notificationBarContainer.constrainView(superview, by: .centerX), + coordinator.constraints.notificationContainerHeight, + notificationBarContainer.constrainView(contentContainer, by: .bottom, to: .top), + coordinator.constraints.notificationContainerTop, + ]) + } + + private func constrainContentContainer() { + let contentContainer = coordinator.contentContainer! + let toolbar = coordinator.toolbar! + let notificationBarContainer = coordinator.notificationBarContainer! + + coordinator.constraints.contentContainerTop = contentContainer.constrainView(notificationBarContainer, by: .top, to: .bottom) + + NSLayoutConstraint.activate([ + contentContainer.constrainView(superview, by: .leading), + contentContainer.constrainView(superview, by: .trailing), + contentContainer.constrainView(toolbar, by: .bottom, to: .top), + coordinator.constraints.contentContainerTop, + ]) + } + + private func constrainToolbar() { + let toolbar = coordinator.toolbar! + coordinator.constraints.toolbarBottom = toolbar.constrainView(superview.safeAreaLayoutGuide, by: .bottom) + NSLayoutConstraint.activate([ + toolbar.constrainView(superview, by: .width), + toolbar.constrainView(superview, by: .centerX), + toolbar.constrainAttribute(.height, to: 49), + coordinator.constraints.toolbarBottom, + ]) + } + + private func constrainSuggestionTrayContainer() { + let suggestionTrayContainer = coordinator.suggestionTrayContainer! + let contentContainer = coordinator.contentContainer! + NSLayoutConstraint.activate([ + suggestionTrayContainer.constrainView(contentContainer, by: .width), + suggestionTrayContainer.constrainView(contentContainer, by: .height), + suggestionTrayContainer.constrainView(contentContainer, by: .centerX), + suggestionTrayContainer.constrainView(contentContainer, by: .centerY), + ]) + } + + private func constrainLogoBackground() { + let logoContainer = coordinator.logoContainer! + let logo = coordinator.logo! + let text = coordinator.logoText! + NSLayoutConstraint.activate([ + logoContainer.constrainView(superview, by: .width), + logoContainer.constrainView(superview, by: .height), + logoContainer.constrainView(superview, by: .centerX), + logoContainer.constrainView(superview, by: .centerY), + logo.constrainView(logoContainer, by: .centerX), + logo.constrainView(logoContainer, by: .centerY, constant: -72), + logo.constrainAttribute(.width, to: 96), + logo.constrainAttribute(.height, to: 96), + text.constrainView(logo, by: .top, to: .bottom, constant: 12), + text.constrainView(logo, by: .centerX), + ]) + } + +} + +class MainViewCoordinator { + + let superview: UIView + + var logoContainer: UIView! + var logo: UIImageView! + var logoText: UIImageView! + var toolbar: UIToolbar! + var suggestionTrayContainer: UIView! + var contentContainer: UIView! + var notificationBarContainer: UIView! + var statusBackground: UIView! + var tabBarContainer: UIView! + var navigationBarContainer: UIView! + var progress: ProgressView! + var toolbarBackButton: UIBarButtonItem! + var toolbarForwardButton: UIBarButtonItem! + var toolbarFireButton: UIBarButtonItem! + var toolbarTabSwitcherButton: UIBarButtonItem! + var lastToolbarButton: UIBarButtonItem! + + let constraints = Constraints() + + fileprivate init(superview: UIView) { + self.superview = superview + } + + func decorateWithTheme(_ theme: Theme) { + superview.backgroundColor = theme.mainViewBackgroundColor + logoText.tintColor = theme.ddgTextTintColor + } + + func hideSuggestionTray() { + suggestionTrayContainer.isHidden = true + suggestionTrayContainer.backgroundColor = .clear + } + + class Constraints { + + var navigationBarContainerTop: NSLayoutConstraint! + var toolbarBottom: NSLayoutConstraint! + var contentContainerTop: NSLayoutConstraint! + var tabBarContainerTop: NSLayoutConstraint! + var notificationContainerTop: NSLayoutConstraint! + var notificationContainerHeight: NSLayoutConstraint! + + } + +} diff --git a/DuckDuckGo/MainViewController+Segues.swift b/DuckDuckGo/MainViewController+Segues.swift new file mode 100644 index 0000000000..e1dddc6396 --- /dev/null +++ b/DuckDuckGo/MainViewController+Segues.swift @@ -0,0 +1,226 @@ +// +// MainViewController+Segues.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import Common +import Core +import Bookmarks +import BrowserServicesKit + +extension MainViewController { + + func segueToDaxOnboarding() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + let storyboard = UIStoryboard(name: "DaxOnboarding", bundle: nil) + guard let controller = storyboard.instantiateInitialViewController(creator: { coder in + DaxOnboardingViewController(coder: coder) + }) else { + assertionFailure() + return + } + controller.delegate = self + controller.modalPresentationStyle = .overFullScreen + present(controller, animated: false) + } + + func segueToHomeRow() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + let storyboard = UIStoryboard(name: "HomeRow", bundle: nil) + guard let controller = storyboard.instantiateInitialViewController() else { + assertionFailure() + return + } + controller.modalPresentationStyle = .overCurrentContext + present(controller, animated: true) + } + + func segueToBookmarks() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + launchBookmarksViewController() + } + + func segueToEditCurrentBookmark() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + guard let link = currentTab?.link, + let bookmark = menuBookmarksViewModel.favorite(for: link.url) ?? + menuBookmarksViewModel.bookmark(for: link.url) else { + assertionFailure() + return + } + segueToEditBookmark(bookmark) + } + + func segueToEditBookmark(_ bookmark: BookmarkEntity) { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + launchBookmarksViewController { + $0.openEditFormForBookmark(bookmark) + } + } + + private func launchBookmarksViewController(completion: ((BookmarksViewController) -> Void)? = nil) { + os_log(#function, log: .generalLog, type: .debug) + + let storyboard = UIStoryboard(name: "Bookmarks", bundle: nil) + let bookmarks = storyboard.instantiateViewController(identifier: "BookmarksViewController") { coder in + BookmarksViewController(coder: coder, + bookmarksDatabase: self.bookmarksDatabase, + bookmarksSearch: self.bookmarksCachingSearch, + syncService: self.syncService, + syncDataProviders: self.syncDataProviders) + } + bookmarks.delegate = self + + let controller = ThemableNavigationController(rootViewController: bookmarks) + controller.modalPresentationStyle = .automatic + present(controller, animated: true) { + completion?(bookmarks) + } + } + + func segueToActionSheetDaxDialogWithSpec(_ spec: DaxDialogs.ActionSheetSpec) { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + + if spec == DaxDialogs.ActionSheetSpec.fireButtonEducation { + ViewHighlighter.hideAll() + } + + let storyboard = UIStoryboard(name: "DaxOnboarding", bundle: nil) + let controller = storyboard.instantiateViewController(identifier: "ActionSheetDaxDialog", creator: { coder in + ActionSheetDaxDialogViewController(coder: coder) + }) + controller.spec = spec + controller.delegate = self + controller.modalTransitionStyle = .crossDissolve + controller.modalPresentationStyle = .overFullScreen + present(controller, animated: true) + } + + func segueToReportBrokenSite() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + + let storyboard = UIStoryboard(name: "Feedback", bundle: nil) + guard let controller: UINavigationController = storyboard.instantiateInitialViewController(), + let brokenSiteScreen = controller.topViewController as? ReportBrokenSiteViewController else { + assertionFailure() + return + } + + brokenSiteScreen.brokenSiteInfo = currentTab?.getCurrentWebsiteInfo() + + if UIDevice.current.userInterfaceIdiom == .pad { + controller.modalPresentationStyle = .formSheet + } else { + controller.modalPresentationStyle = .pageSheet + } + + present(controller, animated: true) + } + + func segueToDownloads() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + + let storyboard = UIStoryboard(name: "Downloads", bundle: nil) + guard let controller = storyboard.instantiateInitialViewController() else { + assertionFailure() + return + } + present(controller, animated: true) + } + + func segueToTabSwitcher() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + + let storyboard = UIStoryboard(name: "TabSwitcher", bundle: nil) + guard let controller = storyboard.instantiateInitialViewController(creator: { coder in + TabSwitcherViewController(coder: coder, + bookmarksDatabase: self.bookmarksDatabase, + syncService: self.syncService) + }) else { + assertionFailure() + return + } + + controller.transitioningDelegate = tabSwitcherTransition + controller.delegate = self + controller.tabsModel = tabManager.model + controller.previewsSource = previewsSource + controller.modalPresentationStyle = .overCurrentContext + + tabSwitcherController = controller + + present(controller, animated: true) + } + + func segueToSettings() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + launchSettings() + } + + func segueToSettingsCookiePopupManagement() { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + launchSettings { + $0.openCookiePopupManagement() + } + } + + func segueToSettingsLoginsWithAccount(_ account: SecureVaultModels.WebsiteAccount) { + os_log(#function, log: .generalLog, type: .debug) + hideAllHighlightsIfNeeded() + launchSettings { + $0.openLogins(accountDetails: account) + } + } + + private func launchSettings(completion: ((SettingsViewController) -> Void)? = nil) { + os_log(#function, log: .generalLog, type: .debug) + let storyboard = UIStoryboard(name: "Settings", bundle: nil) + + let settings = storyboard.instantiateViewController(identifier: "SettingsViewController") { coder in + SettingsViewController(coder: coder, + bookmarksDatabase: self.bookmarksDatabase, + syncService: self.syncService, + syncDataProviders: self.syncDataProviders, + internalUserDecider: AppDependencyProvider.shared.internalUserDecider) + } + + let controller = ThemableNavigationController(rootViewController: settings) + controller.modalPresentationStyle = .automatic + present(controller, animated: true) { + completion?(settings) + } + } + + private func hideAllHighlightsIfNeeded() { + os_log(#function, log: .generalLog, type: .debug) + if !DaxDialogs.shared.shouldShowFireButtonPulse { + ViewHighlighter.hideAll() + } + } +} diff --git a/DuckDuckGo/MainViewController.swift b/DuckDuckGo/MainViewController.swift index ebb3836fd8..ceda17d760 100644 --- a/DuckDuckGo/MainViewController.swift +++ b/DuckDuckGo/MainViewController.swift @@ -31,8 +31,8 @@ import Persistence import PrivacyDashboard import Networking -// swiftlint:disable type_body_length // swiftlint:disable file_length +// swiftlint:disable type_body_length class MainViewController: UIViewController { // swiftlint:enable type_body_length @@ -45,34 +45,6 @@ class MainViewController: UIViewController { return isIPad ? [.left, .right] : [] } - - @IBOutlet weak var progressView: ProgressView! - - @IBOutlet weak var suggestionTrayContainer: UIView! - @IBOutlet weak var customNavigationBar: UIView! - @IBOutlet weak var containerView: UIView! - @IBOutlet weak var fireButton: UIBarButtonItem! - @IBOutlet weak var lastToolbarButton: UIBarButtonItem! - @IBOutlet weak var backButton: UIBarButtonItem! - @IBOutlet weak var forwardButton: UIBarButtonItem! - @IBOutlet weak var tabsButton: UIBarButtonItem! - @IBOutlet weak var toolbar: UIToolbar! - @IBOutlet weak var navBarTop: NSLayoutConstraint! - @IBOutlet weak var toolbarBottom: NSLayoutConstraint! - @IBOutlet weak var containerViewTop: NSLayoutConstraint! - - @IBOutlet weak var tabsBar: UIView! - @IBOutlet weak var tabsBarTop: NSLayoutConstraint! - - @IBOutlet weak var notificationContainer: UIView! - @IBOutlet weak var notificationContainerTop: NSLayoutConstraint! - @IBOutlet weak var notificationContainerHeight: NSLayoutConstraint! - - @IBOutlet weak var statusBarBackground: UIView! - - @IBOutlet weak var logoContainer: UIView! - @IBOutlet weak var logo: UIImageView! - @IBOutlet weak var logoText: UIImageView! weak var findInPageView: FindInPageView! weak var findInPageHeightLayoutConstraint: NSLayoutConstraint! @@ -85,12 +57,12 @@ class MainViewController: UIViewController { var allowContentUnderflow = false { didSet { - containerViewTop.constant = allowContentUnderflow ? contentUnderflow : 0 + viewCoordinator.constraints.contentContainerTop.constant = allowContentUnderflow ? contentUnderflow : 0 } } var contentUnderflow: CGFloat { - return 3 + (allowContentUnderflow ? -customNavigationBar.frame.size.height : 0) + return 3 + (allowContentUnderflow ? -viewCoordinator.navigationBarContainer.frame.size.height : 0) } lazy var emailManager: EmailManager = { @@ -105,16 +77,16 @@ class MainViewController: UIViewController { var suggestionTrayController: SuggestionTrayViewController? var tabManager: TabManager! - private let previewsSource = TabPreviewsSource() + let previewsSource = TabPreviewsSource() fileprivate lazy var appSettings: AppSettings = AppUserDefaults() private var launchTabObserver: LaunchTabNotification.Observer? private let appTrackingProtectionDatabase: CoreDataDatabase - private let bookmarksDatabase: CoreDataDatabase + let bookmarksDatabase: CoreDataDatabase private weak var bookmarksDatabaseCleaner: BookmarkDatabaseCleaner? private let favoritesViewModel: FavoritesListInteracting - private let syncService: DDGSyncing - private let syncDataProviders: SyncDataProviders + let syncService: DDGSyncing + let syncDataProviders: SyncDataProviders private var localUpdatesCancellable: AnyCancellable? private var syncUpdatesCancellable: AnyCancellable? private var emailCancellables = Set() @@ -134,9 +106,9 @@ class MainViewController: UIViewController { private lazy var fireButtonAnimator: FireButtonAnimator = FireButtonAnimator(appSettings: appSettings) - private var bookmarksCachingSearch: BookmarksCachingSearch + let bookmarksCachingSearch: BookmarksCachingSearch - fileprivate lazy var tabSwitcherTransition = TabSwitcherTransitionDelegate() + lazy var tabSwitcherTransition = TabSwitcherTransitionDelegate() var currentTab: TabViewController? { return tabManager?.current } @@ -147,12 +119,18 @@ class MainViewController: UIViewController { // Skip SERP flow (focusing on autocomplete logic) and prepare for new navigation when selecting search bar private var skipSERPFlow = true - required init?(coder: NSCoder, - bookmarksDatabase: CoreDataDatabase, - bookmarksDatabaseCleaner: BookmarkDatabaseCleaner, - appTrackingProtectionDatabase: CoreDataDatabase, - syncService: DDGSyncing, - syncDataProviders: SyncDataProviders + required init?(coder: NSCoder) { + fatalError("Use init?(code:") + } + + var viewCoordinator: MainViewCoordinator! + + init( + bookmarksDatabase: CoreDataDatabase, + bookmarksDatabaseCleaner: BookmarkDatabaseCleaner, + appTrackingProtectionDatabase: CoreDataDatabase, + syncService: DDGSyncing, + syncDataProviders: SyncDataProviders ) { self.appTrackingProtectionDatabase = appTrackingProtectionDatabase self.bookmarksDatabase = bookmarksDatabase @@ -161,12 +139,10 @@ class MainViewController: UIViewController { self.syncDataProviders = syncDataProviders self.favoritesViewModel = FavoritesListViewModel(bookmarksDatabase: bookmarksDatabase) self.bookmarksCachingSearch = BookmarksCachingSearch(bookmarksStore: CoreDataBookmarksSearchStore(bookmarksStore: bookmarksDatabase)) - super.init(coder: coder) - bindSyncService() - } - required init?(coder: NSCoder) { - fatalError("Use init?(code:") + super.init(nibName: nil, bundle: nil) + + bindSyncService() } fileprivate var tabCountInfo: TabCountInfo? @@ -197,6 +173,14 @@ class MainViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + viewCoordinator = MainViewFactory.createViewHierarchy(self.view) + + viewCoordinator.toolbarBackButton.action = #selector(onBackPressed) + viewCoordinator.toolbarForwardButton.action = #selector(onForwardPressed) + viewCoordinator.toolbarFireButton.action = #selector(onFirePressed) + + loadSuggestionTray() + loadTabsBarIfNeeded() loadFindInPage() attachOmniBar() @@ -235,11 +219,51 @@ class MainViewController: UIViewController { startOnboardingFlowIfNotSeenBefore() tabsBarController?.refresh(tabsModel: tabManager.model) + _ = AppWidthObserver.shared.willResize(toWidth: view.frame.width) + applyWidth() + if DaxDialogs.shared.shouldShowFireButtonPulse { showFireButtonPulse() } } + override func performSegue(withIdentifier identifier: String, sender: Any?) { + assertionFailure() + super.performSegue(withIdentifier: identifier, sender: sender) + } + + func loadSuggestionTray() { + let storyboard = UIStoryboard(name: "SuggestionTray", bundle: nil) + + guard let controller = storyboard.instantiateInitialViewController(creator: { coder in + SuggestionTrayViewController(coder: coder, + favoritesViewModel: self.favoritesViewModel, + bookmarksSearch: self.bookmarksCachingSearch) + }) else { + assertionFailure() + return + } + + controller.view.frame = viewCoordinator.suggestionTrayContainer.bounds + viewCoordinator.suggestionTrayContainer.addSubview(controller.view) + + controller.dismissHandler = dismissSuggestionTray + controller.autocompleteDelegate = self + controller.favoritesOverlayDelegate = self + suggestionTrayController = controller + } + + func loadTabsBarIfNeeded() { + guard isPad else { return } + + let storyboard = UIStoryboard(name: "TabSwitcher", bundle: nil) + let controller: TabsBarViewController = storyboard.instantiateViewController(identifier: "TabsBar") + controller.view.frame = viewCoordinator.tabBarContainer.bounds + controller.delegate = self + viewCoordinator.tabBarContainer.addSubview(controller.view) + tabsBarController = controller + } + func startAddFavoriteFlow() { DaxDialogs.shared.enableAddFavoriteFlow() if DefaultTutorialSettings().hasSeenOnboarding { @@ -260,9 +284,8 @@ class MainViewController: UIViewController { ProcessInfo.processInfo.environment["ONBOARDING"] == "true" guard showOnboarding else { return } - let onboardingFlow = "DaxOnboarding" + segueToDaxOnboarding() - performSegue(withIdentifier: onboardingFlow, sender: self) } private func registerForKeyboardNotifications() { @@ -320,15 +343,15 @@ class MainViewController: UIViewController { private func initTabButton() { tabSwitcherButton.delegate = self - tabsButton.customView = tabSwitcherButton - tabsButton.isAccessibilityElement = true - tabsButton.accessibilityTraits = .button + viewCoordinator.toolbarTabSwitcherButton.customView = tabSwitcherButton + viewCoordinator.toolbarTabSwitcherButton.isAccessibilityElement = true + viewCoordinator.toolbarTabSwitcherButton.accessibilityTraits = .button } private func initMenuButton() { - lastToolbarButton.customView = menuButton - lastToolbarButton.isAccessibilityElement = true - lastToolbarButton.accessibilityTraits = .button + viewCoordinator.lastToolbarButton.customView = menuButton + viewCoordinator.lastToolbarButton.isAccessibilityElement = true + viewCoordinator.lastToolbarButton.accessibilityTraits = .button menuButton.delegate = self } @@ -372,118 +395,6 @@ class MainViewController: UIViewController { currentTab?.saveAsBookmark(favorite: true, viewModel: menuBookmarksViewModel) } - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - - if !DaxDialogs.shared.shouldShowFireButtonPulse { - ViewHighlighter.hideAll() - } - - if let controller = segue.destination as? TabsBarViewController { - controller.delegate = self - tabsBarController = controller - return - } - - if let navController = segue.destination as? UINavigationController { - if let brokenSiteScreen = navController.topViewController as? ReportBrokenSiteViewController { - if UIDevice.current.userInterfaceIdiom == .pad { - segue.destination.modalPresentationStyle = .formSheet - } - - brokenSiteScreen.brokenSiteInfo = currentTab?.getCurrentWebsiteInfo() - } - } - - if var onboarding = segue.destination as? Onboarding { - onboarding.delegate = self - } - - if let controller = segue.destination as? ActionSheetDaxDialogViewController { - let spec = sender as? DaxDialogs.ActionSheetSpec - if spec == DaxDialogs.ActionSheetSpec.fireButtonEducation { - ViewHighlighter.hideAll() - } - controller.spec = spec - controller.delegate = self - } - - } - - @IBSegueAction func onCreateSuggestionTray(_ coder: NSCoder, sender: Any?, segueIdentifier: String?) -> SuggestionTrayViewController { - guard let controller = SuggestionTrayViewController(coder: coder, - favoritesViewModel: favoritesViewModel, - bookmarksSearch: bookmarksCachingSearch) else { - fatalError("Failed to create controller") - } - - controller.dismissHandler = dismissSuggestionTray - controller.autocompleteDelegate = self - controller.favoritesOverlayDelegate = self - suggestionTrayController = controller - - return controller - } - - @IBSegueAction func onCreateBookmarksList(_ coder: NSCoder, sender: Any?, segueIdentifier: String?) -> BookmarksViewController { - guard let controller = BookmarksViewController(coder: coder, - bookmarksDatabase: self.bookmarksDatabase, - bookmarksSearch: bookmarksCachingSearch, - syncService: syncService, - syncDataProviders: syncDataProviders) else { - fatalError("Failed to create controller") - } - controller.delegate = self - - if segueIdentifier == "BookmarksEditCurrent", - let link = currentTab?.link, - let bookmark = menuBookmarksViewModel.favorite(for: link.url) ?? menuBookmarksViewModel.bookmark(for: link.url) { - controller.openEditFormWhenPresented(bookmark: bookmark) - } else if segueIdentifier == "BookmarksEdit", - let bookmark = sender as? BookmarkEntity { - controller.openEditFormWhenPresented(bookmark: bookmark) - } - - return controller - } - - @IBSegueAction func onCreateTabSwitcher(_ coder: NSCoder, sender: Any?, segueIdentifier: String?) -> TabSwitcherViewController { - guard let controller = TabSwitcherViewController(coder: coder, - bookmarksDatabase: bookmarksDatabase, - syncService: syncService) else { - fatalError("Failed to create controller") - } - - controller.transitioningDelegate = tabSwitcherTransition - controller.delegate = self - controller.tabsModel = tabManager.model - controller.previewsSource = previewsSource - tabSwitcherController = controller - - return controller - } - - @IBSegueAction func onCreateSettings(_ coder: NSCoder, sender: Any?, segueIdentifier: String?) -> SettingsViewController { - guard let controller = SettingsViewController(coder: coder, - bookmarksDatabase: bookmarksDatabase, - syncService: syncService, - syncDataProviders: syncDataProviders, - internalUserDecider: AppDependencyProvider.shared.internalUserDecider) else { - fatalError("Failed to create controller") - } - - if segueIdentifier == "SettingsToLogins" { - if let account = sender as? SecureVaultModels.WebsiteAccount { - controller.openLoginsWhenPresented(accountDetails: account) - } else { - controller.openLoginsWhenPresented() - } - } else if segueIdentifier == "SettingsToCookiePopupManagement" { - controller.openCookiePopupManagementWhenPresented() - } - - return controller - } - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) @@ -571,12 +482,12 @@ class MainViewController: UIViewController { omniBar = OmniBar.loadFromXib() omniBar.omniDelegate = self omniBar.menuButtonContent.delegate = self - omniBar.frame = customNavigationBar.bounds - customNavigationBar.addSubview(omniBar) + omniBar.frame = viewCoordinator.navigationBarContainer.bounds + viewCoordinator.navigationBarContainer.addSubview(omniBar) } fileprivate func attachHomeScreen() { - logoContainer.isHidden = false + viewCoordinator.logoContainer.isHidden = false findInPageView.isHidden = true chromeManager.detach() @@ -612,12 +523,12 @@ class MainViewController: UIViewController { wakeLazyFireButtonAnimator() if let spec = DaxDialogs.shared.fireButtonEducationMessage() { - performSegue(withIdentifier: "ActionSheetDaxDialog", sender: spec) + segueToActionSheetDaxDialogWithSpec(spec) } else { let alert = ForgetDataAlert.buildAlert(forgetTabsAndDataHandler: { [weak self] in self?.forgetAllWithAnimation {} }) - self.present(controller: alert, fromView: self.toolbar) + self.present(controller: alert, fromView: self.viewCoordinator.toolbar) } } @@ -666,7 +577,7 @@ class MainViewController: UIViewController { func loadUrlInNewTab(_ url: URL, reuseExisting: Bool = false, inheritedAttribution: AdClickAttributionLogic.State?) { allowContentUnderflow = false - customNavigationBar.alpha = 1 + viewCoordinator.navigationBarContainer.alpha = 1 loadViewIfNeeded() if reuseExisting, let existing = tabManager.first(withUrl: url) { selectTab(existing) @@ -721,7 +632,7 @@ class MainViewController: UIViewController { } private func prepareTabForRequest(request: () -> Void) { - customNavigationBar.alpha = 1 + viewCoordinator.navigationBarContainer.alpha = 1 allowContentUnderflow = false request() guard let tab = currentTab else { fatalError("no tab") } @@ -736,7 +647,7 @@ class MainViewController: UIViewController { } func select(tabAt index: Int) { - customNavigationBar.alpha = 1 + viewCoordinator.navigationBarContainer.alpha = 1 allowContentUnderflow = false let tab = tabManager.select(tabAt: index) select(tab: tab) @@ -761,16 +672,16 @@ class MainViewController: UIViewController { currentTab?.progressWorker.progressBar = nil currentTab?.chromeDelegate = nil addToView(controller: tab) - tab.progressWorker.progressBar = progressView + tab.progressWorker.progressBar = viewCoordinator.progress chromeManager.attach(to: tab.webView.scrollView) tab.chromeDelegate = self } private func addToView(controller: UIViewController) { addChild(controller) - containerView.subviews.forEach { $0.removeFromSuperview() } - containerView.addSubview(controller.view) - controller.view.frame = containerView.bounds + viewCoordinator.contentContainer.subviews.forEach { $0.removeFromSuperview() } + viewCoordinator.contentContainer.addSubview(controller.view) + controller.view.frame = viewCoordinator.contentContainer.bounds controller.didMove(toParent: self) } @@ -793,7 +704,7 @@ class MainViewController: UIViewController { } private func refreshTabIcon() { - tabsButton.accessibilityHint = UserText.numberOfTabs(tabManager.count) + viewCoordinator.toolbarTabSwitcherButton.accessibilityHint = UserText.numberOfTabs(tabManager.count) tabSwitcherButton.tabCount = tabManager.count tabSwitcherButton.hasUnread = tabManager.hasUnread } @@ -824,11 +735,11 @@ class MainViewController: UIViewController { } fileprivate func refreshBackForwardButtons() { - backButton.isEnabled = currentTab?.canGoBack ?? false - forwardButton.isEnabled = currentTab?.canGoForward ?? false + viewCoordinator.toolbarBackButton.isEnabled = currentTab?.canGoBack ?? false + viewCoordinator.toolbarForwardButton.isEnabled = currentTab?.canGoForward ?? false - omniBar.backButton.isEnabled = backButton.isEnabled - omniBar.forwardButton.isEnabled = forwardButton.isEnabled + omniBar.backButton.isEnabled = viewCoordinator.toolbarBackButton.isEnabled + omniBar.forwardButton.isEnabled = viewCoordinator.toolbarForwardButton.isEnabled } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -857,7 +768,7 @@ class MainViewController: UIViewController { DispatchQueue.main.async { // Do this async otherwise the toolbar buttons skew to the right - if self.navBarTop.constant >= 0 { + if self.viewCoordinator.constraints.navigationBarContainerTop.constant >= 0 { self.showBars() } // If tabs have been udpated, do this async to make sure size calcs are current @@ -874,7 +785,7 @@ class MainViewController: UIViewController { let expectedState: MenuButton.State if homeController != nil { expectedState = .bookmarksImage - lastToolbarButton.accessibilityLabel = UserText.bookmarksButtonHint + viewCoordinator.lastToolbarButton.accessibilityLabel = UserText.bookmarksButtonHint omniBar.menuButton.accessibilityLabel = UserText.bookmarksButtonHint } else { @@ -883,7 +794,7 @@ class MainViewController: UIViewController { } else { expectedState = .menuImage } - lastToolbarButton.accessibilityLabel = UserText.menuButtonHint + viewCoordinator.lastToolbarButton.accessibilityLabel = UserText.menuButtonHint omniBar.menuButton.accessibilityLabel = UserText.menuButtonHint } @@ -900,14 +811,14 @@ class MainViewController: UIViewController { } private func applyLargeWidth() { - tabsBar.isHidden = false - toolbar.isHidden = true + viewCoordinator.tabBarContainer.isHidden = false + viewCoordinator.toolbar.isHidden = true omniBar.enterPadState() } private func applySmallWidth() { - tabsBar.isHidden = true - toolbar.isHidden = false + viewCoordinator.tabBarContainer.isHidden = true + viewCoordinator.toolbar.isHidden = false omniBar.enterPhoneState() } @@ -931,25 +842,17 @@ class MainViewController: UIViewController { omniBar.hideSeparator() } } - suggestionTrayContainer.isHidden = false + viewCoordinator.suggestionTrayContainer.isHidden = false currentTab?.webView.accessibilityElementsHidden = true } func hideSuggestionTray() { omniBar.showSeparator() - suggestionTrayContainer.isHidden = true + viewCoordinator.suggestionTrayContainer.isHidden = true currentTab?.webView.accessibilityElementsHidden = false suggestionTrayController?.didHide() } - fileprivate func launchReportBrokenSite() { - performSegue(withIdentifier: "ReportBrokenSite", sender: self) - } - - fileprivate func launchDownloads() { - performSegue(withIdentifier: "Downloads", sender: self) - } - fileprivate func launchAutofillLogins(with currentTabUrl: URL? = nil) { let appSettings = AppDependencyProvider.shared.appSettings let autofillSettingsViewController = AutofillLoginSettingsListViewController( @@ -974,24 +877,12 @@ class MainViewController: UIViewController { @objc private func closeAutofillModal() { dismiss(animated: true) } - - func launchSettings() { - performSegue(withIdentifier: "Settings", sender: self) - } - - func launchCookiePopupManagementSettings() { - performSegue(withIdentifier: "SettingsToCookiePopupManagement", sender: self) - } - - fileprivate func launchInstructions() { - performSegue(withIdentifier: "instructions", sender: self) - } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() notificationView?.layoutSubviews() let height = notificationView?.frame.size.height ?? 0 - notificationContainerHeight.constant = height + viewCoordinator.constraints.notificationContainerHeight.constant = height ViewHighlighter.updatePositions() } @@ -1001,13 +892,13 @@ class MainViewController: UIViewController { notificationView.setTitle(text: title) notificationView.setMessage(text: message) - notificationContainer.addSubview(notificationView) - notificationContainerTop.constant = -notificationView.frame.size.height + viewCoordinator.notificationBarContainer.addSubview(notificationView) + viewCoordinator.constraints.notificationContainerTop.constant = -notificationView.frame.size.height self.notificationView = notificationView DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - self.notificationContainerTop.constant = 0 - self.notificationContainerHeight.constant = notificationView.frame.size.height + self.viewCoordinator.constraints.notificationContainerTop.constant = 0 + self.viewCoordinator.constraints.notificationContainerHeight.constant = notificationView.frame.size.height UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } @@ -1017,12 +908,12 @@ class MainViewController: UIViewController { func hideNotification() { - notificationContainerTop.constant = -(notificationView?.frame.size.height ?? 0) - notificationContainerHeight.constant = 0 + viewCoordinator.constraints.notificationContainerTop.constant = -(notificationView?.frame.size.height ?? 0) + viewCoordinator.constraints.notificationContainerHeight.constant = 0 UIView.animate(withDuration: 0.5, animations: { self.view.layoutIfNeeded() }, completion: { _ in - self.notificationContainerTop.constant = 0 + self.viewCoordinator.constraints.notificationContainerTop.constant = 0 self.notificationView?.removeFromSuperview() }) @@ -1033,7 +924,7 @@ class MainViewController: UIViewController { if feature.showNow() { showNotification(title: UserText.homeRowReminderTitle, message: UserText.homeRowReminderMessage) { tapped in if tapped { - self.launchInstructions() + self.segueToHomeRow() } self.hideNotification() } @@ -1048,13 +939,13 @@ class MainViewController: UIViewController { } func replaceToolbar(item target: UIBarButtonItem, with replacement: UIBarButtonItem) { - guard let items = toolbar.items else { return } + guard let items = viewCoordinator.toolbar.items else { return } let newItems = items.compactMap({ $0 == target ? replacement : $0 }) - toolbar.setItems(newItems, animated: false) + viewCoordinator.toolbar.setItems(newItems, animated: false) } func newTab(reuseExisting: Bool = false, allowingKeyboard: Bool = true) { @@ -1076,12 +967,12 @@ class MainViewController: UIViewController { } func animateLogoAppearance() { - logoContainer.alpha = 0 - logoContainer.transform = CGAffineTransform(scaleX: 0.5, y: 0.5) + viewCoordinator.logoContainer.alpha = 0 + viewCoordinator.logoContainer.transform = CGAffineTransform(scaleX: 0.5, y: 0.5) DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { UIView.animate(withDuration: 0.2) { - self.logoContainer.alpha = 1 - self.logoContainer.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) + self.viewCoordinator.logoContainer.alpha = 1 + self.viewCoordinator.logoContainer.transform = CGAffineTransform(scaleX: 1.0, y: 1.0) } } } @@ -1090,7 +981,7 @@ class MainViewController: UIViewController { currentTab?.findInPage?.delegate = self findInPageView.update(with: currentTab?.findInPage, updateTextField: true) // hide toolbar on iPhone - toolbar.accessibilityElementsHidden = !AppWidthObserver.shared.isLargeWidth + viewCoordinator.toolbar.accessibilityElementsHidden = !AppWidthObserver.shared.isLargeWidth } private func showVoiceSearch() { @@ -1173,7 +1064,7 @@ extension MainViewController: FindInPageViewDelegate { func done(findInPageView: FindInPageView) { currentTab?.findInPage = nil - toolbar.accessibilityElementsHidden = false + viewCoordinator.toolbar.accessibilityElementsHidden = false } } @@ -1184,6 +1075,10 @@ extension MainViewController: BrowserChromeDelegate { static let duration = 0.1 } + var tabBarContainer: UIView { + viewCoordinator.tabBarContainer + } + private func hideKeyboard() { dismissOmniBar() _ = findInPageView.resignFirstResponder() @@ -1210,8 +1105,8 @@ extension MainViewController: BrowserChromeDelegate { self.view.layoutIfNeeded() self.omniBar.alpha = percent - self.tabsBar.alpha = percent - self.toolbar.alpha = percent + self.viewCoordinator.tabBarContainer.alpha = percent + self.viewCoordinator.toolbar.alpha = percent } if animated { @@ -1226,8 +1121,8 @@ extension MainViewController: BrowserChromeDelegate { updateNavBarConstant(hidden ? 0 : 1.0) omniBar.alpha = hidden ? 0 : 1 - tabsBar.alpha = hidden ? 0 : 1 - statusBarBackground.alpha = hidden ? 0 : 1 + viewCoordinator.tabBarContainer.alpha = hidden ? 0 : 1 + viewCoordinator.statusBackground.alpha = hidden ? 0 : 1 } var canHideBars: Bool { @@ -1235,11 +1130,11 @@ extension MainViewController: BrowserChromeDelegate { } var isToolbarHidden: Bool { - return toolbar.alpha < 1 + return viewCoordinator.toolbar.alpha < 1 } var toolbarHeight: CGFloat { - return toolbar.frame.size.height + return viewCoordinator.toolbar.frame.size.height } var barsMaxHeight: CGFloat { @@ -1250,20 +1145,20 @@ extension MainViewController: BrowserChromeDelegate { private func updateToolbarConstant(_ ratio: CGFloat) { var bottomHeight = toolbarHeight bottomHeight += view.safeAreaInsets.bottom - let multiplier = toolbar.isHidden ? 1.0 : 1.0 - ratio - toolbarBottom.constant = bottomHeight * multiplier + let multiplier = viewCoordinator.toolbar.isHidden ? 1.0 : 1.0 - ratio + viewCoordinator.constraints.toolbarBottom.constant = bottomHeight * multiplier findInPageHeightLayoutConstraint.constant = findInPageView.container.frame.height + view.safeAreaInsets.bottom } // 1.0 - full size, 0.0 - hidden private func updateNavBarConstant(_ ratio: CGFloat) { - let browserTabsOffset = (tabsBar.isHidden ? 0 : tabsBar.frame.size.height) - let navBarTopOffset = customNavigationBar.frame.size.height + browserTabsOffset - if !tabsBar.isHidden { + let browserTabsOffset = (viewCoordinator.tabBarContainer.isHidden ? 0 : viewCoordinator.tabBarContainer.frame.size.height) + let navBarTopOffset = viewCoordinator.navigationBarContainer.frame.size.height + browserTabsOffset + if !viewCoordinator.tabBarContainer.isHidden { let topBarsConstant = -browserTabsOffset * (1.0 - ratio) - tabsBarTop.constant = topBarsConstant + viewCoordinator.constraints.tabBarContainerTop.constant = topBarsConstant } - navBarTop.constant = browserTabsOffset + -navBarTopOffset * (1.0 - ratio) + viewCoordinator.constraints.navigationBarContainerTop.constant = browserTabsOffset + -navBarTopOffset * (1.0 - ratio) } } @@ -1348,17 +1243,17 @@ extension MainViewController: OmniBarDelegate { ViewHighlighter.hideAll() } hideSuggestionTray() - performSegue(withIdentifier: "Bookmarks", sender: self) + segueToBookmarks() } func onBookmarkEdit() { ViewHighlighter.hideAll() hideSuggestionTray() - performSegue(withIdentifier: "BookmarksEditCurrent", sender: self) + segueToEditCurrentBookmark() } func onEnterPressed() { - guard !suggestionTrayContainer.isHidden else { return } + guard !viewCoordinator.suggestionTrayContainer.isHidden else { return } suggestionTrayController?.willDismiss(with: omniBar.textField.text ?? "") } @@ -1371,7 +1266,7 @@ extension MainViewController: OmniBarDelegate { if !DaxDialogs.shared.shouldShowFireButtonPulse { ViewHighlighter.hideAll() } - launchSettings() + segueToSettings() } func onCancelPressed() { @@ -1518,7 +1413,7 @@ extension MainViewController: HomeControllerDelegate { } func home(_ home: HomeViewController, didRequestEdit favorite: BookmarkEntity) { - performSegue(withIdentifier: "BookmarksEdit", sender: favorite) + segueToEditBookmark(favorite) } func home(_ home: HomeViewController, didRequestContentOverflow shouldOverflow: Bool) -> CGFloat { @@ -1532,20 +1427,20 @@ extension MainViewController: HomeControllerDelegate { } func showSettings(_ home: HomeViewController) { - launchSettings() + segueToSettings() } func home(_ home: HomeViewController, didRequestHideLogo hidden: Bool) { - logoContainer.isHidden = hidden + viewCoordinator.logoContainer.isHidden = hidden } func homeDidRequestLogoContainer(_ home: HomeViewController) -> UIView { - return logoContainer + return viewCoordinator.logoContainer } func home(_ home: HomeViewController, searchTransitionUpdated percent: CGFloat) { - statusBarBackground?.alpha = percent - customNavigationBar?.alpha = percent + viewCoordinator.statusBackground.alpha = percent + viewCoordinator.navigationBarContainer.alpha = percent } } @@ -1637,7 +1532,7 @@ extension MainViewController: TabDelegate { } func tabDidRequestReportBrokenSite(tab: TabViewController) { - launchReportBrokenSite() + segueToReportBrokenSite() } func tabDidRequestBookmarks(tab: TabViewController) { @@ -1651,7 +1546,7 @@ extension MainViewController: TabDelegate { } func tabDidRequestDownloads(tab: TabViewController) { - launchDownloads() + segueToDownloads() } func tabDidRequestAutofillLogins(tab: TabViewController) { @@ -1659,12 +1554,12 @@ extension MainViewController: TabDelegate { } func tabDidRequestSettings(tab: TabViewController) { - launchSettings() + segueToSettings() } func tab(_ tab: TabViewController, - didRequestSettingsToLogins account: SecureVaultModels.WebsiteAccount?) { - performSegue(withIdentifier: "SettingsToLogins", sender: account) + didRequestSettingsToLogins account: SecureVaultModels.WebsiteAccount) { + segueToSettingsLoginsWithAccount(account) } func tabContentProcessDidTerminate(tab: TabViewController) { @@ -1828,7 +1723,7 @@ extension MainViewController: TabSwitcherButtonDelegate { } ViewHighlighter.hideAll() - self.performSegue(withIdentifier: "ShowTabs", sender: self) + self.segueToTabSwitcher() }) } } @@ -1942,10 +1837,10 @@ extension MainViewController: AutoClearWorker { guard let window = view.window else { return } let fireButtonView: UIView? - if toolbar.isHidden { + if viewCoordinator.toolbar.isHidden { fireButtonView = tabsBarController?.fireButton } else { - fireButtonView = fireButton.value(forKey: "view") as? UIView + fireButtonView = viewCoordinator.toolbarFireButton.value(forKey: "view") as? UIView } guard let view = fireButtonView else { return } @@ -1963,25 +1858,25 @@ extension MainViewController: Themable { setNeedsStatusBarAppearanceUpdate() if AppWidthObserver.shared.isLargeWidth { - statusBarBackground.backgroundColor = theme.tabsBarBackgroundColor + viewCoordinator.statusBackground.backgroundColor = theme.tabsBarBackgroundColor } else { - statusBarBackground.backgroundColor = theme.omniBarBackgroundColor + viewCoordinator.statusBackground.backgroundColor = theme.omniBarBackgroundColor } view.backgroundColor = theme.mainViewBackgroundColor - customNavigationBar?.backgroundColor = theme.barBackgroundColor - customNavigationBar?.tintColor = theme.barTintColor + viewCoordinator.navigationBarContainer.backgroundColor = theme.barBackgroundColor + viewCoordinator.navigationBarContainer.tintColor = theme.barTintColor - omniBar?.decorate(with: theme) - progressView?.decorate(with: theme) + omniBar.decorate(with: theme) + viewCoordinator.progress.decorate(with: theme) - toolbar?.barTintColor = theme.barBackgroundColor - toolbar?.tintColor = theme.barTintColor + viewCoordinator.toolbar.barTintColor = theme.barBackgroundColor + viewCoordinator.toolbar.tintColor = theme.barTintColor tabSwitcherButton.decorate(with: theme) gestureBookmarksButton.decorate(with: theme) - tabsButton.tintColor = theme.barTintColor + viewCoordinator.toolbarTabSwitcherButton.tintColor = theme.barTintColor presentedMenuButton.decorate(with: theme) @@ -1989,7 +1884,7 @@ extension MainViewController: Themable { findInPageView.decorate(with: theme) - logoText.tintColor = theme.ddgTextTintColor + viewCoordinator.logoText.tintColor = theme.ddgTextTintColor } } @@ -2062,11 +1957,11 @@ extension MainViewController { let backMenu = historyMenu(with: currentTab.webView.backForwardList.backList.reversed()) omniBar.backButton.menu = backMenu - backButton.menu = backMenu + viewCoordinator.toolbarBackButton.menu = backMenu let forwardMenu = historyMenu(with: currentTab.webView.backForwardList.forwardList) omniBar.forwardButton.menu = forwardMenu - forwardButton.menu = forwardMenu + viewCoordinator.toolbarForwardButton.menu = forwardMenu } private func historyMenu(with backForwardList: [WKBackForwardListItem]) -> UIMenu { diff --git a/DuckDuckGo/NetworkProtectionDebugUtilities.swift b/DuckDuckGo/NetworkProtectionDebugUtilities.swift index 83062a1b3e..a3d47161b9 100644 --- a/DuckDuckGo/NetworkProtectionDebugUtilities.swift +++ b/DuckDuckGo/NetworkProtectionDebugUtilities.swift @@ -37,6 +37,46 @@ final class NetworkProtectionDebugUtilities { try? activeSession.sendProviderMessage(.expireRegistrationKey) } + + // MARK: - Notifications + + func sendTestNotificationRequest() async throws { + guard let activeSession = try? await ConnectionSessionUtilities.activeSession() else { + return + } + + try? activeSession.sendProviderMessage(.triggerTestNotification) + } + + // MARK: - Failure Simulation + + func triggerSimulation(_ option: NetworkProtectionSimulationOption) async { + guard let activeSession = try? await ConnectionSessionUtilities.activeSession() else { + return + } + + guard let message = option.extensionMessage else { + return + } + try? activeSession.sendProviderMessage(message) + } +} + +private extension NetworkProtectionSimulationOption { + var extensionMessage: ExtensionMessage? { + switch self { + case .crashFatalError: + return .simulateTunnelFatalError + case .crashMemory: + return .simulateTunnelMemoryOveruse + case .tunnelFailure: + return .simulateTunnelFailure + case .controllerFailure: + return nil + case .connectionInterruption: + return .simulateConnectionInterruption + } + } } #endif diff --git a/DuckDuckGo/NetworkProtectionDebugViewController.swift b/DuckDuckGo/NetworkProtectionDebugViewController.swift index f3210ba03f..ffa9d42df0 100644 --- a/DuckDuckGo/NetworkProtectionDebugViewController.swift +++ b/DuckDuckGo/NetworkProtectionDebugViewController.swift @@ -34,7 +34,8 @@ final class NetworkProtectionDebugViewController: UITableViewController { Sections.keychain: "Keychain", Sections.debugFeature: "Debug Features", Sections.simulateFailure: "Simulate Failure", - Sections.registrationKey: "Registration Key" + Sections.registrationKey: "Registration Key", + Sections.notifications: "Notifications" ] @@ -44,6 +45,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { case debugFeature case simulateFailure case registrationKey + case notifications } @@ -63,7 +65,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { case controllerFailure case crashFatalError case crashMemory - + case connectionInterruption } enum RegistrationKeyRows: Int, CaseIterable { @@ -72,6 +74,12 @@ final class NetworkProtectionDebugViewController: UITableViewController { } + enum NotificationsRows: Int, CaseIterable { + + case triggerTestNotification + + } + private let debugFeatures: NetworkProtectionDebugFeatures private let tokenStore: NetworkProtectionTokenStore @@ -122,6 +130,9 @@ final class NetworkProtectionDebugViewController: UITableViewController { case .registrationKey: configure(cell, forRegistrationKeyRow: indexPath.row) + case .notifications: + configure(cell, forNotificationRow: indexPath.row) + case.none: break } @@ -135,6 +146,7 @@ final class NetworkProtectionDebugViewController: UITableViewController { case .debugFeature: return DebugFeatureRows.allCases.count case .simulateFailure: return SimulateFailureRows.allCases.count case .registrationKey: return RegistrationKeyRows.allCases.count + case .notifications: return NotificationsRows.allCases.count case .none: return 0 } @@ -153,6 +165,8 @@ final class NetworkProtectionDebugViewController: UITableViewController { didSelectSimulateFailure(at: indexPath) case .registrationKey: didSelectRegistationKeyAction(at: indexPath) + case .notifications: + didSelectTestNotificationAction(at: indexPath) case .none: break } @@ -172,6 +186,8 @@ final class NetworkProtectionDebugViewController: UITableViewController { cell.textLabel?.text = "Tunnel: Crash (Fatal Error)" case .crashMemory: cell.textLabel?.text = "Tunnel: Crash (CPU/Memory)" + case .connectionInterruption: + cell.textLabel?.text = "Connection Interruption" case .none: break } @@ -179,11 +195,24 @@ final class NetworkProtectionDebugViewController: UITableViewController { private func didSelectSimulateFailure(at indexPath: IndexPath) { switch SimulateFailureRows(rawValue: indexPath.row) { - case .controllerFailure: simulateFailure(option: .controllerFailure) - case .tunnelFailure: simulateFailure(option: .tunnelFailure) - case .crashFatalError: simulateFailure(option: .crashFatalError) - case .crashMemory: simulateFailure(option: .crashMemory) - case .none: return + case .controllerFailure: + NetworkProtectionTunnelController.shouldSimulateFailure = true + case .tunnelFailure: + triggerSimulation(.tunnelFailure) + case .crashFatalError: + triggerSimulation(.crashFatalError) + case .crashMemory: + triggerSimulation(.crashMemory) + case .connectionInterruption: + triggerSimulation(.connectionInterruption) + case .none: + break + } + } + + private func triggerSimulation(_ option: NetworkProtectionSimulationOption) { + Task { + await NetworkProtectionDebugUtilities().triggerSimulation(option) } } @@ -236,22 +265,32 @@ final class NetworkProtectionDebugViewController: UITableViewController { } } - // MARK: Selection Actions + // MARK: Notifications - private func clearAuthToken() { - try? tokenStore.deleteToken() + private func configure(_ cell: UITableViewCell, forNotificationRow row: Int) { + switch NotificationsRows(rawValue: row) { + case .triggerTestNotification: + cell.textLabel?.text = "Test Notification" + case .none: + break + } } - private func simulateControllerFailure() { - NetworkProtectionTunnelController.enabledSimulationOption = .controllerFailure + private func didSelectTestNotificationAction(at indexPath: IndexPath) { + switch NotificationsRows(rawValue: indexPath.row) { + case .triggerTestNotification: + Task { + try await NetworkProtectionDebugUtilities().sendTestNotificationRequest() + } + case .none: + break + } } - private func simulaterTunnelFailure() { - NetworkProtectionTunnelController.enabledSimulationOption = .crashFatalError - } + // MARK: Selection Actions - private func simulateFailure(option: NetworkProtectionSimulationOption) { - NetworkProtectionTunnelController.enabledSimulationOption = .crashMemory + private func clearAuthToken() { + try? tokenStore.deleteToken() } } diff --git a/DuckDuckGo/NetworkProtectionRootViewController.swift b/DuckDuckGo/NetworkProtectionRootViewController.swift index ff37f96256..485f586f5d 100644 --- a/DuckDuckGo/NetworkProtectionRootViewController.swift +++ b/DuckDuckGo/NetworkProtectionRootViewController.swift @@ -23,7 +23,7 @@ import SwiftUI final class NetworkProtectionRootViewController: UIHostingController { - init(inviteCompletion: @escaping () -> Void) { + init(inviteCompletion: @escaping () -> Void = { }) { let rootView = NetworkProtectionRootView(inviteCompletion: inviteCompletion) super.init(rootView: rootView) } diff --git a/DuckDuckGo/NetworkProtectionTunnelController.swift b/DuckDuckGo/NetworkProtectionTunnelController.swift index d53263188a..6a5bef318b 100644 --- a/DuckDuckGo/NetworkProtectionTunnelController.swift +++ b/DuckDuckGo/NetworkProtectionTunnelController.swift @@ -26,8 +26,7 @@ import NetworkExtension import NetworkProtection final class NetworkProtectionTunnelController: TunnelController { - static var simulationOptions = NetworkProtectionSimulationOptions() - static var enabledSimulationOption: NetworkProtectionSimulationOption? + static var shouldSimulateFailure: Bool = false private let debugFeatures = NetworkProtectionDebugFeatures() private let tokenStore = NetworkProtectionKeychainTokenStore() @@ -98,19 +97,14 @@ final class NetworkProtectionTunnelController: TunnelController { private func start(_ tunnelManager: NETunnelProviderManager) throws { var options = [String: NSObject]() - if Self.simulationOptions.isEnabled(.controllerFailure) { - Self.simulationOptions.setEnabled(false, option: .controllerFailure) + if Self.shouldSimulateFailure { + Self.shouldSimulateFailure = false throw StartError.simulateControllerFailureError } options["activationAttemptId"] = UUID().uuidString as NSString options["authToken"] = try tokenStore.fetchToken() as NSString? - if let optionKey = Self.enabledSimulationOption?.optionKey { - options[optionKey] = NSNumber(value: true) - Self.enabledSimulationOption = nil - } - do { try tunnelManager.connection.startVPNTunnel(options: options) } catch { @@ -227,19 +221,4 @@ final class NetworkProtectionTunnelController: TunnelController { } } -private extension NetworkProtectionSimulationOption { - var optionKey: String? { - switch self { - case .crashFatalError: - return NetworkProtectionOptionKey.tunnelFatalErrorCrashSimulation - case .crashMemory: - return NetworkProtectionOptionKey.tunnelMemoryCrashSimulation - case .tunnelFailure: - return NetworkProtectionOptionKey.tunnelFailureSimulation - default: - return nil - } - } -} - #endif diff --git a/DuckDuckGo/OnboardingDefaultBroswerViewController.swift b/DuckDuckGo/OnboardingDefaultBroswerViewController.swift index addf162132..beb730753b 100644 --- a/DuckDuckGo/OnboardingDefaultBroswerViewController.swift +++ b/DuckDuckGo/OnboardingDefaultBroswerViewController.swift @@ -41,7 +41,4 @@ class OnboardingDefaultBroswerViewController: OnboardingContentViewController { super.onContinuePressed(navigationHandler: navigationHandler) } - override func onSkipPressed(navigationHandler: @escaping () -> Void) { - super.onSkipPressed(navigationHandler: navigationHandler) - } } diff --git a/DuckDuckGo/PrivacyDashboardViewController.swift b/DuckDuckGo/PrivacyDashboardViewController.swift index ddc3180021..52f548313b 100644 --- a/DuckDuckGo/PrivacyDashboardViewController.swift +++ b/DuckDuckGo/PrivacyDashboardViewController.swift @@ -150,9 +150,9 @@ extension PrivacyDashboardViewController: PrivacyDashboardControllerDelegate { dismiss(animated: true) { switch target { case .cookiePopupManagement: - mainViewController.launchCookiePopupManagementSettings() + mainViewController.segueToSettingsCookiePopupManagement() default: - mainViewController.launchSettings() + mainViewController.segueToSettings() } } } diff --git a/DuckDuckGo/SaveLoginViewController.swift b/DuckDuckGo/SaveLoginViewController.swift index 7f1bcf98fe..fbd144e98b 100644 --- a/DuckDuckGo/SaveLoginViewController.swift +++ b/DuckDuckGo/SaveLoginViewController.swift @@ -61,10 +61,6 @@ class SaveLoginViewController: UIViewController { viewModel?.viewControllerDidAppear() } - override func viewDidLayoutSubviews() { - super.viewDidLayoutSubviews() - } - override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) diff --git a/DuckDuckGo/Settings.bundle/Root.plist b/DuckDuckGo/Settings.bundle/Root.plist index 8c01846663..2e4f5bb46b 100644 --- a/DuckDuckGo/Settings.bundle/Root.plist +++ b/DuckDuckGo/Settings.bundle/Root.plist @@ -6,7 +6,7 @@ DefaultValue - 7.91.1 + 7.92.0 Key version Title diff --git a/DuckDuckGo/SettingsViewController.swift b/DuckDuckGo/SettingsViewController.swift index e184f748e7..45b66e7870 100644 --- a/DuckDuckGo/SettingsViewController.swift +++ b/DuckDuckGo/SettingsViewController.swift @@ -71,8 +71,6 @@ class SettingsViewController: UITableViewController { @IBOutlet weak var debugCell: UITableViewCell! @IBOutlet weak var voiceSearchCell: UITableViewCell! @IBOutlet weak var voiceSearchToggle: UISwitch! - - fileprivate var onDidAppearAction: () -> Void = {} @IBOutlet var labels: [UILabel]! @IBOutlet var accessoryLabels: [UILabel]! @@ -178,13 +176,6 @@ class SettingsViewController: UITableViewController { tableView.layoutIfNeeded() } - override func viewDidAppear(_ animated: Bool) { - super.viewDidAppear(animated) - - onDidAppearAction() - onDidAppearAction = {} - } - init?(coder: NSCoder, bookmarksDatabase: CoreDataDatabase, syncService: DDGSyncing, @@ -202,22 +193,16 @@ class SettingsViewController: UITableViewController { fatalError("Not implemented") } - func openLoginsWhenPresented() { - onDidAppearAction = { [weak self] in - self?.showAutofill() - } + func openLogins() { + showAutofill() } - func openLoginsWhenPresented(accountDetails: SecureVaultModels.WebsiteAccount) { - onDidAppearAction = { [weak self] in - self?.showAutofillAccountDetails(accountDetails) - } + func openLogins(accountDetails: SecureVaultModels.WebsiteAccount) { + showAutofillAccountDetails(accountDetails) } - func openCookiePopupManagementWhenPresented() { - onDidAppearAction = { [weak self] in - self?.showCookiePopupManagement(animated: true) - } + func openCookiePopupManagement() { + showCookiePopupManagement(animated: true) } @IBSegueAction func onCreateRootDebugScreen(_ coder: NSCoder, sender: Any?, segueIdentifier: String?) -> RootDebugViewController { @@ -420,7 +405,7 @@ class SettingsViewController: UITableViewController { // This will be tidied up as part of https://app.asana.com/0/0/1205084446087078/f let rootViewController = NetworkProtectionRootViewController { [weak self] in self?.navigationController?.popViewController(animated: true) - let newRootViewController = NetworkProtectionRootViewController { } + let newRootViewController = NetworkProtectionRootViewController() self?.pushNetP(newRootViewController) } pushNetP(rootViewController) @@ -544,10 +529,6 @@ class SettingsViewController: UITableViewController { } } - override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { - return super.tableView(tableView, titleForFooterInSection: section) - } - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let rows = super.tableView(tableView, numberOfRowsInSection: section) if section == appearanceSectionIndex && textSizeCell.isHidden { diff --git a/DuckDuckGo/SuggestionTray.storyboard b/DuckDuckGo/SuggestionTray.storyboard new file mode 100644 index 0000000000..64c0f040aa --- /dev/null +++ b/DuckDuckGo/SuggestionTray.storyboard @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DuckDuckGo/TabDelegate.swift b/DuckDuckGo/TabDelegate.swift index b754c52d1d..6f7438d918 100644 --- a/DuckDuckGo/TabDelegate.swift +++ b/DuckDuckGo/TabDelegate.swift @@ -62,7 +62,7 @@ protocol TabDelegate: AnyObject { func tabDidRequestSettings(tab: TabViewController) func tab(_ tab: TabViewController, - didRequestSettingsToLogins account: SecureVaultModels.WebsiteAccount?) + didRequestSettingsToLogins account: SecureVaultModels.WebsiteAccount) func tabDidRequestFindInPage(tab: TabViewController) func closeFindInPage(tab: TabViewController) diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index 5a1a383922..b3535ccca6 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -1297,7 +1297,7 @@ extension TabViewController: WKNavigationDelegate { // This check needs to happen before GPC checks. Otherwise the navigation type may be rewritten to `.other` // which would skip link rewrites. - if navigationAction.navigationType != .backForward { + if navigationAction.navigationType != .backForward && navigationAction.isTargetingMainFrame() { let didRewriteLink = linkProtection.requestTrackingLinkRewrite(initiatingURL: webView.url, navigationAction: navigationAction, onStartExtracting: { showProgressIndicator() }, diff --git a/DuckDuckGo/TabsBarViewController.swift b/DuckDuckGo/TabsBarViewController.swift index a0bf6a128c..064a6a2d89 100644 --- a/DuckDuckGo/TabsBarViewController.swift +++ b/DuckDuckGo/TabsBarViewController.swift @@ -312,8 +312,9 @@ extension MainViewController: TabsBarDelegate { } func tabsBarDidRequestFireEducationDialog(_ controller: TabsBarViewController) { - let spec = DaxDialogs.shared.fireButtonEducationMessage() - performSegue(withIdentifier: "ActionSheetDaxDialog", sender: spec) + if let spec = DaxDialogs.shared.fireButtonEducationMessage() { + segueToActionSheetDaxDialogWithSpec(spec) + } } func tabsBarDidRequestTabSwitcher(_ controller: TabsBarViewController) { diff --git a/DuckDuckGo/UIView+Constraints.swift b/DuckDuckGo/UIView+Constraints.swift index 65c2f0cbf3..4daabe252e 100644 --- a/DuckDuckGo/UIView+Constraints.swift +++ b/DuckDuckGo/UIView+Constraints.swift @@ -21,9 +21,9 @@ import UIKit extension UIView { - func constrainView(_ other: UIView, + func constrainView(_ other: Any, by attribute: NSLayoutConstraint.Attribute, - to otherAttribute: NSLayoutConstraint.Attribute, + to otherAttribute: NSLayoutConstraint.Attribute? = nil, relatedBy relation: NSLayoutConstraint.Relation = .equal, multiplier: Double = 1.0, constant: Double = 0.0) -> NSLayoutConstraint { @@ -32,7 +32,7 @@ extension UIView { attribute: attribute, relatedBy: relation, toItem: other, - attribute: otherAttribute, + attribute: otherAttribute ?? attribute, multiplier: multiplier, constant: constant) diff --git a/DuckDuckGo/bg.lproj/Main.strings b/DuckDuckGo/bg.lproj/Main.strings deleted file mode 100644 index d227fca0ed..0000000000 --- a/DuckDuckGo/bg.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Сърфиране напред"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Превключване на раздели"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Сърфиране назад"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Отметки"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Затваряне на всички раздели и изчистване на данните"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 от 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Готово"; - diff --git a/DuckDuckGo/cs.lproj/Main.strings b/DuckDuckGo/cs.lproj/Main.strings deleted file mode 100644 index 4ed4a36e30..0000000000 --- a/DuckDuckGo/cs.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Procházet dopředu"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Přepínač karet"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Procházet zpátky"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Záložky"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Zavřít všechny karty a vymazat data"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 z 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Hotovo"; - diff --git a/DuckDuckGo/da.lproj/Main.strings b/DuckDuckGo/da.lproj/Main.strings deleted file mode 100644 index 83131719e5..0000000000 --- a/DuckDuckGo/da.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Gennemse fremad"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Faneskifter"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Gennemse tilbage"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Bogmærker"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Luk alle faner og ryd data"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 af 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Færdig"; - diff --git a/DuckDuckGo/de.lproj/Main.strings b/DuckDuckGo/de.lproj/Main.strings deleted file mode 100644 index b2f9f23424..0000000000 --- a/DuckDuckGo/de.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Vorwärts"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Tabwechsel-Bildschirm"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Zurück"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Lesezeichen"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Alle Tabs schließen und Daten löschen"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 von 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Fertig"; - diff --git a/DuckDuckGo/el.lproj/Main.strings b/DuckDuckGo/el.lproj/Main.strings deleted file mode 100644 index f4a511320c..0000000000 --- a/DuckDuckGo/el.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Περιήγηση προς τα μπροστά"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Εναλλαγή καρτελών"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Περιήγηση προς τα πίσω"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Σελιδοδείκτες"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Κλείσιμο όλων των καρτελών και εκκαθάριση δεδομένων"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 από 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Ολοκληρώθηκε"; - diff --git a/DuckDuckGo/es.lproj/Main.strings b/DuckDuckGo/es.lproj/Main.strings deleted file mode 100644 index 0bc0cac4cc..0000000000 --- a/DuckDuckGo/es.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Avanzar"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Cambiar pestañas"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Retroceder"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Marcadores"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Cerrar todas las pestañas y borrar los datos"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 de 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Hecho"; - diff --git a/DuckDuckGo/et.lproj/Main.strings b/DuckDuckGo/et.lproj/Main.strings deleted file mode 100644 index f6ef3e05b0..0000000000 --- a/DuckDuckGo/et.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Sirvi edasi"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Vahekaardi vaheldaja"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Sirvi tagasi"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Järjehoidjad"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Sulge kõik vahekaardid ja kustuta andmed"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 / 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Valmis"; - diff --git a/DuckDuckGo/fi.lproj/Main.strings b/DuckDuckGo/fi.lproj/Main.strings deleted file mode 100644 index f0b1e8064c..0000000000 --- a/DuckDuckGo/fi.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Selaa eteenpäin"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Välilehtien vaihtotyökalu"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Selaa taaksepäin"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Kirjanmerkit"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Sulje kaikki välilehdet ja tyhjennä tiedot"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1/12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Valmis"; - diff --git a/DuckDuckGo/fr.lproj/Main.strings b/DuckDuckGo/fr.lproj/Main.strings deleted file mode 100644 index 8ff3d6c928..0000000000 --- a/DuckDuckGo/fr.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Afficher la page suivante"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Outil de changement d'onglet"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Afficher la page précédente"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Signets"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Fermer tous les onglets et effacer les données"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 sur 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Terminé"; - diff --git a/DuckDuckGo/hr.lproj/Main.strings b/DuckDuckGo/hr.lproj/Main.strings deleted file mode 100644 index b272121196..0000000000 --- a/DuckDuckGo/hr.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Pretraži unaprijed"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Mjenjač kartica"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Pretraži unazad"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Knjižne oznake"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Zatvori sve kartice i očisti podatke"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 od 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Gotovo"; - diff --git a/DuckDuckGo/hu.lproj/Main.strings b/DuckDuckGo/hu.lproj/Main.strings deleted file mode 100644 index 20a12da220..0000000000 --- a/DuckDuckGo/hu.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Böngészés előre"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Lapváltó"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Böngészés vissza"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Könyvjelzők"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Összes lap bezárása és adattörlés"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1/12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Kész"; - diff --git a/DuckDuckGo/it.lproj/Main.strings b/DuckDuckGo/it.lproj/Main.strings deleted file mode 100644 index d98e3e79a0..0000000000 --- a/DuckDuckGo/it.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Vai avanti"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Selettore schede"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Torna indietro"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Segnalibri"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Chiudi tutte le schede e cancella i dati"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 di 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Fatto"; - diff --git a/DuckDuckGo/lt.lproj/Main.strings b/DuckDuckGo/lt.lproj/Main.strings deleted file mode 100644 index 802a934cc0..0000000000 --- a/DuckDuckGo/lt.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Naršyti pirmyn"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Skirtukų perjungiklis"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Naršyti atgal"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Žymės"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Uždaryti visus skirtukus ir išvalyti duomenis"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 iš 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Atlikta"; - diff --git a/DuckDuckGo/lv.lproj/Main.strings b/DuckDuckGo/lv.lproj/Main.strings deleted file mode 100644 index 90b6fcf657..0000000000 --- a/DuckDuckGo/lv.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Pārlūkot uz priekšu"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Ciļņu pārslēdzējs"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Pārlūkot atpakaļ"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Grāmatzīmes"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Aizvērt visas cilnes un notīrīt datus"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 no 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Gatavs"; - diff --git a/DuckDuckGo/nb.lproj/Main.strings b/DuckDuckGo/nb.lproj/Main.strings deleted file mode 100644 index 50c970d34d..0000000000 --- a/DuckDuckGo/nb.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Gå frem"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Fanebytter"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Gå tilbake"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Bokmerker"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Lukk alle faner og slett data"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 av 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Ferdig"; - diff --git a/DuckDuckGo/nl.lproj/Main.strings b/DuckDuckGo/nl.lproj/Main.strings deleted file mode 100644 index 7136ee440a..0000000000 --- a/DuckDuckGo/nl.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Vooruit browsen"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Wisselen tussen tabbladen"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Terug browsen"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Bladwijzers"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Alle tabbladen sluiten en gegevens wissen"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 van 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Klaar"; - diff --git a/DuckDuckGo/pl.lproj/Main.strings b/DuckDuckGo/pl.lproj/Main.strings deleted file mode 100644 index f3a3e28e05..0000000000 --- a/DuckDuckGo/pl.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Przeglądaj dalej"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Przełącznik kart"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Przeglądaj wstecz"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Zakładki"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Zamknij wszystkie karty i wyczyść dane"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 z 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Gotowe"; - diff --git a/DuckDuckGo/pt.lproj/Main.strings b/DuckDuckGo/pt.lproj/Main.strings deleted file mode 100644 index 3bb92a1fbb..0000000000 --- a/DuckDuckGo/pt.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Navegar para a frente"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Alternar de separador"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Navegar para trás"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Marcadores"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Fechar todos os separadores e limpar os dados"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 de 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Feito"; - diff --git a/DuckDuckGo/ro.lproj/Main.strings b/DuckDuckGo/ro.lproj/Main.strings deleted file mode 100644 index cdc12a056d..0000000000 --- a/DuckDuckGo/ro.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Navigare înainte"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Comutator între file"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Navigare înapoi"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Semne de carte"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Închide toate filele și șterge datele"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 din 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Terminat"; - diff --git a/DuckDuckGo/ru.lproj/Main.strings b/DuckDuckGo/ru.lproj/Main.strings deleted file mode 100644 index ad87d393bf..0000000000 --- a/DuckDuckGo/ru.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Вперед"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Переключатель вкладок"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Назад"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Закладки"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Закрыть все вкладки и удалить данные"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 из 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Готово"; - diff --git a/DuckDuckGo/sk.lproj/Main.strings b/DuckDuckGo/sk.lproj/Main.strings deleted file mode 100644 index 3e86b1d44b..0000000000 --- a/DuckDuckGo/sk.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Prehliadajte dopredu"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Prepínač kariet"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Prehliadajte dozadu"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Záložky"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Zatvoriť všetky karty a vymazať údaje"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 z 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Hotovo"; - diff --git a/DuckDuckGo/sl.lproj/Main.strings b/DuckDuckGo/sl.lproj/Main.strings deleted file mode 100644 index e8129b28f8..0000000000 --- a/DuckDuckGo/sl.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Brskaj naprej"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Preklopi med zavihki"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Brskaj nazaj"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Zaznamki"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Zapri vse zavihke in izbriši podatke"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 od 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Končano"; - diff --git a/DuckDuckGo/sv.lproj/Main.strings b/DuckDuckGo/sv.lproj/Main.strings deleted file mode 100644 index 85c434c49f..0000000000 --- a/DuckDuckGo/sv.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "Bläddra framåt"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Flikväxlare"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Bläddra tillbaka"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Bokmärken"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Stäng alla flikar och rensa data"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1 av 12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Klart"; - diff --git a/DuckDuckGo/tr.lproj/Main.strings b/DuckDuckGo/tr.lproj/Main.strings deleted file mode 100644 index 9f6e3a39ae..0000000000 --- a/DuckDuckGo/tr.lproj/Main.strings +++ /dev/null @@ -1,21 +0,0 @@ -/* Class = "UIBarButtonItem"; title = "Browse Forward"; ObjectID = "cUp-YP-aMf"; */ -"cUp-YP-aMf.title" = "İleri Git"; - -/* Class = "UIBarButtonItem"; title = "Tab Switcher"; ObjectID = "K7o-WL-SC5"; */ -"K7o-WL-SC5.title" = "Sekme Değiştirici"; - -/* Class = "UIBarButtonItem"; title = "Browse Back"; ObjectID = "Kc6-IR-lKx"; */ -"Kc6-IR-lKx.title" = "Geri Dön"; - -/* Class = "UIBarButtonItem"; title = "Bookmarks"; ObjectID = "M7u-mw-fly"; */ -"M7u-mw-fly.title" = "Yer İmleri"; - -/* Class = "UIBarButtonItem"; title = "Close all tabs and clear data"; ObjectID = "ntb-c7-mjV"; */ -"ntb-c7-mjV.title" = "Tüm sekmeleri kapat ve verileri temizle"; - -/* Class = "UILabel"; text = "1 of 12"; ObjectID = "rSE-zZ-iud"; */ -"rSE-zZ-iud.text" = "1/12"; - -/* Class = "UIButton"; normalTitle = "Done"; ObjectID = "X8N-Ee-U1n"; */ -"X8N-Ee-U1n.normalTitle" = "Bitti"; - diff --git a/DuckDuckGoTests/BarsAnimatorTests.swift b/DuckDuckGoTests/BarsAnimatorTests.swift index 198ba820a9..40efd123f9 100644 --- a/DuckDuckGoTests/BarsAnimatorTests.swift +++ b/DuckDuckGoTests/BarsAnimatorTests.swift @@ -181,5 +181,5 @@ private class BrowserChromeDelegateMock: BrowserChromeDelegate { var omniBar: OmniBar! = OmniBar(frame: CGRect(x: 0, y: 0, width: 300, height: 30)) - var tabsBar: UIView! = UIView() + var tabBarContainer: UIView = UIView() } diff --git a/DuckDuckGoTests/PrivacyIconLogicTests.swift b/DuckDuckGoTests/PrivacyIconLogicTests.swift index ad8c995326..a14220bdc8 100644 --- a/DuckDuckGoTests/PrivacyIconLogicTests.swift +++ b/DuckDuckGoTests/PrivacyIconLogicTests.swift @@ -33,14 +33,6 @@ class PrivacyIconLogicTests: XCTestCase { static let ddgMainURL = URL(string: "https://duckduckgo.com")! static let ddgSupportURL = URL(string: "https://duckduckgo.com/email/settings/support")! - override func setUp() { - super.setUp() - } - - override func tearDown() { - super.tearDown() - } - func testPrivacyIconIsShieldForPageURL() { let url = PrivacyIconLogicTests.insecurePageURL let icon = PrivacyIconLogic.privacyIcon(for: url) diff --git a/DuckDuckGoTests/TrackerAnimationLogicTests.swift b/DuckDuckGoTests/TrackerAnimationLogicTests.swift index b94ce01f99..07302fc11f 100644 --- a/DuckDuckGoTests/TrackerAnimationLogicTests.swift +++ b/DuckDuckGoTests/TrackerAnimationLogicTests.swift @@ -30,14 +30,6 @@ class TrackerAnimationLogicTests: XCTestCase { static let pageURL = URL(string: "https://example.com")! - override func setUp() { - super.setUp() - } - - override func tearDown() { - super.tearDown() - } - func testAnimationLogicToAnimateTrackersIfAnyBlocked() { let trackerInfo = makeBlockedTrackerInfo(pageURL: Self.pageURL) XCTAssertTrue(TrackerAnimationLogic.shouldAnimateTrackers(for: trackerInfo)) diff --git a/DuckDuckGoTests/UserAgentTests.swift b/DuckDuckGoTests/UserAgentTests.swift index 86da0621c2..2ad32d1438 100644 --- a/DuckDuckGoTests/UserAgentTests.swift +++ b/DuckDuckGoTests/UserAgentTests.swift @@ -22,34 +22,53 @@ import XCTest import BrowserServicesKit @testable import Core -class UserAgentTests: XCTestCase { +// swiftlint:disable file_length type_body_length +final class UserAgentTests: XCTestCase { private struct DefaultAgent { + + // swiftlint:disable line_length static let mobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148" static let tablet = "Mozilla/5.0 (iPad; CPU OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148" + static let oldWebkitVersionMobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.14 (KHTML, like Gecko) Mobile/15E148" + static let newWebkitVersionMobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.16 (KHTML, like Gecko) Mobile/15E148" + static let sameWebkitVersionMobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148" + } private struct ExpectedAgent { - // swiftlint:disable line_length - + // Based on DefaultAgent values static let mobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.4 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15" static let tablet = "Mozilla/5.0 (iPad; CPU OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.4 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15" static let desktop = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.4 DuckDuckGo/7 Safari/605.1.15" - + static let oldWebkitVersionMobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.14 (KHTML, like Gecko) Version/12.4 Mobile/15E148 DuckDuckGo/7 Safari/605.1.14" + static let newWebkitVersionMobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 DuckDuckGo/7 Safari/604.1" + static let sameWebkitVersionMobile = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 DuckDuckGo/7 Safari/604.1" + static let mobileNoApplication = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.4 Mobile/15E148 Safari/605.1.15" // Based on fallback constants in UserAgent static let mobileFallback = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.5 Mobile/15E148 DuckDuckGo/7 Safari/605.1.15" static let desktopFallback = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.5 DuckDuckGo/7 Safari/605.1.15" - + + static let mobileFixed = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 DuckDuckGo/7 Safari/604.1" + static let tabletFixed = "Mozilla/5.0 (iPad; CPU OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 DuckDuckGo/7 Safari/604.1" + static let desktopFixed = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 DuckDuckGo/7 Safari/605.1.15" + + static let mobileClosest = "Mozilla/5.0 (iPhone; CPU iPhone OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1" + static let tabletClosest = "Mozilla/5.0 (iPad; CPU OS 12_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Mobile/15E148 Safari/604.1" + static let desktopClosest = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15" // swiftlint:enable line_length + } private struct Constants { static let url = URL(string: "http://example.com/index.html") static let noAppUrl = URL(string: "http://cvs.com/index.html") static let noAppSubdomainUrl = URL(string: "http://subdomain.cvs.com/index.html") + static let ddgFixedUrl = URL(string: "http://test2.com/index.html") + static let ddgDefaultUrl = URL(string: "http://test3.com/index.html") } let testConfig = """ @@ -73,7 +92,7 @@ class UserAgentTests: XCTestCase { """.data(using: .utf8)! private var privacyConfig: PrivacyConfiguration! - + override func setUp() { super.setUp() @@ -164,4 +183,270 @@ class UserAgentTests: XCTestCase { XCTAssertEqual(ExpectedAgent.mobileNoApplication, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: manager.privacyConfig)) } + + /// Experimental config + + func makePrivacyConfig(from rawConfig: Data) -> PrivacyConfiguration { + let mockEmbeddedData = MockEmbeddedDataProvider(data: rawConfig, etag: "test") + let mockProtectionStore = MockDomainsProtectionStore() + + let manager = PrivacyConfigurationManager(fetchedETag: nil, + fetchedData: nil, + embeddedDataProvider: mockEmbeddedData, + localProtection: mockProtectionStore, + internalUserDecider: DefaultInternalUserDecider()) + return manager.privacyConfig + } + + let ddgConfig = """ + { + "features": { + "customUserAgent": { + "defaultPolicy": "ddg", + "state": "enabled", + "settings": { + "omitApplicationSites": [ + { + "domain": "cvs.com", + "reason": "Site reports browser not supported" + } + ], + "ddgFixedSites": [ + { + "domain": "test2.com" + } + ] + }, + "exceptions": [] + } + }, + "unprotectedTemporary": [] + } + """.data(using: .utf8)! + + func testWhenMobileUaAndDesktopFalseAndDomainSupportsFixedUAThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: ddgConfig) + XCTAssertEqual(ExpectedAgent.mobileFixed, testee.agent(forUrl: Constants.ddgFixedUrl, isDesktop: false, privacyConfig: config)) + } + + func testWhenMobileUaAndDesktopTrueAndDomainSupportsFixedUAThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: ddgConfig) + XCTAssertEqual(ExpectedAgent.desktopFixed, testee.agent(forUrl: Constants.ddgFixedUrl, isDesktop: true, privacyConfig: config)) + } + + func testWhenTabletUaAndDesktopFalseAndDomainSupportsFixedUAThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.tablet) + let config = makePrivacyConfig(from: ddgConfig) + XCTAssertEqual(ExpectedAgent.tabletFixed, testee.agent(forUrl: Constants.ddgFixedUrl, isDesktop: false, privacyConfig: config)) + } + + func testWhenTabletUaAndDesktopTrueAndDomainSupportsFixedUAThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.tablet) + let config = makePrivacyConfig(from: ddgConfig) + XCTAssertEqual(ExpectedAgent.desktopFixed, testee.agent(forUrl: Constants.ddgFixedUrl, isDesktop: true, privacyConfig: config)) + } + + let ddgFixedConfig = """ + { + "features": { + "customUserAgent": { + "state": "enabled", + "settings": { + "defaultPolicy": "ddgFixed", + "omitApplicationSites": [ + { + "domain": "cvs.com", + "reason": "Site reports browser not supported" + } + ], + "ddgDefaultSites": [ + { + "domain": "test3.com" + } + ] + }, + "exceptions": [] + } + }, + "unprotectedTemporary": [] + } + """.data(using: .utf8)! + + func testWhenMobileUaAndDesktopFalseAndDefaultPolicyFixedThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.mobileFixed, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenMobileUaAndDesktopTrueAndDefaultPolicyFixedThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.desktopFixed, testee.agent(forUrl: Constants.url, isDesktop: true, privacyConfig: config)) + } + + func testWhenTabletUaAndDesktopFalseAndDefaultPolicyFixedThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.tablet) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.tabletFixed, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenTabletUaAndDesktopTrueAndDefaultPolicyFixedThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.tablet) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.desktopFixed, testee.agent(forUrl: Constants.url, isDesktop: true, privacyConfig: config)) + } + + func testWhenDefaultPolicyFixedAndDomainIsOnDefaultListThenDefaultAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.mobile, testee.agent(forUrl: Constants.ddgDefaultUrl, isDesktop: false, privacyConfig: config)) + } + + let closestConfig = """ + { + "features": { + "customUserAgent": { + "state": "enabled", + "settings": { + "defaultPolicy": "closest", + "omitApplicationSites": [ + { + "domain": "cvs.com", + "reason": "Site reports browser not supported" + } + ], + "ddgFixedSites": [ + { + "domain": "test2.com" + } + ], + "ddgDefaultSites": [ + { + "domain": "test3.com" + } + ] + }, + "exceptions": [] + } + }, + "unprotectedTemporary": [] + } + """.data(using: .utf8)! + + func testWhenMobileUaAndDesktopFalseAndDefaultPolicyClosestThenClosestMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: closestConfig) + XCTAssertEqual(ExpectedAgent.mobileClosest, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenMobileUaAndDesktopTrueAndDefaultPolicyClosestThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: closestConfig) + XCTAssertEqual(ExpectedAgent.desktopClosest, testee.agent(forUrl: Constants.url, isDesktop: true, privacyConfig: config)) + } + + func testWhenTabletUaAndDesktopFalseAndDefaultPolicyClosestThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.tablet) + let config = makePrivacyConfig(from: closestConfig) + XCTAssertEqual(ExpectedAgent.tabletClosest, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenTabletUaAndDesktopTrueAndDefaultPolicyClosestThenFixedMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.tablet) + let config = makePrivacyConfig(from: closestConfig) + XCTAssertEqual(ExpectedAgent.desktopClosest, testee.agent(forUrl: Constants.url, isDesktop: true, privacyConfig: config)) + } + + func testWhenDefaultPolicyClosestAndDomainIsOnDefaultListThenDefaultAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: closestConfig) + XCTAssertEqual(ExpectedAgent.mobile, testee.agent(forUrl: Constants.ddgDefaultUrl, isDesktop: false, privacyConfig: config)) + } + + func testWhenDefaultPolicyClosestAndDomainIsOnFixedListThenFixedAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.mobile) + let config = makePrivacyConfig(from: closestConfig) + XCTAssertEqual(ExpectedAgent.mobileFixed, testee.agent(forUrl: Constants.ddgFixedUrl, isDesktop: false, privacyConfig: config)) + } + + let configWithVersions = """ + { + "features": { + "customUserAgent": { + "state": "enabled", + "settings": { + "defaultPolicy": "ddg", + "omitApplicationSites": [ + { + "domain": "cvs.com", + "reason": "Site reports browser not supported" + } + ], + "closestUserAgent": { + "versions": ["350", "360"] + }, + "ddgFixedUserAgent": { + "versions": ["351", "361"] + } + }, + "exceptions": [] + } + }, + "unprotectedTemporary": [] + } + """.data(using: .utf8)! + + func testWhenAtbDoesNotMatchVersionFromConfigThenDefaultUAIsUsed() { + let statisticsStore = MockStatisticsStore() + statisticsStore.atb = "v300-1" + let testee = UserAgent(defaultAgent: DefaultAgent.mobile, statistics: statisticsStore) + let config = makePrivacyConfig(from: configWithVersions) + XCTAssertEqual(ExpectedAgent.mobile, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenAtbMatchesVersionInClosestUserAgentThenClosestUAIsUsed() { + let statisticsStore = MockStatisticsStore() + statisticsStore.atb = "v360-1" + let testee = UserAgent(defaultAgent: DefaultAgent.mobile, statistics: statisticsStore) + let config = makePrivacyConfig(from: configWithVersions) + XCTAssertEqual(ExpectedAgent.mobileClosest, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenAtbMatchesVersionInDDGFixedUserAgentThenDDGFixedUAIsUsed() { + let statisticsStore = MockStatisticsStore() + statisticsStore.atb = "v361-1" + let testee = UserAgent(defaultAgent: DefaultAgent.mobile, statistics: statisticsStore) + let config = makePrivacyConfig(from: configWithVersions) + XCTAssertEqual(ExpectedAgent.mobileFixed, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenAtbWithoutDayComponentMatchesVersionInDDGFixedUserAgentThenDDGFixedUAIsUsed() { + let statisticsStore = MockStatisticsStore() + statisticsStore.atb = "v361" + let testee = UserAgent(defaultAgent: DefaultAgent.mobile, statistics: statisticsStore) + let config = makePrivacyConfig(from: configWithVersions) + XCTAssertEqual(ExpectedAgent.mobileFixed, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenOldWebKitVersionThenDefaultMobileAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.oldWebkitVersionMobile) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.oldWebkitVersionMobile, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenNewerWebKitVersionThenFixedAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.newWebkitVersionMobile) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.newWebkitVersionMobile, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + + func testWhenSameWebKitVersionThenFixedAgentUsed() { + let testee = UserAgent(defaultAgent: DefaultAgent.sameWebkitVersionMobile) + let config = makePrivacyConfig(from: ddgFixedConfig) + XCTAssertEqual(ExpectedAgent.sameWebkitVersionMobile, testee.agent(forUrl: Constants.url, isDesktop: false, privacyConfig: config)) + } + } +// swiftlint:enable file_length type_body_length diff --git a/IntegrationTests/AtbServerTests.swift b/IntegrationTests/AtbServerTests.swift index fe395bac42..8d7a50a7bc 100644 --- a/IntegrationTests/AtbServerTests.swift +++ b/IntegrationTests/AtbServerTests.swift @@ -37,11 +37,7 @@ class AtbServerTests: XCTestCase { loader = StatisticsLoader(statisticsStore: store) } - - override func tearDown() { - super.tearDown() - } - + func testExtiCall() { let waitForCompletion = expectation(description: "wait for completion") diff --git a/PacketTunnelProvider/NetworkProtectionPacketTunnelProvider.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift similarity index 96% rename from PacketTunnelProvider/NetworkProtectionPacketTunnelProvider.swift rename to PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift index 3132cabffc..ccb15449ae 100644 --- a/PacketTunnelProvider/NetworkProtectionPacketTunnelProvider.swift +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionPacketTunnelProvider.swift @@ -166,7 +166,9 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { let tokenStore = NetworkProtectionKeychainTokenStore(keychainType: .dataProtection(.unspecified), errorEvents: nil) let errorStore = NetworkProtectionTunnelErrorStore() - super.init(notificationsPresenter: DefaultNotificationPresenter(), + let notificationsPresenter = NetworkProtectionUNNotificationPresenter() + notificationsPresenter.requestAuthorization() + super.init(notificationsPresenter: notificationsPresenter, tunnelHealthStore: NetworkProtectionTunnelHealthStore(), controllerErrorStore: errorStore, keychainType: .dataProtection(.unspecified), @@ -201,21 +203,3 @@ final class NetworkProtectionPacketTunnelProvider: PacketTunnelProvider { } } } - -final class DefaultNotificationPresenter: NetworkProtectionNotificationsPresenter { - - func showTestNotification() { - } - - func showReconnectedNotification() { - } - - func showReconnectingNotification() { - } - - func showConnectionFailureNotification() { - } - - func showSupersededNotification() { - } -} diff --git a/PacketTunnelProvider/NetworkProtection/NetworkProtectionUNNotificationPresenter.swift b/PacketTunnelProvider/NetworkProtection/NetworkProtectionUNNotificationPresenter.swift new file mode 100644 index 0000000000..7ada176e81 --- /dev/null +++ b/PacketTunnelProvider/NetworkProtection/NetworkProtectionUNNotificationPresenter.swift @@ -0,0 +1,114 @@ +// +// NetworkProtectionUNNotificationPresenter.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit +import NetworkProtection +import Core + +/// This class takes care of requesting the presentation of notifications using UNNotificationCenter +/// +final class NetworkProtectionUNNotificationPresenter: NSObject, NetworkProtectionNotificationsPresenter { + + private let userNotificationCenter: UNUserNotificationCenter + + private var threadIdentifier: String { + let bundleId = Bundle(for: Self.self).bundleIdentifier ?? "com.duckduckgo.mobile.ios.NetworkExtension" + return bundleId + ".threadIdentifier" + } + + init(userNotificationCenter: UNUserNotificationCenter = .current()) { + self.userNotificationCenter = userNotificationCenter + + super.init() + } + + // MARK: - Setup + + func requestAuthorization() { + userNotificationCenter.delegate = self + requestAlertAuthorization() + } + + // MARK: - Notification Utility methods + + private func requestAlertAuthorization(completionHandler: ((Bool) -> Void)? = nil) { + let options: UNAuthorizationOptions = .alert + + userNotificationCenter.requestAuthorization(options: options) { authorized, _ in + completionHandler?(authorized) + } + } + + private func notificationContent(body: String) -> UNNotificationContent { + let content = UNMutableNotificationContent() + + content.threadIdentifier = threadIdentifier + content.title = UserText.networkProtectionNotificationsTitle + content.body = body + + if #available(iOSApplicationExtension 15.0, *) { + content.interruptionLevel = .timeSensitive + content.relevanceScore = 0 + } + + return content + } + + func showTestNotification() { + // Debug only string. Doesn't need localized + let content = notificationContent(body: "Test notification") + showNotification(.test, content) + } + + func showReconnectedNotification() { + let content = notificationContent(body: UserText.networkProtectionConnectionSuccessNotificationBody) + showNotification(.reconnected, content) + } + + func showReconnectingNotification() { + let content = notificationContent(body: UserText.networkProtectionConnectionInterruptedNotificationBody) + showNotification(.reconnecting, content) + } + + func showConnectionFailureNotification() { + let content = notificationContent(body: UserText.networkProtectionConnectionFailureNotificationBody) + showNotification(.connectionFailure, content) + } + + func showSupersededNotification() { + } + + private func showNotification(_ identifier: NetworkProtectionNotificationIdentifier, _ content: UNNotificationContent) { + let request = UNNotificationRequest(identifier: identifier.rawValue, content: content, trigger: .none) + + requestAlertAuthorization { authorized in + guard authorized else { + return + } + self.userNotificationCenter.removeDeliveredNotifications(withIdentifiers: [identifier.rawValue]) + self.userNotificationCenter.add(request) + } + } +} + +extension NetworkProtectionUNNotificationPresenter: UNUserNotificationCenterDelegate { + func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { + return .banner + } +} diff --git a/PacketTunnelProvider/UserText.swift b/PacketTunnelProvider/UserText.swift new file mode 100644 index 0000000000..0d2bd15fae --- /dev/null +++ b/PacketTunnelProvider/UserText.swift @@ -0,0 +1,35 @@ +// +// UserText.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +// swiftlint:disable line_length +final class UserText { + + // MARK: - Network Protection Notifications + + static let networkProtectionNotificationsTitle = NSLocalizedString("network.protection.notification.title", value: "DuckDuckGo", comment: "The title of the notifications shown from Network Protection") + + static let networkProtectionConnectionSuccessNotificationBody = NSLocalizedString("network.protection.success.notification.body", value: "Network Protection is On. Your location and online activity are protected.", comment: "The body of the notification shown when Network Protection reconnects successfully") + + static let networkProtectionConnectionInterruptedNotificationBody = NSLocalizedString("network.protection.interrupted.notification.body", value: "Network Protection was interrupted. Attempting to reconnect now...", comment: "The body of the notification shown when Network Protection's connection is interrupted") + + static let networkProtectionConnectionFailureNotificationBody = NSLocalizedString("network.protection.failure.notification.body", value: "Network Protection failed to connect. Please try again later.", comment: "The body of the notification shown when Network Protection fails to reconnect") +} +// swiftlint:enable line_length diff --git a/fastlane/Fastfile b/fastlane/Fastfile index dcc1b3745d..a4eef3a73b 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -141,7 +141,7 @@ end desc 'Increment build number based on version in App Store Connect' lane :increment_build_number_for_version do |options| - app_identifier = "com.duckduckgo.mobile.ios" + app_identifier = "com.duckduckgo.mobile.ios" if options[:app_identifier] app_identifier = options[:app_identifier] end diff --git a/fastlane/metadata/default/release_notes.txt b/fastlane/metadata/default/release_notes.txt index c67b8d6903..4942898476 100644 --- a/fastlane/metadata/default/release_notes.txt +++ b/fastlane/metadata/default/release_notes.txt @@ -1,4 +1,3 @@ -- Fix issue that caused crashes for some iOS 15 users -- Improved credential autofill on websites in Dutch, French, German, Italian, Spanish, and Swedish, making logging into accounts easier. More languages coming soon. +Bug fixes and other improvements. Join our fully distributed team and help raise the standard of trust online! https://duckduckgo.com/hiring