From db85ca9729154fa723eee1864626c749d0e24afb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gonz=C3=A1lez?= Date: Thu, 12 Dec 2024 20:43:54 +0100 Subject: [PATCH 01/32] Site Permissions: Code Clean up (#5363) Task/Issue URL: https://app.asana.com/0/72649045549333/1208702063802241/f ### Description This PR finishes cleaning up the code from Site Permissions. - Moves strings to site permissions module - Moves Activities to site permissions module - Removes old LocationPermissions ### Steps to test this PR Navigate to Site Permissions screen and smoke test it --------- Co-authored-by: Dax The Translator --- .../app/browser/BrowserTabViewModelTest.kt | 21 --- .../favicon/DuckDuckGoFaviconManagerTest.kt | 6 - .../view/ClearPersonalDataActionTest.kt | 5 +- .../location/GeoLocationPermissionsTest.kt | 163 ------------------ app/src/main/AndroidManifest.xml | 9 - .../app/appearance/AppearanceActivity.kt | 2 +- .../duckduckgo/app/browser/BrowserActivity.kt | 4 +- .../favicon/DuckDuckGoFaviconManager.kt | 3 - .../app/browser/favicon/FaviconModule.kt | 3 - .../com/duckduckgo/app/di/PrivacyModule.kt | 15 -- .../ui/FireproofWebsitesActivity.kt | 2 +- .../global/view/ClearPersonalDataAction.kt | 3 - .../location/GeoLocationPermissionsManager.kt | 88 ---------- .../app/permissions/PermissionsActivity.kt | 10 +- .../app/privacy/ui/AllowListActivity.kt | 6 +- app/src/main/res/values-bg/strings.xml | 30 +--- app/src/main/res/values-cs/strings.xml | 30 +--- app/src/main/res/values-da/strings.xml | 30 +--- app/src/main/res/values-de/strings.xml | 30 +--- app/src/main/res/values-el/strings.xml | 30 +--- app/src/main/res/values-es/strings.xml | 30 +--- app/src/main/res/values-et/strings.xml | 30 +--- app/src/main/res/values-fi/strings.xml | 30 +--- app/src/main/res/values-fr/strings.xml | 30 +--- app/src/main/res/values-hr/strings.xml | 30 +--- app/src/main/res/values-hu/strings.xml | 30 +--- app/src/main/res/values-it/strings.xml | 30 +--- app/src/main/res/values-lt/strings.xml | 30 +--- app/src/main/res/values-lv/strings.xml | 30 +--- app/src/main/res/values-nb/strings.xml | 30 +--- app/src/main/res/values-nl/strings.xml | 30 +--- app/src/main/res/values-pl/strings.xml | 30 +--- app/src/main/res/values-pt/strings.xml | 30 +--- app/src/main/res/values-ro/strings.xml | 30 +--- app/src/main/res/values-ru/strings.xml | 30 +--- app/src/main/res/values-sk/strings.xml | 30 +--- app/src/main/res/values-sl/strings.xml | 30 +--- app/src/main/res/values-sv/strings.xml | 30 +--- app/src/main/res/values-tr/strings.xml | 30 +--- app/src/main/res/values/donottranslate.xml | 3 - app/src/main/res/values/strings.xml | 25 --- .../res/values-bg/strings-autoconsent.xml | 3 +- .../res/values-cs/strings-autoconsent.xml | 3 +- .../res/values-da/strings-autoconsent.xml | 3 +- .../res/values-de/strings-autoconsent.xml | 3 +- .../res/values-el/strings-autoconsent.xml | 3 +- .../res/values-es/strings-autoconsent.xml | 3 +- .../res/values-et/strings-autoconsent.xml | 3 +- .../res/values-fi/strings-autoconsent.xml | 3 +- .../res/values-fr/strings-autoconsent.xml | 3 +- .../res/values-hr/strings-autoconsent.xml | 3 +- .../res/values-hu/strings-autoconsent.xml | 3 +- .../res/values-it/strings-autoconsent.xml | 3 +- .../res/values-lt/strings-autoconsent.xml | 3 +- .../res/values-lv/strings-autoconsent.xml | 3 +- .../res/values-nb/strings-autoconsent.xml | 3 +- .../res/values-nl/strings-autoconsent.xml | 3 +- .../res/values-pl/strings-autoconsent.xml | 3 +- .../res/values-pt/strings-autoconsent.xml | 3 +- .../res/values-ro/strings-autoconsent.xml | 3 +- .../res/values-ru/strings-autoconsent.xml | 3 +- .../res/values-sk/strings-autoconsent.xml | 3 +- .../res/values-sl/strings-autoconsent.xml | 3 +- .../res/values-sv/strings-autoconsent.xml | 3 +- .../res/values-tr/strings-autoconsent.xml | 3 +- .../res/values-bg/strings-autofill-impl.xml | 1 + .../res/values-cs/strings-autofill-impl.xml | 1 + .../res/values-da/strings-autofill-impl.xml | 1 + .../res/values-de/strings-autofill-impl.xml | 1 + .../res/values-el/strings-autofill-impl.xml | 1 + .../res/values-es/strings-autofill-impl.xml | 1 + .../res/values-et/strings-autofill-impl.xml | 1 + .../res/values-fi/strings-autofill-impl.xml | 1 + .../res/values-fr/strings-autofill-impl.xml | 1 + .../res/values-hr/strings-autofill-impl.xml | 1 + .../res/values-hu/strings-autofill-impl.xml | 1 + .../res/values-it/strings-autofill-impl.xml | 1 + .../res/values-lt/strings-autofill-impl.xml | 1 + .../res/values-lv/strings-autofill-impl.xml | 1 + .../res/values-nb/strings-autofill-impl.xml | 1 + .../res/values-nl/strings-autofill-impl.xml | 1 + .../res/values-pl/strings-autofill-impl.xml | 1 + .../res/values-pt/strings-autofill-impl.xml | 1 + .../res/values-ro/strings-autofill-impl.xml | 1 + .../res/values-ru/strings-autofill-impl.xml | 1 + .../res/values-sk/strings-autofill-impl.xml | 1 + .../res/values-sl/strings-autofill-impl.xml | 1 + .../res/values-sv/strings-autofill-impl.xml | 1 + .../res/values-tr/strings-autofill-impl.xml | 1 + .../main/res/values-bg/strings-common-ui.xml | 20 ++- .../main/res/values-cs/strings-common-ui.xml | 20 ++- .../main/res/values-da/strings-common-ui.xml | 20 ++- .../main/res/values-de/strings-common-ui.xml | 20 ++- .../main/res/values-el/strings-common-ui.xml | 20 ++- .../main/res/values-es/strings-common-ui.xml | 20 ++- .../main/res/values-et/strings-common-ui.xml | 20 ++- .../main/res/values-fi/strings-common-ui.xml | 20 ++- .../main/res/values-fr/strings-common-ui.xml | 20 ++- .../main/res/values-hr/strings-common-ui.xml | 20 ++- .../main/res/values-hu/strings-common-ui.xml | 20 ++- .../main/res/values-it/strings-common-ui.xml | 20 ++- .../main/res/values-lt/strings-common-ui.xml | 20 ++- .../main/res/values-lv/strings-common-ui.xml | 20 ++- .../main/res/values-nb/strings-common-ui.xml | 20 ++- .../main/res/values-nl/strings-common-ui.xml | 20 ++- .../main/res/values-pl/strings-common-ui.xml | 20 ++- .../main/res/values-pt/strings-common-ui.xml | 20 ++- .../main/res/values-ro/strings-common-ui.xml | 20 ++- .../main/res/values-ru/strings-common-ui.xml | 20 ++- .../main/res/values-sk/strings-common-ui.xml | 20 ++- .../main/res/values-sl/strings-common-ui.xml | 20 ++- .../main/res/values-sv/strings-common-ui.xml | 20 ++- .../main/res/values-tr/strings-common-ui.xml | 20 ++- .../src/main/res/values/strings-common-ui.xml | 13 ++ .../site-permissions-impl/build.gradle | 1 + .../src/main/AndroidManifest.xml | 33 ++++ .../impl/ui}/SitePermissionsActivity.kt | 26 ++- .../impl/ui}/SitePermissionsAdapter.kt | 41 +++-- .../impl/ui/SitePermissionsScreens.kt | 24 +++ .../impl/ui}/SitePermissionsViewModel.kt | 8 +- .../PermissionSettingAdapter.kt | 6 +- .../PermissionsPerWebsiteActivity.kt | 24 +-- .../PermissionsPerWebsiteViewModel.kt | 12 +- .../WebsitePermissionSettingOption.kt | 4 +- .../src/main/res/drawable/ic_location_24.xml | 0 .../res/drawable/ic_location_blocked_24.xml | 0 .../main/res/drawable/ic_microphone_24.xml | 0 .../res/drawable/ic_microphone_blocked_24.xml | 0 .../src/main/res/drawable/ic_video_24.xml | 0 .../main/res/drawable/ic_video_blocked_24.xml | 0 .../main/res/drawable/ic_video_player_24.xml | 0 .../drawable/ic_video_player_blocked_24.xml | 0 .../activity_permission_per_website.xml | 0 .../res/layout/activity_site_permissions.xml | 2 +- ...item_site_permission_setting_selection.xml | 0 .../layout/popup_window_remove_all_menu.xml | 29 ++++ .../view_site_permissions_description.xml | 0 .../view_site_permissions_empty_list.xml | 0 .../res/layout/view_site_permissions_site.xml | 0 .../layout/view_site_permissions_title.xml | 0 .../layout/view_site_permissions_toggle.xml | 0 .../menu_permissions_per_website_activity.xml | 24 +++ .../values-bg/strings-site-permissions.xml | 38 ++++ .../values-cs/strings-site-permissions.xml | 38 ++++ .../values-da/strings-site-permissions.xml | 38 ++++ .../values-de/strings-site-permissions.xml | 38 ++++ .../values-el/strings-site-permissions.xml | 38 ++++ .../values-es/strings-site-permissions.xml | 38 ++++ .../values-et/strings-site-permissions.xml | 38 ++++ .../values-fi/strings-site-permissions.xml | 38 ++++ .../values-fr/strings-site-permissions.xml | 38 ++++ .../values-hr/strings-site-permissions.xml | 38 ++++ .../values-hu/strings-site-permissions.xml | 38 ++++ .../values-it/strings-site-permissions.xml | 38 ++++ .../values-lt/strings-site-permissions.xml | 38 ++++ .../values-lv/strings-site-permissions.xml | 38 ++++ .../values-nb/strings-site-permissions.xml | 38 ++++ .../values-nl/strings-site-permissions.xml | 38 ++++ .../values-pl/strings-site-permissions.xml | 38 ++++ .../values-pt/strings-site-permissions.xml | 38 ++++ .../values-ro/strings-site-permissions.xml | 38 ++++ .../values-ru/strings-site-permissions.xml | 38 ++++ .../values-sk/strings-site-permissions.xml | 38 ++++ .../values-sl/strings-site-permissions.xml | 38 ++++ .../values-sv/strings-site-permissions.xml | 38 ++++ .../values-tr/strings-site-permissions.xml | 38 ++++ .../src/main/res/values/donottranslate.xml | 24 +-- .../res/values/strings-site-permissions.xml | 38 ++++ .../PermissionsPerWebsiteViewModelTest.kt | 25 +-- .../SitePermissionsViewModelTest.kt | 15 +- .../src/main/res/values-bg/strings-sync.xml | 3 +- .../src/main/res/values-cs/strings-sync.xml | 3 +- .../src/main/res/values-da/strings-sync.xml | 3 +- .../src/main/res/values-de/strings-sync.xml | 3 +- .../src/main/res/values-el/strings-sync.xml | 3 +- .../src/main/res/values-es/strings-sync.xml | 3 +- .../src/main/res/values-et/strings-sync.xml | 3 +- .../src/main/res/values-fi/strings-sync.xml | 3 +- .../src/main/res/values-fr/strings-sync.xml | 3 +- .../src/main/res/values-hr/strings-sync.xml | 3 +- .../src/main/res/values-hu/strings-sync.xml | 3 +- .../src/main/res/values-it/strings-sync.xml | 3 +- .../src/main/res/values-lt/strings-sync.xml | 3 +- .../src/main/res/values-lv/strings-sync.xml | 3 +- .../src/main/res/values-nb/strings-sync.xml | 3 +- .../src/main/res/values-nl/strings-sync.xml | 3 +- .../src/main/res/values-pl/strings-sync.xml | 3 +- .../src/main/res/values-pt/strings-sync.xml | 3 +- .../src/main/res/values-ro/strings-sync.xml | 3 +- .../src/main/res/values-ru/strings-sync.xml | 3 +- .../src/main/res/values-sk/strings-sync.xml | 3 +- .../src/main/res/values-sl/strings-sync.xml | 3 +- .../src/main/res/values-sv/strings-sync.xml | 3 +- .../src/main/res/values-tr/strings-sync.xml | 3 +- 194 files changed, 1866 insertions(+), 1131 deletions(-) delete mode 100644 app/src/androidTest/java/com/duckduckgo/app/location/GeoLocationPermissionsTest.kt delete mode 100644 app/src/main/java/com/duckduckgo/app/location/GeoLocationPermissionsManager.kt create mode 100644 site-permissions/site-permissions-impl/src/main/AndroidManifest.xml rename {app/src/main/java/com/duckduckgo/app/sitepermissions => site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui}/SitePermissionsActivity.kt (83%) rename {app/src/main/java/com/duckduckgo/app/sitepermissions => site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui}/SitePermissionsAdapter.kt (85%) create mode 100644 site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsScreens.kt rename {app/src/main/java/com/duckduckgo/app/sitepermissions => site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui}/SitePermissionsViewModel.kt (94%) rename {app/src/main/java/com/duckduckgo/app/sitepermissions => site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui}/permissionsperwebsite/PermissionSettingAdapter.kt (88%) rename {app/src/main/java/com/duckduckgo/app/sitepermissions => site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui}/permissionsperwebsite/PermissionsPerWebsiteActivity.kt (82%) rename {app/src/main/java/com/duckduckgo/app/sitepermissions => site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui}/permissionsperwebsite/PermissionsPerWebsiteViewModel.kt (93%) rename {app/src/main/java/com/duckduckgo/app/sitepermissions => site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui}/permissionsperwebsite/WebsitePermissionSettingOption.kt (94%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_location_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_location_blocked_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_microphone_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_microphone_blocked_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_video_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_video_blocked_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_video_player_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/drawable/ic_video_player_blocked_24.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/activity_permission_per_website.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/activity_site_permissions.xml (94%) rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/item_site_permission_setting_selection.xml (100%) create mode 100644 site-permissions/site-permissions-impl/src/main/res/layout/popup_window_remove_all_menu.xml rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/view_site_permissions_description.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/view_site_permissions_empty_list.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/view_site_permissions_site.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/view_site_permissions_title.xml (100%) rename {app => site-permissions/site-permissions-impl}/src/main/res/layout/view_site_permissions_toggle.xml (100%) create mode 100644 site-permissions/site-permissions-impl/src/main/res/menu/menu_permissions_per_website_activity.xml rename {app/src/test/java/com/duckduckgo/app => site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui}/sitepermissions/PermissionsPerWebsiteViewModelTest.kt (89%) rename {app/src/test/java/com/duckduckgo/app => site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui}/sitepermissions/SitePermissionsViewModelTest.kt (91%) diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt index 0d99cca8bbfd..fc0aac1180cb 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt @@ -142,7 +142,6 @@ import com.duckduckgo.app.global.install.AppInstallStore import com.duckduckgo.app.global.model.PrivacyShield.PROTECTED import com.duckduckgo.app.global.model.Site import com.duckduckgo.app.global.model.SiteFactoryImpl -import com.duckduckgo.app.location.GeoLocationPermissions import com.duckduckgo.app.location.data.LocationPermissionsDao import com.duckduckgo.app.onboarding.store.AppStage import com.duckduckgo.app.onboarding.store.AppStage.ESTABLISHED @@ -370,8 +369,6 @@ class BrowserTabViewModelTest { private val mockFileDownloader: FileDownloader = mock() - private val geoLocationPermissions: GeoLocationPermissions = mock() - private val fireproofDialogsEventHandler: FireproofDialogsEventHandler = mock() private val mockEmailManager: EmailManager = mock() @@ -3038,8 +3035,6 @@ class BrowserTabViewModelTest { ) givenCurrentSite(domain) - givenDeviceLocationSharingIsEnabled(true) - givenLocationPermissionIsEnabled(true) loadUrl("https://www.example.com", isBrowserShowing = true) @@ -3055,8 +3050,6 @@ class BrowserTabViewModelTest { ) givenCurrentSite(domain) - givenDeviceLocationSharingIsEnabled(true) - givenLocationPermissionIsEnabled(true) loadUrl("https://www.example.com", isBrowserShowing = true) @@ -3066,8 +3059,6 @@ class BrowserTabViewModelTest { @Test fun whenUserVisitsDomainWithoutLocationPermissionThenMessageIsNotShown() = runTest { val domain = "https://www.example.com" - givenDeviceLocationSharingIsEnabled(true) - givenLocationPermissionIsEnabled(true) givenCurrentSite(domain) loadUrl("https://www.example.com", isBrowserShowing = true) @@ -3077,8 +3068,6 @@ class BrowserTabViewModelTest { @Test fun whenUserVisitsDomainAndLocationIsNotEnabledThenMessageIsNotShown() = runTest { val domain = "https://www.example.com" - givenDeviceLocationSharingIsEnabled(true) - givenLocationPermissionIsEnabled(false) givenCurrentSite(domain) loadUrl("https://www.example.com", isBrowserShowing = true) @@ -3095,8 +3084,6 @@ class BrowserTabViewModelTest { ) givenCurrentSite(domain) - givenDeviceLocationSharingIsEnabled(true) - givenLocationPermissionIsEnabled(true) loadUrl("https://www.example.com", isBrowserShowing = true) loadUrl("https://www.example.com", isBrowserShowing = true) @@ -5901,14 +5888,6 @@ class BrowserTabViewModelTest { dismissedCtaDaoChannel.send(listOf(DismissedCta(CtaId.DAX_DIALOG_TRACKERS_FOUND))) } - private fun givenDeviceLocationSharingIsEnabled(state: Boolean) { - whenever(geoLocationPermissions.isDeviceLocationEnabled()).thenReturn(state) - } - - private fun givenLocationPermissionIsEnabled(state: Boolean) { - whenever(mockSettingsStore.appLocationPermission).thenReturn(state) - } - private inline fun assertCommandIssued(instanceAssertions: T.() -> Unit = {}) { verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture()) val issuedCommand = commandCaptor.allValues.find { it is T } diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/favicon/DuckDuckGoFaviconManagerTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/favicon/DuckDuckGoFaviconManagerTest.kt index 9fadc0af7566..459bf10c12e9 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/favicon/DuckDuckGoFaviconManagerTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/favicon/DuckDuckGoFaviconManagerTest.kt @@ -29,7 +29,6 @@ import com.duckduckgo.app.browser.favicon.FileBasedFaviconPersister.Companion.NO import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteDao import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteRepositoryImpl import com.duckduckgo.app.location.data.LocationPermissionsDao -import com.duckduckgo.app.location.data.LocationPermissionsRepositoryImpl import com.duckduckgo.autofill.api.store.AutofillStore import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.common.utils.faviconLocation @@ -75,11 +74,6 @@ class DuckDuckGoFaviconManagerTest { faviconPersister = mockFaviconPersister, savedSitesDao = mockSavedSitesDao, fireproofWebsiteRepository = FireproofWebsiteRepositoryImpl(mockFireproofWebsiteDao, coroutineRule.testDispatcherProvider, mock()), - locationPermissionsRepository = LocationPermissionsRepositoryImpl( - mockLocationPermissionsDao, - mock(), - coroutineRule.testDispatcherProvider, - ), savedSitesRepository = mockSavedSitesRepository, faviconDownloader = mockFaviconDownloader, dispatcherProvider = coroutineRule.testDispatcherProvider, diff --git a/app/src/androidTest/java/com/duckduckgo/app/global/view/ClearPersonalDataActionTest.kt b/app/src/androidTest/java/com/duckduckgo/app/global/view/ClearPersonalDataActionTest.kt index ad34f71aeba9..0357ad5c82ef 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/global/view/ClearPersonalDataActionTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/global/view/ClearPersonalDataActionTest.kt @@ -26,7 +26,6 @@ import com.duckduckgo.app.fire.AppCacheClearer import com.duckduckgo.app.fire.UnsentForgetAllPixelStore import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteEntity import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteRepository -import com.duckduckgo.app.location.GeoLocationPermissions import com.duckduckgo.app.settings.db.SettingsDataStore import com.duckduckgo.app.tabs.model.TabRepository import com.duckduckgo.cookies.api.DuckDuckGoCookieManager @@ -56,7 +55,6 @@ class ClearPersonalDataActionTest { private val mockSettingsDataStore: SettingsDataStore = mock() private val mockCookieManager: DuckDuckGoCookieManager = mock() private val mockAppCacheClearer: AppCacheClearer = mock() - private val mockGeoLocationPermissions: GeoLocationPermissions = mock() private val mockThirdPartyCookieManager: ThirdPartyCookieManager = mock() private val mockAdClickManager: AdClickManager = mock() private val mockFireproofWebsiteRepository: FireproofWebsiteRepository = mock() @@ -78,7 +76,6 @@ class ClearPersonalDataActionTest { settingsDataStore = mockSettingsDataStore, cookieManager = mockCookieManager, appCacheClearer = mockAppCacheClearer, - geoLocationPermissions = mockGeoLocationPermissions, thirdPartyCookieManager = mockThirdPartyCookieManager, adClickManager = mockAdClickManager, fireproofWebsiteRepository = mockFireproofWebsiteRepository, @@ -131,7 +128,7 @@ class ClearPersonalDataActionTest { @Test fun whenClearCalledThenGeoLocationPermissionsAreCleared() = runTest { testee.clearTabsAndAllDataAsync(appInForeground = false, shouldFireDataClearPixel = false) - verify(mockGeoLocationPermissions).clearAllButFireproofed() + verify(mockSitePermissionsManager).clearAllButFireproof(any()) } @Test diff --git a/app/src/androidTest/java/com/duckduckgo/app/location/GeoLocationPermissionsTest.kt b/app/src/androidTest/java/com/duckduckgo/app/location/GeoLocationPermissionsTest.kt deleted file mode 100644 index 96ab9b94882d..000000000000 --- a/app/src/androidTest/java/com/duckduckgo/app/location/GeoLocationPermissionsTest.kt +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2020 DuckDuckGo - * - * 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. - */ - -package com.duckduckgo.app.location - -import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import androidx.room.Room -import androidx.test.platform.app.InstrumentationRegistry -import com.duckduckgo.app.browser.favicon.FaviconManager -import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteDao -import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteEntity -import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteRepositoryImpl -import com.duckduckgo.app.global.db.AppDatabase -import com.duckduckgo.app.location.data.LocationPermissionEntity -import com.duckduckgo.app.location.data.LocationPermissionType -import com.duckduckgo.app.location.data.LocationPermissionsDao -import com.duckduckgo.app.location.data.LocationPermissionsRepositoryImpl -import com.duckduckgo.common.test.CoroutineTestRule -import com.duckduckgo.common.test.InstantSchedulersRule -import dagger.Lazy -import kotlinx.coroutines.test.runTest -import org.junit.After -import org.junit.Assert.* -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.mockito.kotlin.mock - -class GeoLocationPermissionsTest { - - @get:Rule - var instantTaskExecutorRule = InstantTaskExecutorRule() - - @get:Rule - val schedulers = InstantSchedulersRule() - - @get:Rule - var coroutineRule = CoroutineTestRule() - - private lateinit var locationPermissionsDao: LocationPermissionsDao - - private lateinit var fireproofWebsiteDao: FireproofWebsiteDao - - private lateinit var db: AppDatabase - - private lateinit var geoLocationPermissions: GeoLocationPermissions - - private val mockFaviconManager: FaviconManager = mock() - private val lazyFaviconManager = Lazy { mockFaviconManager } - - @Before - fun before() { - db = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getInstrumentation().targetContext, AppDatabase::class.java) - .allowMainThreadQueries() - .build() - locationPermissionsDao = db.locationPermissionsDao() - fireproofWebsiteDao = db.fireproofWebsiteDao() - - geoLocationPermissions = GeoLocationPermissionsManager( - InstrumentationRegistry.getInstrumentation().targetContext, - LocationPermissionsRepositoryImpl(locationPermissionsDao, lazyFaviconManager, coroutineRule.testDispatcherProvider), - FireproofWebsiteRepositoryImpl(fireproofWebsiteDao, coroutineRule.testDispatcherProvider, lazyFaviconManager), - coroutineRule.testDispatcherProvider, - ) - } - - @After - fun after() { - db.close() - } - - @Test - fun whenClearingAllPermissionsButFireproofedThenOnlyNonFireproofedSitesAreDeleted() = runTest { - givenFireproofWebsiteDomain("anotherdomain.com") - givenLocationPermissionsDomain("https://domain.com") - - val oldFireproofWebsites = fireproofWebsiteDao.fireproofWebsitesSync() - assertEquals(oldFireproofWebsites.size, 1) - - val oldLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(oldLocationPermissions.size, 1) - - geoLocationPermissions.clearAllButFireproofed() - - val newFireproofWebsites = fireproofWebsiteDao.fireproofWebsitesSync() - assertEquals(newFireproofWebsites.size, 1) - - val newLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(newLocationPermissions.size, 0) - } - - @Test - fun whenClearingAllPermissionsButFireproofedAndNoFireproofedSitesThenAllSitePermissionsAreDeleted() = runTest { - givenLocationPermissionsDomain("https://domain.com") - - val oldLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(oldLocationPermissions.size, 1) - - geoLocationPermissions.clearAllButFireproofed() - - val newLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(newLocationPermissions.size, 0) - } - - @Test - fun whenClearingAllPermissionsButFireproofedAndSiteIsFireproofedThenNothingIsDeleted() = runTest { - givenFireproofWebsiteDomain("domain.com") - givenLocationPermissionsDomain("https://domain.com") - - val oldFireproofWebsites = fireproofWebsiteDao.fireproofWebsitesSync() - assertEquals(oldFireproofWebsites.size, 1) - - val oldLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(oldLocationPermissions.size, 1) - - geoLocationPermissions.clearAllButFireproofed() - - val newFireproofWebsites = fireproofWebsiteDao.fireproofWebsitesSync() - assertEquals(newFireproofWebsites.size, 1) - - val newLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(newLocationPermissions.size, 1) - } - - @Test - fun whenClearingAllPermissionsThenAllPermissionsAreDeleted() = runTest { - givenLocationPermissionsDomain("https://domain.com") - - val oldLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(oldLocationPermissions.size, 1) - - geoLocationPermissions.clearAll() - - val newLocationPermissions = locationPermissionsDao.allPermissions() - assertEquals(newLocationPermissions.size, 0) - } - - private fun givenFireproofWebsiteDomain(vararg fireproofWebsitesDomain: String) { - fireproofWebsitesDomain.forEach { - fireproofWebsiteDao.insert(FireproofWebsiteEntity(domain = it)) - } - } - - private fun givenLocationPermissionsDomain( - domain: String, - permissionType: LocationPermissionType = LocationPermissionType.ALLOW_ALWAYS, - ) { - locationPermissionsDao.insert(LocationPermissionEntity(domain = domain, permission = permissionType)) - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e17ff9ee6576..1b5f33d42785 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -376,15 +376,6 @@ android:exported="false" android:label="@string/fireproofWebsitesActivityTitle" android:parentActivityName="com.duckduckgo.app.settings.SettingsActivity" /> - - ) - suspend fun clearAll() - suspend fun clearAllButFireproofed() -} - -class GeoLocationPermissionsManager @Inject constructor( - private val context: Context, - private val permissionsRepository: LocationPermissionsRepository, - private val fireproofWebsiteRepository: FireproofWebsiteRepository, - private val dispatchers: DispatcherProvider, -) : GeoLocationPermissions { - - override fun isDeviceLocationEnabled(): Boolean { - val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager - return LocationManagerCompat.isLocationEnabled(locationManager) - } - - override fun allow(domain: String) { - val geolocationPermissions = GeolocationPermissions.getInstance() - geolocationPermissions.allow(domain) - } - - override fun clear(domain: String) { - val geolocationPermissions = GeolocationPermissions.getInstance() - geolocationPermissions.clear(domain) - } - - override suspend fun undoClearAll(locationPermissions: List) { - locationPermissions.forEach { entity -> - permissionsRepository.savePermissionEntity(entity) - } - } - - override suspend fun clearAll() { - withContext(dispatchers.io()) { - val geolocationPermissions = GeolocationPermissions.getInstance() - val permissions = permissionsRepository.getLocationPermissionsSync() - permissions.forEach { - geolocationPermissions.clear(it.domain) - permissionsRepository.deletePermission(it.domain) - } - } - } - - override suspend fun clearAllButFireproofed() { - val geolocationPermissions = GeolocationPermissions.getInstance() - val permissions = permissionsRepository.getLocationPermissionsSync() - permissions.forEach { - if (!fireproofWebsiteRepository.isDomainFireproofed(it.domain)) { - geolocationPermissions.clear(it.domain) - permissionsRepository.deletePermission(it.domain) - } - } - } -} diff --git a/app/src/main/java/com/duckduckgo/app/permissions/PermissionsActivity.kt b/app/src/main/java/com/duckduckgo/app/permissions/PermissionsActivity.kt index 6949f5852592..285274a722c1 100644 --- a/app/src/main/java/com/duckduckgo/app/permissions/PermissionsActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/permissions/PermissionsActivity.kt @@ -32,13 +32,14 @@ import com.duckduckgo.app.browser.databinding.ActivityPermissionsBinding import com.duckduckgo.app.permissions.PermissionsViewModel.Command import com.duckduckgo.app.settings.clear.AppLinkSettingType import com.duckduckgo.app.settings.clear.getAppLinkSettingForIndex -import com.duckduckgo.app.sitepermissions.SitePermissionsActivity import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.appbuildconfig.api.AppBuildConfig import com.duckduckgo.common.ui.DuckDuckGoActivity import com.duckduckgo.common.ui.view.dialog.RadioListAlertDialogBuilder import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.site.permissions.impl.ui.SitePermissionScreenNoParams import javax.inject.Inject import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -53,6 +54,9 @@ class PermissionsActivity : DuckDuckGoActivity() { @Inject lateinit var pixel: Pixel + @Inject + lateinit var globalActivityStarter: GlobalActivityStarter + private val viewModel: PermissionsViewModel by bindViewModel() private val binding: ActivityPermissionsBinding by viewBinding() @@ -116,7 +120,7 @@ class PermissionsActivity : DuckDuckGoActivity() { private fun launchLocation() { val options = ActivityOptions.makeSceneTransitionAnimation(this).toBundle() - startActivity(SitePermissionsActivity.intent(this), options) + globalActivityStarter.start(this, SitePermissionScreenNoParams, options) } private fun launchAppLinksSettingSelector(appLinkSettingType: AppLinkSettingType) { @@ -131,7 +135,7 @@ class PermissionsActivity : DuckDuckGoActivity() { ), currentAppLinkSetting, ) - .setPositiveButton(R.string.dialogSave) + .setPositiveButton(com.duckduckgo.mobile.android.R.string.dialogSave) .setNegativeButton(R.string.cancel) .addEventListener( object : RadioListAlertDialogBuilder.EventListener() { diff --git a/app/src/main/java/com/duckduckgo/app/privacy/ui/AllowListActivity.kt b/app/src/main/java/com/duckduckgo/app/privacy/ui/AllowListActivity.kt index 425c37e6d241..387c5951db1f 100644 --- a/app/src/main/java/com/duckduckgo/app/privacy/ui/AllowListActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/privacy/ui/AllowListActivity.kt @@ -109,7 +109,7 @@ class AllowListActivity : DuckDuckGoActivity() { val inputBinding = DialogEditAllowlistBinding.inflate(layoutInflater) CustomAlertDialogBuilder(this) .setTitle(R.string.dialogAddTitle) - .setPositiveButton(R.string.dialogSave) + .setPositiveButton(com.duckduckgo.mobile.android.R.string.dialogSave) .setNegativeButton(R.string.cancel) .setView(inputBinding) .addEventListener( @@ -128,7 +128,7 @@ class AllowListActivity : DuckDuckGoActivity() { inputBinding.customDialogTextInput.text = entry.domain CustomAlertDialogBuilder(this) .setTitle(R.string.dialogEditTitle) - .setPositiveButton(R.string.dialogSave) + .setPositiveButton(com.duckduckgo.mobile.android.R.string.dialogSave) .setNegativeButton(R.string.cancel) .setView(inputBinding) .addEventListener( @@ -144,7 +144,7 @@ class AllowListActivity : DuckDuckGoActivity() { private fun showDeleteDialog(entry: UserAllowListedDomain) { TextAlertDialogBuilder(this) - .setTitle(R.string.dialogConfirmTitle) + .setTitle(com.duckduckgo.mobile.android.R.string.dialogConfirmTitle) .setMessage(getString(R.string.allowlistEntryDeleteConfirmMessage, entry.domain).html(this)) .setPositiveButton(android.R.string.yes) .setNegativeButton(android.R.string.no) diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 8491b958ca68..b8ede3d5b2b8 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -192,6 +192,7 @@ Защита от проследяване в мрежата Защитата от проследяване в мрежата е активирана Научете повече]]> + Learn More]]> Защита от изскачащи прозорци за бисквитки @@ -200,6 +201,7 @@ Fire Button + Data Clearing Разрешения @@ -211,6 +213,7 @@ Запази Автоматично изчистване… + Automatically Clear Data… Автоматично изчистване… Няма Раздели @@ -227,8 +230,10 @@ Относно DuckDuckGo + About Добре дошли на наша страна! DuckDuckGo е независима компания, основана през 2008 г., за защита на личните данни в интернет за всеки, на когото му е омръзнало да бъде проследяван онлайн и иска лесно решение на проблема. Ние сме доказателство, че можете да получите реална и безкомпромисна защита на личните данни онлайн.\n\nБраузърът DuckDuckGo притежава функциите, които очаквате от един основен браузър, като отметки, раздели, пароли и много други, както и редица мощни защити на поверителността, които повечето популярни браузъри не предлагат по подразбиране. Този уникален и комплексен набор от защити на поверителността предлага сигурност при онлайн дейностите – търсене, сърфиране, изпращане на имейли и др.\n\nЗа да работят, нашите защити на поверителността не изискват да имате технически познания или да се извършвате сложни настройки. Необходимо е да използвате браузъра DuckDuckGo на всички Ваши устройства и ще получите поверителност по подразбиране.\n\nНо ако искате да надникнете зад кулисите и да разберете как работят защитите на поверителността на DuckDuckGo, можете да намерите повече информация на нашите страници за помощ. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Няма предложения @@ -260,14 +265,6 @@ Вижте какво е изпратено "Информацията, изпратена в отчетите, не може да се използва, за да бъдете идентифицирани:

• URL адрес на страница (без информация за идентифициране)
• Марка, модел и производител на устройството
• Номер на версията на операционната система
• Номер на версията на приложението
• Анонимна експериментална група за тестване на функции
• Информация за версиите на нашите защити, които са били активни
• Номер на версията на уеб браузъра
• Списък със защитите и функциите на браузъра, които са били активни
• Имена на хостове на блокирани тракери, сурогатни заявки, игнорирани заявки и заявки, които не са в списъка за блокиране на тракери
• Грешки, докладвани от браузъра
• Кодове за статус на отговор на уебсайта (HTTP)
• Форма за докладване, която сте използвали (меню, табло за управление и т.н.)
• Дата на последния изпратен доклад за този сайт
• Дали сте избрали да покажете информация за този доклад
• Брой пъти, когато защитите са били изключени
• Колко бързо са се заредили частите на страницата
• Как сте стигнали до тази страница: SERP (търсене с DuckDuckGo), навигация (връзка/URL) или чрез външни средства (други средства)
• Брой опреснявания откакто страницата е била заредена
• Основен език и държава на устройството
]]>"
- - Потвърдете - Запази - Изтриване - Редактиране - Премахване - Премахване на всички - Търсене с DuckDuckGo @@ -670,23 +667,6 @@ Изскачащият прозорец е скрит Бисквитките са настроени - - Разрешения за сайтове - Сайтовете, които посещавате, може да поискат достъп до местоположението, камерата, микрофона или софтуера за управление на цифровите права (DRM) на устройството. Те няма да имат достъп до тях, освен ако не им дадете изрично разрешение. - Разрешаване на всички сайтове да искат: - Местоположение - Камера - Микрофон - Управление на сайтове - Все още няма сайтове - Разрешенията са премахнати за всички сайтове - Разрешения за \"%1$s\" - Питай всеки път - Отказвам - Разрешавам - Деактивирано за всички сайтове - %1$s разрешение за %2$s - Разберете кога изтеглянето е завършено Получавайте известие, когато изтеглянето завърши. diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 461d61188c99..b046ab5bbfef 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -192,6 +192,7 @@ Ochrana před sledováním na webu Ochrana před sledováním na webu je povolená Další informace]]> + Learn More]]> Ochrana před vyskakovacími okny ohledně cookies @@ -200,6 +201,7 @@ Fire Button + Data Clearing Oprávnění @@ -211,6 +213,7 @@ Uložit Automatické vymazání… + Automatically Clear Data… Automatické vymazání… Žádný Karty @@ -227,8 +230,10 @@ O DuckDuckGo + About Vítejte na Kačeří straně! DuckDuckGo je nezávislá společnost založená v roce 2008, která se zabývá ochranou soukromí pro všechny, kdo už mají dost sledování na internetu a chtějí snadné řešení. Jsme důkazem, že skutečná ochrana soukromí na internetu nemusí mít kompromisy.\n\nProhlížeč DuckDuckGo má všechno, co od prohlížeče očekáváš, jako jsou záložky, karty, hesla a další funkce. A k tomu má víc než desítku účinných funkcí na ochranu soukromí, které většina oblíbených prohlížečů ve výchozím nastavení nenabízí. Tahle jedinečná komplexní sada na ochranu soukromí pomáhá chránit tvoje aktivity na internetu od vyhledávání přes prohlížení až po posílání e-mailů.\n\nAby naše ochrana soukromí fungovala, nemusíš znát technické detaily ani řešit žádná složitá nastavení. Stačí přejít na prohlížeč DuckDuckGo ve všech zařízeních a dostaneš soukromí pro všechny své aktivity.\n\nJestli chceš nahlédnout pod pokličku, víc informací o tom, jak ochrana soukromí DuckDuckGo funguje, najdeš v naší nápovědě. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Žádné návrhy @@ -260,14 +265,6 @@ Podívej se, co se odesílá "Informace odeslané v přehledech se nedají použít k tvé identifikaci:

• Adresa URL stránky (bez údajů umožňujících zjištění totožnosti)
• Značka, model a výrobce zařízení
• Číslo verze operačního systému
• Číslo verze aplikace
• Anonymní experimentální skupina pro testování funkcí
• Informace o tom, které verze našich ochranných funkcí byly aktivní
• Číslo verze webového prohlížeče
• Seznam aktivních ochranných funkcí a funkcí prohlížeče
• Názvy hostitelů blokovaných trackerů, náhradních požadavků, ignorovaných požadavků a požadavků, které v seznamu blokovaných trackerů nejsou
• Chyby hlášené prohlížečem
• Kódy stavu odezvy webových stránek (HTTP)
• Jaký formulář pro hlášení byl použitý (nabídka, hlavní panel atd.)
• Datum posledního hlášení poslaného pro tento web
• Jestli jsi vyjádřil(a) souhlas se zobrazováním těchto informací o hlášeních
• Kolikrát byly ochranné funkce vypnuté
• Jak rychle se jednotlivé části stránky načetly
• Jak ses na tuhle stránku dostal(a), a to buď: přes SERP (vyhledávání DuckDuckGo), navigací (z odkazu/URL), nebo externě (jiným způsobem)
• Počet obnovení od načtení stránky
• Primární jazyk a země tvého zařízení
]]>"
- - Potvrdit - Uložit - Smazat - Upravit - Odstranit - Odstranit vše - Hledat DuckDuckGo @@ -670,23 +667,6 @@ Skryté vyskakovací okno O cookies je postaráno! - - Oprávnění webu - Stránky, které navštívíš, můžou žádat o přístup k fotoaparátu, mikrofonu, softwaru DRM (Digital Rights Management) nebo k poloze tvého zařízení. Přístup mít nebudou, pokud jim ho výslovně nepovolíš. - Povolit všem webům, aby žádaly o: - Poloha - Fotoaparát - Mikrofon - Správa webů - Zatím žádné weby - Oprávnění odebrána všem webům - Oprávnění „%1$s“ - Vždycky se ptát - Odmítnout - Povolit - Zakázáno pro všechny weby - %1$s – povolení pro web %2$s - Zjisti, až budou soubory ke stažení připraveny Dostávej oznámení, jakmile skončí stahování. diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 54809ad00982..d52b38933a8a 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -192,6 +192,7 @@ Beskyttelse mod sporing på nettet Beskyttelse mod sporing på nettet er aktiveret Lær mere]]> + Learn More]]> Beskyttelse mod pop op-beskeder om cookies @@ -200,6 +201,7 @@ Fire Button + Data Clearing Tilladelser @@ -211,6 +213,7 @@ Gem Ryd automatisk … + Automatically Clear Data… Ryd automatisk … Ingen Faner @@ -227,8 +230,10 @@ Om DuckDuckGo + About Velkommen til Duck siden DuckDuckGo er en uafhængig virksomhed, grundlagt i 2008, der beskytter privatlivet på internettet for alle, der er trætte af at blive sporet online og ønsker en nem løsning. Vi er bevis på, at du kan få ægte beskyttelse af privatlivet online uden at gå på kompromis.\n\nDuckDuckGo-browseren kommer med de funktioner, du forventer af en standardbrowser, som bogmærker, faner, adgangskoder og meget mere, plus over et dusin kraftfulde beskyttelser af privatlivet, som ikke tilbydes i de fleste populære browsere som standard. Dette unikke og omfattende sæt af beskyttelsesfunktioner hjælper med at beskytte dine onlineaktiviteter, fra søgning til browsing, e-mailing og meget mere.\n\nVores beskyttelse af privatlivet fungerer, uden at du behøver at vide noget om de tekniske detaljer eller håndtere komplicerede indstillinger. Det eneste, du skal gøre, er at skifte din browser til DuckDuckGo på alle dine enheder, så får du privatliv som standard.\n\nMen hvis du gerne vil have et kig under motorhjelmen, kan du finde flere oplysninger om, hvordan DuckDuckGos beskyttelse af privatlivet fungerer, på vores hjælpesider + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Ingen forslag @@ -260,14 +265,6 @@ Se, hvad der bliver sendt "Oplysninger sendt i rapporter kan ikke bruges til at identificere dig:

• Side-URL (uden identificerbare oplysninger)
• Enhedsmærke, model og producent
• Operativsystem-versionsnummer
• App-versionsnummer
• Anonym eksperimentgruppe til funktionstest
• Oplysninger om, hvilke versioner af vores beskyttelser der var aktive
• Webbrowser-motorversionsnummer
• Liste over hvilke beskyttelser og browserfunktioner, der var aktive
• Værtsnavne på blokerede trackere, surrogatanmodninger, ignorerede anmodninger og anmodninger, der ikke er på listen over trackerblokeringer
• Browserrapporterede fejl
• Websiteresponsstatuskoder (HTTP)
• Hvilken rapporteringsformular du brugte (menu , dashboard osv.)
• Dato for sidste rapport sendt for dette websted
• Hvorvidt du valgte at vise disse rapportoplysninger
• Antal gange, beskyttelse blev slået fra
• Hvor hurtigt dele af siden blev indlæst
• Hvordan du kom til denne side, enten: SERP (DuckDuckGo-søgning), Navigation (link/URL) eller Ekstern (på anden måde)
• Antal opdateringer siden sideindlæsning
• Din enheds primære sprog og land
]]>"
- - Bekræft - Gem - Slet - Rediger - Fjern - Fjern alt - Søg på DuckDuckGo @@ -670,23 +667,6 @@ Pop op-vindue skjult Administrerede cookies - - Tilladelser til webstedet - Websteder, du besøger, kan bede om adgang til din enheds placering, kamera, mikrofon eller DRM-software (Digital Rights Management). De vil ikke kunne få adgang til disse, medmindre du udtrykkeligt giver dem tilladelse. - Tillad, at alle websteder beder om: - Placering - Kamera - Mikrofon - Administrer websteder - Ingen websteder endnu - Tilladelser fjernet for alle websteder - Tilladelser til \"%1$s\" - Spørg hver gang - Afvis - Tillad - Deaktiveret for alle websteder - %1$s tilladelse til %2$s - Find ud af, hvornår downloads er klar Få en meddelelse, når downloads er gennemført. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e06539ff743f..18d2439fd6e4 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -192,6 +192,7 @@ Web Tracking Protection Web Tracking Protection ist aktiviert Mehr erfahren]]> + Learn More]]> Cookie-Pop-up-Schutz @@ -200,6 +201,7 @@ Fire Button + Data Clearing Berechtigungen @@ -211,6 +213,7 @@ Speichern Automatisches Löschen von … + Automatically Clear Data… Automatisches Löschen von … Gar nichts Tabs @@ -227,8 +230,10 @@ Über DuckDuckGo + About Willkommen auf der Duck-len Seite! DuckDuckGo ist die unabhängige Firma für Internet-Datenschutz, das 2008 für alle gegründet wurde, die es leid sind, online getrackt zu werden, und eine einfache Lösung suchen. Wir sind der Beweis, dass du echten Online-Datenschutz ohne Kompromisse erhalten kannst.\n\nDer DuckDuckGo-Browser verfügt über die Funktionen, die von einem Go-to-Browser erwartet werden, darunter Lesezeichen, Tabs, Passwörter und mehr. Hinzu kommen über ein Dutzend leistungsstarke Datenschutzfunktionen, die in den meisten gängigen Browsern standardmäßig nicht angeboten werden. Dieser einzigartige, umfassende Datenschutz hilft dir, deine Online-Aktivitäten zu schützen – von der Suche über das Browsen bis hin zu E-Mails und vielem mehr.\n\nUnser Datenschutz funktioniert, ohne dass du etwas über die technischen Details wissen oder dich mit komplizierten Einstellungen auseinandersetzen musst. Du musst lediglich den Browser auf allen deinen Geräten auf DuckDuckGo umstellen und schon erhältst du echte Privatsphäre als Standard.\n\nWenn du jedoch einen Blick unter die Haube werfen möchtest, findest du auf unseren Hilfeseiten mehr Informationen darüber, wie der Datenschutz bei DuckDuckGo funktioniert. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Keine Vorschläge @@ -260,14 +265,6 @@ Sehen, was gesendet wurde "Die in den Berichten gesendeten Informationen können nicht dazu verwendet werden, dich zu identifizieren:

• Seiten-URL (ohne identifizierbare Informationen)
• Gerätemarke, -modell und -hersteller
• Versionsnummer des Betriebssystems
• Versionsnummer der App
• Anonyme Experimentiergruppe für Funktionstests
• Informationen darüber, welche Versionen unserer Schutzmaßnahmen aktiv waren
• Versionsnummer der Webbrowser-Engine
• Liste der Schutzmaßnahmen und Browserfunktionen, die aktiv waren
• Hostnamen der blockierten Tracker, Ersatzanfragen, ignorierte Anfragen und Anfragen, die nicht in der Tracker-Blockierliste enthalten sind
• Vom Browser gemeldete Fehler
• Codes für den Website-Antwortstatus (HTTP)
• Verwendete Berichtsform (Menü, Dashboard usw.)
• Datum des letzten Berichts für diese Website
• Ob du dich für die Anzeige dieser Berichtsinformationen entschieden hast oder nicht
• Wie oft der Schutz ausgeschaltet wurde
• Wie schnell Teile der Seite geladen wurden
• Wie du auf diese Seite gekommen bist: SERP (DuckDuckGo-Suche), Navigation (Link/URL) oder extern (andere Mittel)
• Anzahl der Aktualisierungen seit dem Laden der Seite
• Hauptsprache und Land deines Geräts
]]>"
- - Bestätigen - Speichern - Löschen - Bearbeiten - Entfernen - Alle entfernen - Mit DuckDuckGo suchen @@ -670,23 +667,6 @@ Pop-up ausgeblendet Cookies verwaltet - - Website-Berechtigungen - Von dir besuchte Websites bitten möglicherweise um Zugriff auf den Standort, die Kamera, das Mikrofon oder die DRM-Software (Digital Rights Management) deines Geräts. Sie können darauf nicht zugreifen, es sei denn, du erteilst ihnen ausdrücklich die Erlaubnis. - Allen Websites erlauben, um Folgendes zu bitten: - Standort - Kamera - Mikrofon - Websites verwalten - Noch keine Websites - Berechtigungen für alle Websites entfernt - Berechtigungen für „%1$s“ - Jedes Mal fragen - Ablehnen - Zulassen - Für alle Websites deaktiviert - %1$s-Berechtigung für %2$s - Erfahre, wann Downloads bereit sind Erhalte eine Benachrichtigung, wenn Downloads abgeschlossen sind. diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 9d73d38e166a..6e3a7d380d09 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -192,6 +192,7 @@ Προστασία παρακολούθησης ιστού Η προστασία παρακολούθησης ιστού είναι ενεργοποιημένη Μάθετε περισσότερα]]> + Learn More]]> Προστασία αναδυόμενων παραθύρων για cookies @@ -200,6 +201,7 @@ Κουμπί Φωτιά + Data Clearing Δικαιώματα @@ -211,6 +213,7 @@ Αποθήκευση Αυτόματη εκκαθάριση… + Automatically Clear Data… Αυτόματη εκκαθάριση… Κανένα Καρτέλες @@ -227,8 +230,10 @@ Σχετικά με το DuckDuckGo + About Καλωσορίσατε στην πλευρά της Πάπιας! Το DuckDuckGo αποτελεί την ανεξάρτητη εταιρεία προστασίας προσωπικών δεδομένων στο διαδίκτυο που ιδρύθηκε το 2008 για όσους έχουν βαρεθεί να παρακολουθούνται στο διαδίκτυο και επιθυμούν μια εύκολη λύση. Αποτελούμε τρανή απόδειξη ότι μπορείτε να αποκτήσετε πραγματική προστασία του απορρήτου σας στο διαδίκτυο χωρίς συμβιβασμούς.\n\nΤο πρόγραμμα περιήγησης DuckDuckGo διαθέτει τις λειτουργίες που περιμένετε από ένα πρόγραμμα περιήγησης, όπως σελιδοδείκτες, καρτέλες, κωδικούς πρόσβασης και πολλά άλλα, καθώς και πάνω από δώδεκα ισχυρές λειτουργίες προστασίας απορρήτου που δεν προσφέρονται από τα περισσότερα δημοφιλή προγράμματα περιήγησης βάσει προεπιλογής. Αυτό το μοναδικά ολοκληρωμένο σύνολο προστασίας του απορρήτου συμβάλλει στην προστασία των διαδικτυακών δραστηριοτήτων σας, από αναζήτηση έως περιήγηση, αποστολή email και πολλά άλλα.\n\nΗ προστασία απορρήτου μας λειτουργεί χωρίς να χρειάζεται να γνωρίζετε τις τεχνικές λεπτομέρειες ή να ασχολείστε με περίπλοκες ρυθμίσεις. Το μόνο που έχετε να κάνετε είναι να αλλάξετε το πρόγραμμα περιήγησής σας σε DuckDuckGo σε όλες τις συσκευές σας και θα έχετε ιδιωτικότητα βάσει προεπιλογής.\n\nΑλλά αν θέλετε να ρίξετε μια αναλυτική ματιά, μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με το πώς λειτουργούν οι προστασίες απορρήτου του DuckDuckGo στις σελίδες της ενότητας Βοήθεια + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Δεν υπάρχουν προτάσεις @@ -260,14 +265,6 @@ Δείτε τι έχει αποσταλεί "Οι πληροφορίες που αποστέλλονται σε αναφορές δεν μπορούν να χρησιμοποιηθούν για την ταυτοποίησή σας:

• Διεύθυνση URL σελίδας (χωρίς ταυτοποιήσιμες πληροφορίες)
• Μάρκα, μοντέλο και κατασκευαστής της συσκευής
• Αριθμός έκδοσης λειτουργικού συστήματος
• Αριθμός έκδοσης εφαρμογής
• Ανώνυμη πειραματική ομάδα για δοκιμή λειτουργιών
• Πληροφορίες σχετικά με το ποιες εκδόσεις των λειτουργιών προστασίας μας ήταν ενεργές
• Αριθμός έκδοσης μηχανής προγράμματος περιήγησης ιστού
• Κατάλογος των λειτουργιών προστασίας και των λειτουργιών του προγράμματος περιήγησης που ήταν ενεργά
• Ονόματα κεντρικών υπολογιστών εφαρμογών παρακολούθησης που έχουν αποκλειστεί, υποκατάστατα αιτήματα, αγνοημένα αιτήματα και αιτήματα που δεν περιλαμβάνονται στη λίστα αποκλεισμού εφαρμογών παρακολούθησης
• Σφάλματα που αναφέρθηκαν από το πρόγραμμα περιήγησης
• Κωδικοί κατάστασης απόκρισης ιστότοπου (HTTP)
• Ποια φόρμα αναφοράς χρησιμοποιήσατε (μενού, πίνακας εργαλείων, κ.λπ.)
• Ημερομηνία της τελευταίας αναφοράς που στάλθηκε γι' αυτόν τον ιστότοπο
• Εάν επιλέξατε να εμφανίσετε αυτές τις πληροφορίες αναφοράς ή όχι
• Αριθμός φορών που απενεργοποιήθηκαν οι λειτουργίες προστασίας
• Πόσο γρήγορα φορτώθηκαν τμήματα της σελίδας
• Πώς μεταβήκατε σε αυτήν τη σελίδα, είτε: SERP (αναζήτηση DuckDuckGo), Πλοήγηση (σύνδεσμος/διεύθυνση URL), είτε Εξωτερικά (άλλα μέσα)
• Αριθμός ανανεώσεων από τη φόρτωση της σελίδας
• Κύρια γλώσσα και χώρα της συσκευής σας
]]>"
- - Επιβεβαίωση - Αποθήκευση - Διαγραφή - Επεξεργασία - Αφαίρεση - Αφαίρεση όλων - Αναζήτηση DuckDuckGo @@ -670,23 +667,6 @@ Κρυφό αναδυόμενο παράθυρο Διαχειριζόμενα cookies - - Δικαιώματα ιστότοπου - Οι ιστότοποι που επισκέπτεστε ενδέχεται να ζητήσουν πρόσβαση στην τοποθεσία, την κάμερα, το μικρόφωνο ή το λογισμικό DRM (Διαχείριση ψηφιακών δικαιωμάτων) της συσκευής σας. Δεν θα μπορούν να έχουν πρόσβαση σε αυτά εάν δεν τους παρέχετε ρητά την άδειά σας. - Να επιτρέπεται σε όλους τους ιστότοπους να αιτούνται: - Τοποθεσία - Κάμερα - Μικρόφωνο - Διαχείριση ιστότοπων - Δεν υπάρχουν ακόμη ιστότοποι - Τα δικαιώματα καταργήθηκαν για όλους τους ιστότοπους - Δικαιώματα για «%1$s» - Να γίνεται ερώτηση κάθε φορά - Απόρριψη - Αποδοχή - Απενεργοποιήθηκε για όλους τους ιστότοπους - %1$s άδεια για %2$s - Ανακαλύψτε πότε είναι έτοιμες οι λήψεις Λάβετε ειδοποίηση όταν ολοκληρωθούν οι λήψεις. diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2fbf71f3e3b7..6d7a8b9c355a 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -192,6 +192,7 @@ Protección de rastreo en la web La protección de rastreo en la web está habilitada Más información]]> + Learn More]]> Protección contra ventanas emergentes de cookies @@ -200,6 +201,7 @@ Fire Button + Data Clearing Permisos @@ -211,6 +213,7 @@ Guardar Borrar automáticamente… + Automatically Clear Data… Borrar automáticamente… Ninguno Pestañas @@ -227,8 +230,10 @@ Acerca de DuckDuckGo + About Bienvenidas al \"Lado Pato\"! DuckDuckGo es la empresa de privacidad en internet independiente fundada en 2008 para quienes estén cansados de ser rastreados en línea y quieran una solución sencilla. Somos la prueba de que es posible obtener protección de privacidad real en línea sin concesiones.\n\nEl navegador DuckDuckGo incluye las funciones que esperas de un navegador de referencia, como favoritos, pestañas, contraseñas y más, así como más de una docena de potentes funciones de protección de privacidad que no ofrecen los navegadores más populares de forma predeterminada. Este conjunto completo de funciones de protección de privacidad ayuda a proteger tu actividad en línea, desde la búsqueda hasta la navegación, el correo electrónico y mucho más.\n\nNuestra protección de privacidad funciona sin necesidad de conocimientos técnicos y sin tener que lidiar con configuraciones complicadas. Lo único que tienes que hacer es cambiar el navegador a DuckDuckGo en todos tus dispositivos y obtener privacidad de forma predeterminada.\n\nSin embargo, si quieres conocer los entresijos, puedes encontrar más información sobre cómo funciona la protección de privacidad de DuckDuckGo en nuestras páginas de ayuda + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages No hay sugerencias @@ -260,14 +265,6 @@ Ver lo enviado "La información enviada en los informes no se puede usar para identificarte:

• URL de la página (sin información identificable)
• Marca, modelo y fabricante del dispositivo
• Número de versión del sistema operativo
• Número de versión de la aplicación
• Grupo de experimento anónimo para pruebas de funciones
• Información sobre qué versiones de nuestras protecciones estaban activas
• Número de versión del motor del navegador web
• Lista de las protecciones y funciones del navegador que estaban activas
• Nombres de host de rastreadores bloqueados, solicitudes de sustitución, solicitudes ignoradas y solicitudes que no están en la lista de bloqueo de rastreadores
• Errores notificados por el navegador
• Códigos de estado de respuesta del sitio web (HTTP)
• Qué formulario de informes se ha utilizado (menú, panel de control, etc.).
• Fecha del último informe enviado para este sitio
• Si has optado o no por mostrar esta información del informe
• Número de veces que se han desactivado las protecciones
• La rapidez con la que se han cargado partes de la página
• Cómo has llegado a esta página, ya sea: SERP (búsqueda de DuckDuckGo), Navegación (enlace/URL) o Externo (otros medios)
• Número de actualizaciones desde la carga de la página
• Idioma principal y país de tu dispositivo
]]>"
- - Confirmar - Guardar - Eliminar - Editar - Eliminar - Eliminar todo - Buscar en DuckDuckGo @@ -670,23 +667,6 @@ Ventana emergente oculta Cookies gestionadas - - Permisos del sitio - Los sitios que visites pueden pedirte acceso a la ubicación de tu dispositivo, a la cámara, al micrófono o al software DRM (Gestión de Derechos Digitales). No podrán acceder a ellos a menos que les des permiso explícitamente. - Permitir que todos los sitios soliciten: - Ubicación - Cámara - Micrófono - Administrar sitios - Aún no hay sitios - Permisos eliminados para todos los sitios - Permisos para \"%1$s\" - Preguntar cada vez - Rechazar - Permitir - Desactivado para todos los sitios - %1$s permiso para %2$s - Entérate de cuándo están listas las descargas Recibe una notificación cuando se completen las descargas. diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 027c5d79b7f5..0f050b0aa069 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -192,6 +192,7 @@ Veebijälgimise kaitse Veebijälgimise kaitse on lubatud Lisateave]]> + Learn More]]> Küpsiste hüpikakna kaitse @@ -200,6 +201,7 @@ Fire Button + Data Clearing Load @@ -211,6 +213,7 @@ Salvesta Kustuta automaatselt… + Automatically Clear Data… Kustuta automaatselt… Puudub Vahelehed @@ -227,8 +230,10 @@ DuckDuckGo\'st + About Tere tulemast Pardipoolele! DuckDuckGo on 2008. aastal asutatud sõltumatu internetiprivaatsuse ettevõte igaühele, kellel on kõrini varjatud jälgimisest internetis ja kes soovib lihtsat lahendust selle vältimiseks. Me oleme tõestuseks, et internetis on võimalik saada tõelist privaatsuskaitset ilma kompromisse tegemata.\n\nDuckDuckGo brauseril on kõik funktsioonid, mida sa brauserilt ootad, nagu järjehoidjad, vahekaardid, paroolid ja palju muud, lisaks sellele aga ka üle tosina võimsa privaatsuskaitse funktsiooni, mida enamik populaarsemaid brausereid vaikimisi ei paku. See ainulaadselt terviklik privaatsuskaitse aitab kaitsta sinu tegevust internetis alates otsingutest kuni sirvimiseni, meilide saatmiseni ja palju muuni.\n\nMeie privaatsuskaitse toimib ilma, et peaks teadma midagi tehnilistest nüanssidest või tegelema keeruliste seadistustega. Ainus, mis sa pead tegema, on vahetada oma brauser kõigis seadmetes DuckDuckGo vastu – ja vaikeprivaatsus ongi tagatud.\n\nKui aga soovid piiluda kapoti alla, leiad lisateavet DuckDuckGo privaatsuskaitse tööpõhimõtete kohta meie abilehtedelt + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Ettepanekud puuduvad @@ -260,14 +265,6 @@ Vaata, mida saadetakse "Aruannetes saadetud teavet ei saa kasutada sinu tuvastamiseks:

• lehekülje URL (ilma tuvastatava teabeta)
• seadme mark, mudel ja tootja
• operatsioonisüsteemi versiooni number
• rakenduse versiooni number
• anonüümne katserühm funktsioonide testimiseks
• teave selle kohta, millised meie kaitsete versioonid olid aktiivsed
• veebibrauseri versiooni number
• aktiivsete kaitsete ja brauseri funktsioonide loend
• blokeeritud jälgurite hostinimed, asendustaotlused, ignoreeritud taotlused ja päringud, mis pole jälguri blokeerimisloendis
• brauseri poolt teatatud tõrked
• veebilehe vastuse oleku (HTTP) koodid
• millist aruandlusvormi sa kasutasid (menüü, juhtpaneel jne)
• selle saidi kohta saadetud viimase aruande kuupäev
• kas valisid selle aruande teabe kuvamise või mitte
• kaitsete väljalülitamise kordade arv
• kui kiiresti lehe osad laadisid
• mille abil sellele lehele jõudsid, kas: SERP (DuckDuckGo otsing), navigeerimine (link/URL) või väline (muud vahendid)
• värskenduste arv alates lehe laadimisest
• sinu seadme peamine keel ja riik
]]>"
- - Kinnita - Salvesta - Kustuta - Redigeeri - Eemaldage - Eemalda kõik - DuckDuckGo otsing @@ -670,23 +667,6 @@ Hüpikaken on peidetud Hallatavad küpsised - - Saidi load - Külastatavad veebisaidid võivad küsida juurdepääsu sinu seadme asukohale, kaamerale, mikrofonile või DRM-i (Digital Rights Management) tarkvarale. Need ei saa juurdepääsu enne, kui oled selleks andnud selgesõnalise loa. - Luba kõigil saitidel küsida järgmist. - Asukoht - Kaamera - Mikrofon - Saitide haldamine - Saite pole veel - Kõikide saitide load on eemaldatud - Saidi „%1$s“ load - Küsi iga kord - Keela - Luba - Kõigi saitide jaoks keelatud - Luba %1$s saidile %2$s - Teata, kui allalaadimised valmis saavad Kui allalaadimine on lõpule jõudnud, saad teavituse. diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 06e5e74e78e8..f6603cea34ef 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -192,6 +192,7 @@ Verkkoseurannan suojaus Verkkoseurantasuojaus on käytössä Lisätietoja]]> + Learn More]]> Evästeiden ponnahdusikkuna -suojaus @@ -200,6 +201,7 @@ Fire-painike + Data Clearing Käyttöoikeudet @@ -211,6 +213,7 @@ Tallenna Tyhjennä automaattisesti… + Automatically Clear Data… Tyhjennä automaattisesti… Ei mitään Välilehdet @@ -227,8 +230,10 @@ Tietoa DuckDuckGo:sta + About Tervetuloa Duckin puolelle! DuckDuckGo on vuonna 2008 perustettu riippumaton internetissä tietosuojaa tarjoava yritys niille, jotka ovat kyllästyneet siihen, että heitä seurataan netissä, ja haluavat yksinkertaisen ratkaisun. Olemme todiste siitä, että voit saada todellista tietosuojaa verkossa ilman kompromisseja.\n\nDuckDuckGo-selaimessa on kaikki parhaiden selainten ominaisuudet, kuten kirjanmerkit, välilehdet, salasanat ja paljon muuta, sekä yli kymmenkunta tehokasta tietosuojausta, joita ei ole oletuksena useimmissa suosituissa selaimissa. Tämä ainutlaatuisen kattava tietosuoja auttaa turvaamaan haut, selaamisen, sähköpostin lähettämiseen ja muun toimintasi verkossa.\n\nTietosuojamme toimivat, vaikka et tietäisi mitään teknisistä yksityiskohdista tai osaisi käsitellä monimutkaisia asetuksia. Sinun tarvitsee vain vaihtaa selaimesi DuckDuckGohon kaikilla laitteillasi, ja saat tietosuojan oletuksena.\n\nJos kuitenkin haluat kurkistaa konepellin alle, lisätietoja DuckDuckGon tietosuojan toiminnasta on ohjesivuillamme. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Ei ehdotuksia @@ -260,14 +265,6 @@ Katso, mitä on lähetetty "Raporteissa lähetetyistä tiedoista ei voi tunnistaa sinua:

• Sivun URL-osoite (ilman tunnistettavia tietoja)
• Laitteen merkki, malli ja valmistaja
• Käyttöjärjestelmän versionumero
• Sovelluksen versionumero
• Nimetön kokeiluryhmä ominaisuuksien testaamista varten
• Tietoa suojauksiemme aktiivisista versioista
• Verkkoselainhakukoneen versionumero
• Luettelo aktiivisista suojauksista ja selaimen ominaisuuksista
• Estettyjen seurantatoimintojen isäntänimet, korvaavat pyynnöt, huomiotta jätetyt pyynnöt ja pyynnöt, jotka eivät ole seurannan estoluettelossa
• Selaimen ilmoittamat virheet
• Web-sivuston vastaustilan (HTTP) koodit
• Mitä ilmoituslomaketta käytit (valikko, hallintapaneeli jne.)
• Tämän sivuston viimeisen raportin lähetyspäivämäärä
• Oletko valinnut tämän raportin tietojen näyttämisen vai et
• Suojausten poiskytkeytymiskerrat
• Kuinka nopeasti osat sivusta latautuivat
• Miten pääsit tälle sivulle, joko: SERP (DuckDuckGo-haku), navigointi (linkki/URL) tai ulkoinen (muu keino)
• Päivitysten määrä sivun latauksen jälkeen
• Laitteesi ensisijainen kieli ja maa
]]>"
- - Vahvista - Tallenna - Poista - Muokkaa - Poista - Poista kaikki - Hae DuckDuckGosta @@ -670,23 +667,6 @@ Ponnahdusikkuna piilotettu Hallitut evästeet - - Sivuston käyttöoikeudet - Käyttämäsi sivustot saattavat pyytää pääsyä laitteesi sijaintiin, kameraan, mikrofoniin tai DRM-ohjelmistoon (Digital Rights Management). Ne eivät voi käyttää tietoja, ellet myönnä niille erillistä käyttöoikeutta. - Salli kaikkien sivustojen pyytää: - Sijainti - Kamera - Mikrofoni - Hallitse sivustoja - Ei vielä yhtään sivustoa - Käyttöoikeudet poistettu kaikilta sivustoilta - Oikeudet: %1$s - Kysy joka kerta - Estä - Salli - Poistettu käytöstä kaikilla sivustoilla - %1$s: käyttöoikeus – lupa %2$s - Saat tietää, milloin lataukset ovat valmiita Saat ilmoituksen, kun lataukset ovat valmiita. diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 81718179a259..54ccc021f15d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -192,6 +192,7 @@ Protection contre le pistage sur le Web La protection contre le pistage sur le Web est activée En savoir plus]]> + Learn More]]> Protection contre les fenêtres contextuelles des cookies @@ -200,6 +201,7 @@ Fire Button + Data Clearing Autorisations @@ -211,6 +213,7 @@ Enregistrer Effacer automatiquement… + Automatically Clear Data… Effacer automatiquement… Aucune Onglets @@ -227,8 +230,10 @@ À propos de DuckDuckGo + About Bienvenue du côté Duck ! DuckDuckGo est une société indépendante de confidentialité sur internet fondée en 2008, destinée à tous ceux qui en ont assez d\'être suivis en ligne et qui veulent une solution simple. Nous sommes la preuve que vous pouvez bénéficier d\'une véritable protection de la confidentialité en ligne, sans avoir à faire de compromis.\n\nLe navigateur DuckDuckGo est doté des fonctionnalités que vous attendez d\'un navigateur de référence, comme les signets, les onglets et les mots de passe, entre autres, auxquels s\'ajoutent plus d\'une douzaine de protections puissantes de la confidentialité que la plupart des navigateurs populaires ne proposent pas par défaut.Cet ensemble unique et complet de protections de la confidentialité permet de préserver vos activités en ligne, de la recherche à la navigation, en passant par l\'envoi d\'e-mails, etc.\n\nInutile de s\'y connaître en détails techniques ou de gérer des paramètres complexes pour faire fonctionner nos protections de la confidentialité. Il vous suffit d\'opter pour le navigateur DuckDuckGo sur tous vos appareils afin de pouvoir bénéficier de la confidentialité par défaut.\n\nMais si vous voulez vous faire une idée, vous trouverez plus d\'informations sur le fonctionnement des protections de la confidentialité DuckDuckGo sur nos pages d\'aide + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Aucune suggestion @@ -260,14 +265,6 @@ Voir ce qui est envoyé "Les informations envoyées dans les rapports ne peuvent pas être utilisées pour vous identifier :

• URL de la page (sans informations d'identification)
• Marque, modèle et fabricant de l'appareil
• Numéro de version du système d'exploitation
• Numéro de version de l'application
• Groupe d'expérimentation anonyme pour les tests de fonctionnalités
• Informations sur les versions de nos protections qui étaient actives
• Numéro de version du moteur du navigateur Web
• Liste des protections et des fonctionnalités du navigateur qui étaient actives
• Noms d'hôte des traqueurs bloqués, demandes de substitution, demandes ignorées et demandes ne figurant pas dans la liste des blocages de traqueurs
• Erreurs signalées par le navigateur
• Codes HTTP (Website Response Status)
• Le formulaire de signalement que vous avez utilisé (menu, tableau de bord, etc.)
• Date du dernier rapport envoyé pour ce site
• Si vous avez choisi ou non d'afficher ces informations de signalement
• Nombre de fois où les protections ont été désactivées
• Vitesse de chargement de différentes parties de la page
• Comment vous avez accédé à cette page, soit : SERP (recherche DuckDuckGo), Navigation (lien/URL) ou Externe (autres moyens)
• Nombre d'actualisations depuis le chargement de la page
• Langue principale et pays de votre appareil
]]>"
- - Confirmer - Enregistrer - Supprimer - Modifier - Supprimer - Tout supprimer - Rechercher avec DuckDuckGo @@ -670,23 +667,6 @@ Fenêtre contextuelle masquée Cookies gérés - - Autorisations du site - Les sites que vous visitez sont susceptibles de demander l\'accès à la localisation, à l\'appareil photo, au micro ou au logiciel DRM (gestion des droits numériques) de votre appareil. Ils ne pourront y accéder que si vous leur en donnez explicitement la permission. - Autoriser tous les sites à demander : - Localisation - Appareil photo - Micro - Gérer les sites - Pas encore de sites - Autorisations supprimées pour tous les sites - Autorisations pour « %1$s » - Toujours demander - Refuser - Autoriser - Désactivé pour tous les sites - Autorisation de %1$s pour %2$s - Sachez quand les téléchargements sont prêts Recevez une notification lorsque les téléchargements sont terminés. diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 73692b0c2309..e3ed8bb26d06 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -192,6 +192,7 @@ Zaštita od praćenja na webu Zaštita od praćenja na webu je omogućena Saznaj više]]> + Learn More]]> Zaštita od skočnih prozora kolačića @@ -200,6 +201,7 @@ Fire Button + Data Clearing Dozvole @@ -211,6 +213,7 @@ Spremi Automatski obriši… + Automatically Clear Data… Automatski obriši… Nijedno Kartice @@ -227,8 +230,10 @@ O DuckDuckGou + About Dobrodošli na našu stranu! DuckDuckGo neovisna je tvrtka za privatnost na internetu osnovana 2008. godine namijenjena svakome tko je umoran od toga da ga prate na internetu i želi jednostavno rješenje za to. Mi smo dokaz da je prava zaštita privatnosti na internetu moguća bez kompromisa.\n\nPreglednik DuckDuckGo dolazi sa značajkama koje očekuješ od preglednika, poput oznaka, kartica, lozinki i još mnogo toga; ali uz to, pruža se više od desetak moćnih zaštita privatnosti koje se zadano ne nude u najpopularnijim preglednicima. Ovaj jedinstveno sveobuhvatan skup zaštite privatnosti pomaže u zaštiti tvojih mrežnih aktivnosti, od pretraživanja do pregledavanja, slanja e-pošte i još mnogo toga.\n\nNaša zaštita privatnosti funkcionira bez potrebe da znamo bilo što o tehničkim detaljima ili da se bavimo kompliciranim postavkama. Sve što trebaš učiniti jest prebaciti svoj preglednik na DuckDuckGo na svim svojim uređajima i prema zadanim postavkama dobivaš našu zaštitu privatnosti.\n\nAli ako želiš \"zaviriti ispod haube\", više informacija o tome kako DuckDuckGo zaštita privatnosti funkcionira možeš pronaći na našim stranicama pomoći + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Nema prijedloga @@ -260,14 +265,6 @@ Pogledaj što je poslano "Podaci poslani u izvješćima ne mogu se koristiti za tvoju identifikaciju:

• URL stranice (bez podataka pomoću kojih se možeš identificirati)
• Marka, model i proizvođač uređaja
• Broj verzije operativnog sustava
• Broj verzije aplikacije
• Anonimna eksperimentalna grupa za testiranje značajki
• Informacije o tome koje su verzije naših zaštita bile aktivne
• Broj verzije motora internetskog preglednika
• Popis aktivnih zaštita i značajki preglednika
• Blokirana imena domaćina alata za praćenje, zamjenski zahtjevi, zanemareni zahtjevi i zahtjevi koji nisu na popisu blokiranih alata za praćenje
• Pogreške koje je prijavio preglednik
• Kodovi statusa odgovora web-mjesta (HTTP)
• Koji je obrazac za izvješćivanje korišten (izbornik, nadzorna ploča itd.)
• Datum posljednjeg izvješća poslanog za ovo web-mjesto
• Je li odabrano prikazivanje ovih podataka o izvješću ili ne
• Koliko je puta zaštita isključena
• Koliko se brzo učitavaju dijelovi stranice
• Kako si došao do ove stranice, ili: SERP (DuckDuckGo pretraživanje), Navigacija (veza/URL) ili Vanjska (drugi način)
• Broj osvježavanja od učitavanja stranice
• Primarni jezik i zemlja tvog uređaja
]]>"
- - Potvrdi - Spremi - Izbriši - Uredi - Ukloni - Odstrani sve - Pretraži DuckDuckGo @@ -670,23 +667,6 @@ Skočni prozor je sakriven Upravlja se kolačićima - - Dozvole web lokacija - Stranice koje posjećuješ mogu tražiti pristup lokaciji tvog uređaja, fotoaparatu, mikrofonu ili DRM (Digital Rights Management) softveru. Neće im moći pristupiti osim ako im za to izričito ne daš dopuštenje. - Dopusti svim web-lokacijama da zatraže: - Lokacija - Kamera - Mikrofon - Upravljanje web-lokacijama - Još nema ni jedne web-lokacije - Uklonjena su dopuštenja za sve web lokacije - Dopuštenja za „%1$s“ - Pitaj svaki puta - Odbij - Dopusti - Onemogućeno za sva web-mjesta - %1$s dopuštenje za %2$s - Saznaj kad su preuzimanja spremna Primi obavijest kad se preuzimanja završe. diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 9cca0f781e73..ef40fe740b8b 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -192,6 +192,7 @@ Webes követés elleni védelem A webes követés elleni védelem engedélyezve van További részletek]]> + Learn More]]> Felugró sütiablak elleni védelem @@ -200,6 +201,7 @@ Tűz gomb + Data Clearing Engedélyek @@ -211,6 +213,7 @@ Mentés Automatikus törlés… + Automatically Clear Data… Automatikus törlés… Nincs Lapok @@ -227,8 +230,10 @@ A DuckDuckGóról + About Isten hozott a Kacsa oldalon! A 2008-ban alapított független internetes adatvédelmi cég, a DuckDuckGo egyszerű megoldást kínál azoknak, akiknek elegük van abból, hogy állandóan nyomon követik őket az interneten. Mi vagyunk annak a bizonyítéka, hogy kompromisszumok nélkül is lehet valódi online adatvédelmet biztosítani.\n\nA DuckDuckGo böngésző rendelkezik a böngészőktől elvárt funkciókkal, mint például könyvjelzők, lapok, jelszavak és egyéb funkciók, valamint több mint egy tucat olyan hatékony adatvédelmi megoldással, amelyet a legtöbb népszerű böngésző nem kínál alapértelmezés szerint. Ezek az egyedülállóan átfogó adatvédelmi megoldások segítenek megvédeni online tevékenységeid, legyen szó keresésről, böngészésről, e-mailezésről vagy sok minden másról.\n\nAdatvédelmi megoldásaink anélkül működnek, hogy bármit is tudnod kellene a technikai részletekről vagy bonyolult beállításokkal kellene foglalkoznod. Mindössze annyit kell tenned, hogy minden eszközödön a DuckDuckGo böngészőre váltasz, és máris igénybe veheted az alapértelmezés szerinti adatvédelmet.\n\nHa azonban szeretnél bepillantani a motorháztető alá is, a súgóoldalainkon további információkat találhatsz a DuckDuckGo adatvédelmi megoldásainak működéséről. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Nincs javaslat @@ -260,14 +265,6 @@ Elküldött adatok megtekintése "A jelentésekben elküldött adatok nem használhatók az azonosításodra:

• Oldal URL-címe (azonosítható adatok nélkül)
• Eszköz gyártmánya, típusa és gyártója
• Operációs rendszer verziószáma
• Alkalmazás verziószáma
• Funkciókat tesztelő névtelen kísérleti csoport
• Aktív védelmeink verziójával kapcsolatos információ
• Webböngészőmotor verziószáma
• Azon védelmek és böngészőfunkciók listája, melyek aktívak voltak
• A blokkolt nyomkövetők, helyettesítő kérések, figyelmen kívül hagyott kérések és a nyomkövetők blokkolási listáján nem szereplő kérések állomásnevei
• Böngésző által jelentett hibák
• Webhely válaszállapotának (HTTP) kódjai
• Általad használt jelentési űrlap („menü”, „vezérlőpult” stb.)
• A jelen webhelyről küldött utolsó jelentés időpontja
• Kérted-e vagy sem e jelentésben szereplő információk megjelenítését
• A védelmek kikapcsolásának száma
• Milyen gyorsan töltődtek be az oldal részei
• Miként jutottál el erre az oldalra, ami lehet: SERP (DuckDuckGo-keresés), Navigáció (link/URL-cím) vagy Külső (egyéb mód)
• Frissítések száma az oldal betöltése óta
• Az eszköz elsődleges nyelve és országa
]]>"
- - Megerősítés - Mentés - Törlés - Szerkesztés - Eltávolítás - Összes eltávolítása - Keresés a DuckDuckGo alkalmazásban @@ -670,23 +667,6 @@ Felugró ablak elrejtve Kezelt sütik - - Webhelyengedélyek - A meglátogatott webhelyek hozzáférést kérhetnek az eszköz helyéhez, kamerájához, mikrofonjához vagy a digitális jogosultságokat kezelő (DRM) szoftveréhez. Ezekhez nem férhetnek hozzá, hacsak nem adsz rá kifejezett engedélyt. - Minden webhely kérheti a következőket: - Hely - Kamera - Mikrofon - Webhelyek kezelése - Még nincsenek oldalak - Minden webhely engedélye eltávolítva - Engedélyek a következőhöz: „%1$s” - Kérdezzen rá minden alkalommal - Megtagadás - Engedélyezés - Letiltva minden webhely számára - %1$s engedély a(z) %2$s számára - Készen álló letöltések jelzése Értesítés a letöltések befejeződésekor. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 8308eec8ab05..3a82c16bd0ed 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -192,6 +192,7 @@ Protezione dal tracciamento web La protezione dal tracciamento Web è abilitata Ulteriori informazioni]]> + Learn More]]> Protezione pop-up dei cookie @@ -200,6 +201,7 @@ Fire Button + Data Clearing Autorizzazioni @@ -211,6 +213,7 @@ Salva Elimina automaticamente… + Automatically Clear Data… Elimina automaticamente… Nessuno Schede @@ -227,8 +230,10 @@ Info su DuckDuckGo + About Dax the Duck ti dà il benvenuto! Fondata nel 2008, DuckDuckGo è un\'azienda indipendente che tutela la privacy online per tutti coloro che sono stanchi di essere tracciati online e vogliono una soluzione semplice. Siamo la dimostrazione che si può garantire una vera protezione della privacy online senza compromessi.\n\nIl browser DuckDuckGo è ricco di funzioni essenziali come i segnalibri, le schede, le password e molto altro ancora, oltre a numerose e potenti protezioni della privacy che normalmente non vengono offerte dai browser più comuni. Stiamo parlando di uno straordinario set completo per la protezione della privacy, che aiuta a proteggere le attività online, dalla ricerca alla navigazione, alle e-mail e molto altro ancora.\n\nCon le nostre protezioni della privacy non è necessario conoscere particolari tecnici o dover affrontare configurazioni complesse. È sufficiente scegliere il browser DuckDuckGo su tutti i dispositivi personali per avere automaticamente garantita la privacy.\n\nPer saperne di più su come funzionano le protezioni della privacy di DuckDuckGo, è possibile consultare le nostre pagine di aiuto + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Nessun suggerimento @@ -260,14 +265,6 @@ Controlla cosa è stato inviato "Le informazioni inviate nei rapporti non possono essere utilizzate per identificarti:

• URL della pagina (senza informazioni identificabili)
• Marca, modello e produttore del dispositivo
• Numero di versione del sistema operativo
• Numero di versione dell'app
• Gruppo di sperimentazione anonimo per il test delle funzionalità
• Informazioni sulle versioni delle nostre protezioni che erano attive
• Numero di versione del motore del browser web
• Elenco di protezioni e funzionalità del browser che erano attive
• Nomi di host dei sistemi di tracciamento bloccati, richieste surrogate, richieste ignorate e richieste non presenti nell'elenco di blocco dei sistemi di tracciamento
• Errori segnalati dal browser
• Codici di stato della risposta del sito web (HTTP)
• Modulo di segnalazione utilizzato (menu, dashboard, ecc.)
• Data dell'ultimo rapporto inviato per questo sito
• Se hai scelto di mostrare le informazioni del report
• Numero di volte in cui le protezioni sono state disattivate
• Velocità di caricamento delle parti della pagina
• Come hai raggiunto questa pagina: SERP (ricerca DuckDuckGo), Navigazione (link/URL) o Esterno (altri mezzi)
• Numero di aggiornamenti dal caricamento della pagina
• Lingua principale e paese del tuo dispositivo
]]>"
- - Conferma - Salva - Elimina - Modifica - Rimuovi - Elimina tutto - Cerca con DuckDuckGo @@ -670,23 +667,6 @@ Popup nascosto Cookie gestiti - - Autorizzazioni del sito - I siti che visiti potrebbero richiedere l\'accesso al software di localizzazione, videocamera, microfono o DRM (Digital Rights Management) del tuo dispositivo. Non potranno accedervi finché non darai il consenso esplicito. - Consenti a tutti i siti di richiedere: - Posizione - Fotocamera - Microfono - Gestisci siti - Non esistono ancora siti - Autorizzazioni rimosse per tutti i siti - Autorizzazioni per \"%1$s\" - Chiedi ogni volta - Rifiuta - Consenti - Disattivato per tutti i siti - Autorizzazione %1$s per %2$s - Scopri quando i download sono pronti Ricevi una notifica al termine dei download. diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index fd193e7d9517..fc99c6757361 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -192,6 +192,7 @@ Apsauga nuo žiniatinklio sekimo Žiniatinklio sekimo apsauga įjungta Sužinokite daugiau]]> + Learn More]]> Apsauga nuo slapukų iškylančiųjų langų @@ -200,6 +201,7 @@ Mygtukas „Fire“ + Data Clearing Leidimai @@ -211,6 +213,7 @@ Išsaugoti Valyti automatiškai… + Automatically Clear Data… Valyti automatiškai… Jokie Kortelės @@ -227,8 +230,10 @@ Apie „DuckDuckGo“ + About Sveiki prisijungę prie „Duck“! „DuckDuckGo“ yra nepriklausoma interneto privatumo bendrovė, įkurta 2008 metais ir skirta visiems, kurie pavargo nuo sekimo internete ir nori lengvo sprendimo. Esame įrodymas, kad galite gauti tikrą privatumo apsaugą internete be kompromisų.\n\n„DuckDuckGo“ naršyklėje yra funkcijų, kurių tikitės iš pagrindinės naršyklės, pavyzdžiui, žymės, skirtukai, slaptažodžiai ir kt., taip pat daugiau nei tuzinas galingų privatumo apsaugos priemonių, kurios nesiūlomos daugumoje populiarių naršyklių. Šis unikalus išsamus privatumo apsaugos rinkinys padeda apsaugoti jūsų veiklą internete – nuo paieškos iki naršymo, el. pašto ir kt.\n\nMūsų privatumo apsaugos priemonės veikia nereikalaudamos nieko žinoti apie technines detales ar naudotis sudėtingais nustatymais. Tereikia visuose įrenginiuose perjungti naršyklę į „DuckDuckGo“ ir privatumas bus užtikrintas pagal numatytuosius nustatymus.\n\nTačiau jei norite daugiau informacijos apie tai, kaip veikia „DuckDuckGo“ privatumo apsaugos priemonės, žiūrėkite mūsų pagalbos puslapius. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Pasiūlymų nėra @@ -260,14 +265,6 @@ Žiūrėti, kas išsiųsta "Ataskaitose siunčiama informacija negali būti naudojama jūsų tapatybei nustatyti:

• puslapio URL (be identifikuojamos informacijos);
• įrenginio markė, modelis ir gamintojas;
• operacinės sistemos versijos numeris;
• programos versijos numeris;
• anoniminė eksperimentų grupė funkcijų testavimui;
• informacija apie tai, kurios apsaugos versijos buvo aktyvios;
• žiniatinklio naršyklės variklio versijos numeris;
• sąrašas, kurios apsaugos ir naršyklės funkcijos buvo aktyvios;
• užblokuotų stebėjimo priemonių, pakaitinių užklausų, ignoruojamų užklausų ir užklausų, kurios nėra stebėjimo priemonių blokavimo sąraše, prieglobos pavadinimai;
• naršyklės praneštos klaidos;
• svetainės atsako būsenos (HTTP) kodai;
• naudota ataskaitų teikimo forma (meniu, prietaisų skydelis ir kt.);
• paskutinio šios svetainės pranešimo siuntimo data;
• ar pasirinkote rodyti šio pranešimo informaciją, ar ne;
• apsaugos išjungimo kartų skaičius;
• kaip greitai įkeltos puslapio dalys;
• kaip patekote į šį puslapį: naudodami SERP („DuckDuckGo“ paieška), navigaciją (nuoroda / URL) ar išorinę priemonę (kitos priemonės);
• atnaujinimų skaičius nuo puslapio įkėlimo;
• pagrindinė jūsų įrenginio kalba ir šalis.
]]>"
- - Patvirtinti - Išsaugoti - Trinti - Redaguoti - Pašalinti - Pašalinti visus - Ieškoti „DuckDuckGo“ @@ -670,23 +667,6 @@ Iškylantysis langas paslėptas Slapukai valdomi - - Svetainės leidimai - Svetainėse, kuriose lankotės, gali būti prašoma prieigos prie jūsų įrenginio buvimo vietos, kameros, mikrofono arba DRM (skaitmeninių teisių valdymo) programinės įrangos. Jos negalės prie jų prisijungti, nebent aiškiai suteiksite joms leidimą. - Leisti visoms svetainėms prašyti: - Vieta - Fotoaparatas - Mikrofonas - Tvarkyti svetaines - Svetainių dar nėra - Pašalinti visų svetainių leidimai - Leidimai „%1$s“ - Klausti kiekvieną kartą - Atsisakyti - Leisti - Išjungta visose svetainėse - %1$s leidimas %2$s - Sužinokite, kada atsisiuntimai bus paruošti Gaukite pranešimą, kai atsisiuntimas bus baigtas. diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index d50f2fc25f72..43fe0f712888 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -192,6 +192,7 @@ Tīmekļa izsekošanas aizsardzība Ir iespējota tīmekļa izsekošanas aizsardzība Uzzināt vairāk]]> + Learn More]]> Sīkfailu uznirstošo logu aizsardzība @@ -200,6 +201,7 @@ Fire Button + Data Clearing Atļaujas @@ -211,6 +213,7 @@ Saglabāt Automātiski notīrīt… + Automatically Clear Data… Automātiski notīrīt… Nav Cilnes @@ -227,8 +230,10 @@ Par DuckDuckGo + About Sveicināti Duck pusē! DuckDuckGo ir neatkarīgs 2008. gadā dibināts interneta privātuma uzņēmums ikvienam, kam ir apnikusi izsekošana tiešsaistē un kas vēlas vienkāršu risinājumu. Mēs esam pierādījums tam, ka tiešsaistē var iegūt reālu privātuma aizsardzību bez kompromisiem.\n\nDuckDuckGo pārlūkprogrammā ir visas funkcijas, ko gaidi no sava pārlūka: grāmatzīmes, cilnes, paroles u.c., kā arī vairāk nekā desmit spēcīgu privātuma aizsardzības funkciju, kas nav pieejamas vairumā populārāko pārlūkprogrammu pēc noklusējuma. Šis unikāli visaptverošais privātuma aizsardzības komplekts palīdz aizsargāt tavas darbības tiešsaistē, sākot no meklēšanas līdz pārlūkošanai, e-pasta sūtīšanai u.c.\n\nMūsu privātuma aizsardzība darbojas vienmēr – tev nav jāpārzina sarežģīti tehniskie aspekti vai iestatījumi. Tev vienkārši jālieto DuckDuckGo pārlūks visās savās ierīcēs, un privātums būs tavs standarta risinājums.\n\nBet, ja vēlies paskatīties, kas lācītim vēderā, vairāk informācijas par to, kā darbojas DuckDuckGo privātuma aizsardzība, vari atrast mūsu palīdzības lapās + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Nav ieteikumu @@ -260,14 +265,6 @@ Skatīt, kas tiek nosūtīts "Ziņojumos nosūtīto informāciju nevar izmantot, lai tevi identificētu:

• Lapas URL (bez identificējamas informācijas)
• Ierīces marka, modelis un ražotājs
• Operētājsistēmas versijas numurs
• Lietotnes versijas numurs
• Anonīma eksperimentālā grupa funkciju testēšanai
• Informācija par to, kuras mūsu aizsardzības versijas bija aktīvas
• Tīmekļa pārlūkprogrammas meklētājsistēmas versijas numurs
• Saraksts ar aizsardzības un pārlūkprogrammas funkcijām, kas bija aktīvas
• Bloķēto izsekotāju resursdatoru nosaukumi, surogātu pieprasījumi, ignorētie pieprasījumi un pieprasījumi, kas nav iekļauti izsekotāju bloķēšanas sarakstā
• Pārlūkprogrammas ziņotās kļūdas
• Tīmekļa vietnes atbildes statusa (HTTP) kodi
• Kuru ziņojuma veidlapu izmantoji (“izvēlne”, “informācijas panelis” utt.)
• Datums, kurā tika nosūtīts pēdējais ziņojums par šo vietni
• Vai izvēlējies rādīt šo ziņojuma informāciju
• Aizsardzības izslēgšanas reižu skaits
• Cik ātri tika ielādētas lapas daļas
• Kā tu nonāci šajā lapā: SERP (DuckDuckGo meklēšana), Navigācija (saite/URL) vai Ārēji (citos veidos)
• Atsvaidzināšanas reižu skaits kopš lapas ielādes
• Tavas ierīces galvenā valoda un valsts
]]>"
- - Apstiprināt - Saglabāt - Dzēst - Rediģēt - Noņemt - Noņemt visu - Meklēt DuckDuckGo @@ -670,23 +667,6 @@ Uznirstošais logs paslēpts Pārvaldītie sīkfaili - - Vietnes atļaujas - Apmeklētās vietnes var pieprasīt piekļuvi tavas ierīces atrašanās vietai, kamerai, mikrofonam vai DRM (digitālā satura tiesību pārvaldības) programmatūrai. Tās nevarēs tiem piekļūt, ja vien īpaši nedosi attiecīgo atļauju. - Ļaut visām vietnēm prasīt: - Atrašanās vieta - Kamera - Mikrofons - Pārvaldīt vietnes - Vēl nav nevienas vietnes - Atļaujas ir noņemtas visām vietnēm - Atļaujas vietnei \"%1$s\" - Jautāt katru reizi - Liegt - Atļaut - Atspējots visām vietnēm - %1$s – atļauja vietnei %2$s - Uzzini, kad lejupielādes ir gatavas Saņem paziņojumu, kad lejupielāde ir pabeigta. diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index fdf46ed96af6..6419cd0cfa06 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -192,6 +192,7 @@ Beskyttelse mot nettsporing Nettsporingsbeskyttelse er aktivert Finn ut mer]]> + Learn More]]> Beskyttelse mot popup-vinduer om informasjonskapsler @@ -200,6 +201,7 @@ Fire Button + Data Clearing Tillatelser @@ -211,6 +213,7 @@ Lagre Tøm automatisk … + Automatically Clear Data… Tøm automatisk … Ingen Faner @@ -227,8 +230,10 @@ Om DuckDuckGo + About Velkommen til «the Duck Side»! DuckDuckGo er et uavhengig personvernselskap som ble grunnlagt i 2008, for alle som er lei av å bli sporet på nettet og vil ha en enkel løsning. Vi er beviset på at ekte personvern er mulig på nettet uten å fire på kravene.\n\nDuckDuckGo-nettleseren inneholder funksjonene du kan forvente deg av en vanlig nettleser, som bokmerker, faner, passord og lignende, samt en rekke kraftige personvernfunksjoner, som ikke tilbys som standard i de fleste populære nettleserne. Disse usedvanlig omfattende personvernfunksjonene bidrar til å beskytte nettaktivitetene dine, fra søk til surfing, e-poster med mer.\n\nPersonvernfunksjonene fungerer uten at du behøver å kunne noe om de tekniske detaljene eller forholde deg til kompliserte innstillinger. Det eneste du behøver å gjøre, er å bytte nettleser til DuckDuckGo på alle enhetene dine, så får du personvern som standard.\n\nMen hvis du vil ta en titt under panseret, finner du mer informasjon om hvordan DuckDuckGos personvern fungerer på våre hjelpesider + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Ingen forslag @@ -260,14 +265,6 @@ Se hva som er sendt "Informasjon som sendes i rapporter, kan ikke brukes til å identifisere deg:

• Side-URL (uten identifiserbar informasjon)
• Enhetens merke, modell og produsent
• Operativsystemets versjonsnummer
• Appens versjonsnummer
• Anonym eksperimentgruppe for funksjonstesting
• Informasjon om hvilke versjoner av beskyttelsene våre som var aktive
• Nettlesermotorens versjonsnummer
• Liste over hvilke beskyttelser og nettleserfunksjoner som var aktive
• Vertsnavn på blokkerte sporere, surrogatforespørsler, ignorerte forespørsler og forespørsler som ikke er på listen over sporingsblokkering
• Feil rapportert av nettleseren
• Nettstedets responsstatuskoder (HTTP)
• Hvilket rapportskjema du brukte (meny, dashbord osv.)
• Dato for siste rapport sendt for dette nettstedet
• Hvorvidt du valgte å vise denne rapportinformasjonen
• Antall ganger beskyttelse ble slått av
• Hvor raskt deler av siden ble lastet
• Hvordan du kom til denne siden, enten: SERP (DuckDuckGo-søk), navigasjon (lenke/URL) eller eksternt (på annen måte)
• Antall oppfriskninger siden siden ble lastet
• Enhetens hovedspråk og land
]]>"
- - Bekreft - Lagre - Slett - Rediger - Fjern - Fjern alle - Søk med DuckDuckGo @@ -670,23 +667,6 @@ Popup-vindu skjult Informasjonskapsler administrert - - Nettstedstillatelser - Nettsteder du besøker, kan be om tilgang til enhetens posisjon, kamera, mikrofon eller DRA-programvare (digital rettighetsadministrasjon). De får ikke tilgang til disse med mindre du uttrykkelig gir dem tillatelse. - Tillat alle nettsteder å be om: - Posisjon - Kamera - Mikrofon - Administrer nettsteder - Ingen nettsteder ennå - Tillatelser fjernet for alle nettsteder - Tillatelser for «%1$s» - Spør hver gang - Avvis - Tillat - Deaktivert for alle nettsteder - %1$stillatelse for %2$s - Finn ut når nedlastinger er klare Få et varsel når nedlastinger er fullført. diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 9cfc426638e0..6f66a126f11f 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -192,6 +192,7 @@ Bescherming tegen webtracking Bescherming tegen webtracking is ingeschakeld Meer informatie]]> + Learn More]]> Bescherming tegen cookiepop-ups @@ -200,6 +201,7 @@ Fire Button + Data Clearing Toestemmingen @@ -211,6 +213,7 @@ Opslaan Automatisch wissen… + Automatically Clear Data… Automatisch wissen… Geen Tabbladen @@ -227,8 +230,10 @@ Over DuckDuckGo + About Welkom bij de Duck kant! DuckDuckGo is het onafhankelijke internetprivacybedrijf, opgericht in 2008, voor iedereen die het beu is om online gevolgd te worden en daar een eenvoudige oplossing voor wil. Wij zijn het bewijs dat je privacy op internet écht beschermd kan worden zonder compromissen.\n\nDe DuckDuckGo-browser bevat alle functies die je van een gewone browser mag verwachten, zoals bladwijzers, tabbladen, wachtwoorden en meer, plus meer dan een dozijn krachtige functies voor privacybescherming die je standaard niet vindt in de populairste browsers. Deze unieke, uitgebreide privacybescherming helpt je online activiteiten te beschermen – of je nu zoekt, surft of mailt.\n\nJe hoeft niets te weten over de technische details of ingewikkelde instellingen om te profiteren van onze privacybescherming. Je hoeft alleen maar DuckDuckGo op al je apparaten te installeren en geniet dan standaard van privacy.\n\nWil je toch een kijkje nemen onder de motorkap? Op onze hulppagina\'s vind je meer informatie over hoe de privacybescherming van DuckDuckGo werkt. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Geen suggesties @@ -260,14 +265,6 @@ Bekijk wat er is verzonden "De in de rapporten verzonden informatie kan niet worden gebruikt om je te identificeren:

• URL van de pagina (zonder identificeerbare info)
• Merk, model en fabrikant van het apparaat
• Versienummer van het besturingssysteem
• Versienummer van de app
• Anonieme experimentgroep voor het testen van functies
• Informatie over welke versies van onze beveiligingen actief waren
• Versienummer van de webbrowser-engine
• Lijst met welke beveiligingen en browserfuncties actief waren
• Hostnamen van geblokkeerde trackers, surrogaatverzoeken, genegeerde verzoeken en verzoeken die niet in de lijst met geblokkeerde trackers staan
• Door de browser gerapporteerde fouten
• Responsstatuscodes van websites (HTTP)
• Welk rapportageformulier je hebt gebruikt (menu, dashboard, enz.)
• Datum van het laatst verzonden rapport voor deze site
• Of je er wel of niet voor hebt gekozen om deze rapportgegevens te tonen
• Aantal keren dat beveiligingen zijn uitgeschakeld
• Hoe snel delen van de pagina zijn geladen
• Hoe je op deze pagina bent gekomen, ofwel: SERP (DuckDuckGo-zoekopdracht), Navigatie (link/URL), of Extern (andere middelen)
• Aantal vernieuwingen sinds het laden van de pagina
• Primaire taal en land van je apparaat
]]>"
- - Bevestigen - Opslaan - Verwijderen - Bewerken - Verwijderen - Alles verwijderen - Zoek in DuckDuckGo @@ -670,23 +667,6 @@ Pop-up verborgen Beheerde cookies - - Sitetoestemmingen - Sites die je bezoekt, kunnen toegang vragen tot de software, je camera, je microfoon of DRM (Digital Rights Management) op je apparaat. Ze krijgen die toegang alleen als je daar expliciet toestemming voor geeft. - Sta alle sites toe om het volgende vragen: - Locatie - Camera - Microfoon - Sites beheren - Nog geen sites - Toestemmingen verwijderd voor alle sites - Toestemmingen voor \'%1$s\' - Elke keer vragen - Weigeren - Toestaan - Uitgeschakeld voor alle sites - Toestemming voor %1$s voor %2$s - Blijf op de hoogte van downloads Ontvang een melding wanneer downloads zijn voltooid. diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 5e2057e91863..d93adc2d3e9d 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -192,6 +192,7 @@ Ochrona przed śledzeniem w sieci Ochrona przed śledzeniem w sieci jest włączona Dowiedz się więcej]]> + Learn More]]> Ochrona przed wyskakującymi okienkami dotyczącymi plików cookie @@ -200,6 +201,7 @@ Przycisk zabezpieczenia + Data Clearing Uprawnienia @@ -211,6 +213,7 @@ Zapisz Usuwaj automatycznie… + Automatically Clear Data… Usuwaj automatycznie… Brak Karty @@ -227,8 +230,10 @@ O DuckDuckGo + About Witaj po Kaczej Stronie Mocy! DuckDuckGo to założona w 2008 roku niezależna firma zajmująca się prywatnością w Internecie dla osób, które mają dosyć śledzenia online i poszukują łatwego w obsłudze rozwiązania. Jesteśmy dowodem na to, że możesz uzyskać prawdziwą ochronę prywatności online bez kompromisów.\n\nWszechstronna przeglądarka DuckDuckGo jest wyposażona w funkcje, których potrzebujesz, takie jak zakładki, karty, hasła i inne, a także kilkanaście zaawansowanych mechanizmów ochrony prywatności, które nie są domyślnie oferowane w większości popularnych przeglądarek. Ten wyjątkowo zaawansowany zestaw mechanizmów ochrony prywatności pomaga chronić działania w Internecie, od wyszukiwania po przeglądanie, obsługę wiadomości e-mail i nie tylko.\n\nDo korzystania z mechanizmów ochrony prywatności nie jest wymagana znajomość szczegółów technicznych ani skomplikowane ustawienia. Aby uzyskać ochronę prywatności, wystarczy ustawić na wszystkich urządzeniach domyślną przeglądarkę DuckDuckGo.\n\nJeśli interesują Cię szczegóły techniczne, więcej informacji o działaniu mechanizmów ochrony prywatności DuckDuckGo można znaleźć na stronach pomocy + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Brak sugestii @@ -260,14 +265,6 @@ Zobacz, co wysłano "Informacje przesyłane w raportach nie mogą zostać wykorzystane do Twojej identyfikacji:

• Adres URL strony (bez informacji umożliwiających identyfikację)
• Marka, model i producent urządzenia
• Numer wersji systemu operacyjnego
• Numer wersji aplikacji
• Anonimowa grupa eksperymentalna do testowania funkcji
• Informacje o tym, które wersje naszych zabezpieczeń były aktywne
• Numer wersji silnika przeglądarki internetowej
• Lista zabezpieczeń i funkcji przeglądarki, które były aktywne
• Nazwy hostów zablokowanych mechanizmów śledzących, żądań zastępczych, ignorowanych żądań i żądań, których nie ma na liście blokowanych mechanizmów śledzących
• Błędy zgłoszone przez przeglądarkę
• Kody stanu odpowiedzi witryny (HTTP)
• Wykorzystany sposób raportowania (menu, panel itp.)
• Data ostatniego wysłania raportu dla tej witryny
• Czy wyrażono zgodę na wyświetlanie informacji o tym raporcie
• Liczba wyłączeń zabezpieczeń
• Szybkość ładowania elementów strony
• Sposób przejścia do tej witryny: „SERP” (wyszukiwanie DuckDuckGo), „Nawigacja” (link/URL), lub „Zewnętrzne” (inne sposoby)
• Liczba odświeżeń od załadowania strony
• Podstawowy język i kraj urządzenia
]]>"
- - Potwierdź - Zapisz - Usuń - Edytuj - Usuń - Usuń wszystko - Szukaj w DuckDuckGo @@ -670,23 +667,6 @@ Ukryte wyskakujące okienka Zarządzane pliki cookie - - Uprawnienia witryny - Strony, które odwiedzasz, mogą prosić o dostęp do lokalizacji urządzenia, kamery, mikrofonu lub oprogramowania DRM (Digital Rights Management). Nie będą miały do nich dostępu, jeśli nie udzielisz im zgody. - Pozwól wszystkim stronom prosić o: - Lokalizacja - Aparat - Mikrofon - Zarządzaj witrynami - Nie masz jeszcze witryn - Usunięto uprawnienia wszystkich witryn - Uprawnienia dla: „%1$s” - Pytaj za każdym razem - Odmów - Zezwól - Wyłączono dla wszystkich witryn - Pozwolenie dla witryny %2$s na dostęp do urządzenia: %1$s - Dowiedz się, kiedy pliki do pobrania będą gotowe Otrzymuj powiadomienie po zakończeniu pobierania. diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index bf9bf6ea6755..a3471869a360 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -192,6 +192,7 @@ Proteção contra rastreamento na internet A proteção contra rastreamento na Internet está ativada Sabe mais]]> + Learn More]]> Proteção contra pop-ups de cookies @@ -200,6 +201,7 @@ Botão de proteção + Data Clearing Permissões @@ -211,6 +213,7 @@ Guardar Limpar automaticamente… + Automatically Clear Data… Limpar automaticamente… Nenhum Separadores @@ -227,8 +230,10 @@ Sobre o DuckDuckGo + About Bem-vindo ao Duck Side! A DuckDuckGo é a empresa independente de privacidade na Internet fundada em 2008 para quem está cansado de ser rastreado online e quer uma solução simples. Somos a prova de que podes proteger a tua privacidade online sem compromissos.\n\nO navegador DuckDuckGo vem com as funcionalidades que esperas num navegador de referência, como marcadores, separadores, palavras-passe, entre outras, além de mais de uma dúzia de proteções de privacidade poderosas que os navegadores mais populares não oferecem por predefinição. Este conjunto especialmente abrangente de proteções de privacidade ajuda a proteger as tuas atividades online, desde a pesquisa à navegação, e-mails, entre outras.\n\nPara utilizares as nossas proteções de privacidade, não tens de saber nada sobre os detalhes técnicos nem lidar com definições complicadas. Tudo o que tens de fazer é mudar o teu navegador para o DuckDuckGo em todos os teus dispositivos e desfrutar de privacidade como predefinição.\n\nMas, se quiseres espreitar os bastidores, podes consultar mais informações sobre como funcionam as proteções de privacidade do DuckDuckGo nas nossas páginas de ajuda + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Sem sugestões @@ -260,14 +265,6 @@ Vê o que foi enviado "As informações enviadas nos relatórios não podem ser utilizadas para te identificar:

• URL da página (sem informações identificáveis)
• Marca, modelo e fabricante do dispositivo
• Número da versão do sistema operativo
• Número da versão da aplicação
• Grupo de experiência anónimo para testagem de funcionalidades
• Informações sobre que versões das nossas proteções estavam ativas
• Número da versão do motor do navegador web
• Lista das proteções e funcionalidades do navegador que estavam ativas
• Nomes de anfitriões de rastreadores bloqueados, pedidos de substituição, pedidos ignorados e pedidos que não estão na lista de bloqueio de rastreadores
• Erros comunicados pelo navegador
• Códigos de estado de resposta do site (HTTP)
• Que forma de relatório utilizaste (menu, painel, etc.)
• Data do último relatório enviado para este site
• Se optaste ou não por mostrar esta informação do relatório
• Número de vezes que as proteções foram desativadas
• A rapidez com que partes da página foram carregadas
• Como chegaste a esta página: SERP (pesquisa DuckDuckGo), Navegação (link/URL), ou Externa (outros meios)
• Número de atualizações desde o carregamento da página
• Idioma principal e país do teu dispositivo
]]>"
- - Confirmar - Guardar - Eliminar - Editar - Remover - Remover tudo - Pesquisar no DuckDuckGo @@ -670,23 +667,6 @@ Pop-up ocultado Cookies geridos - - Permissões dos sites - Os sites que visitas podem pedir acesso à localização, câmara, microfone ou DRM (Digital Rights Management) do teu dispositivo. Não poderão aceder a estas funcionalidades sem que concedas permissão explicitamente. - Permitir que todos os sites peçam: - Localização - Câmara - Microfone - Gerir sites - Ainda não há sites - As permissões foram removidas para todos os sites - Permissões para \"%1$s\" - Pergunte todas as vezes - Recusar - Permitir - Desativado para todos os sites - Permissão para %2$s utilizar %1$s - Saber quando as transferências estão prontas Receba uma notificação quando as transferências estiverem concluídas. diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 5c424a32a7d0..e1e67455396a 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -192,6 +192,7 @@ Protecție împotriva urmăririi pe web Protecția împotriva urmăririi pe web este activată Află mai multe]]> + Learn More]]> Protecție pentru ferestre pop-up aferente modulelor cookie @@ -200,6 +201,7 @@ Butonul Foc + Data Clearing Permisiuni @@ -211,6 +213,7 @@ Salvează Ștergere automată… + Automatically Clear Data… Ștergere automată… Niciuna File @@ -227,8 +230,10 @@ Despre DuckDuckGo + About Welcome to the Duck Side! DuckDuckGo este o companie independentă înființată în 2008, care oferă confidențialitate pe internet pentru toți cei care s-au săturat să fie urmăriți online și doresc o soluție simplă.Suntem dovada că protecția confidențialității online fără compromisuri este reală.\n\nBrowserul DuckDuckGo oferă funcțiile la care vă așteptați de la browserul preferat, cum ar fi marcajele, filele, parolele și multe altele, plus peste o duzină de protecții ale confidențialității remarcabile, care nu sunt oferite implicit în majoritatea browserelor populare.Acest set unic și cuprinzător de măsuri de protecție a confidențialității vă ajută să vă protejați activitățile online, de la căutări la navigare, e-mailuri și multe altele.\n\nMăsurile noastre robuste de protecție a confidențialității funcționează fără a fi nevoie să cunoașteți detalii tehnice sau să aveți de-a face cu setări complicate.Tot ce trebuie să faceți este să folosiți browserul DuckDuckGo pe toate dispozitivele și veți beneficia automat de confidențialitate.\n\nDar dacă doriți să aflați detaliile din culise, puteți găsi mai multe informații despre modul în care funcționează protecțiile de confidențialitate DuckDuckGo pe paginile noastre de ajutor + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Fără sugestii @@ -260,14 +265,6 @@ Vezi ce se trimite "Informațiile trimise în rapoarte nu pot fi folosite pentru a te identifica:

• Adresa URL a paginii (fără informații identificabile)
• Marca, modelul și producătorul dispozitivului
• Numărul versiunii sistemului de operare
• Numărul versiunii aplicației
• Grup de experimente anonim pentru testarea funcționalităților
• Informații despre ce versiuni ale instrumentelor noastre de protecție au fost active
• Numărul versiunii motorului browserului
• Lista cu protecțiile și funcțiile browserului care erau active
• Numele de gazdă ale tehnologiilor de urmărire blocate, solicitările surogat, solicitările ignorate și solicitările care nu se află în lista de blocare a tehnologiilor de urmărire
• Erori raportate de browser
• Codurile pentru starea răspunsului site-ului (HTTP)
• Ce formular de raportare ai folosit (meniu, tablou de bord etc.)
• Data ultimului raport trimis pentru acest site
• Dacă ai ales sau nu să afișezi informațiile despre acest raport
• Numărul de dezactivări ale instrumentelor de protecție
• Cât de repede au fost încărcate anumite părți ale paginii
• Cum ai ajuns la această pagină, fie: SERP (căutare DuckDuckGo), navigare (link/URL) sau extern (alte mijloace)
• Numărul de reîmprospătări de la încărcarea paginii
• Limba principală și țara dispozitivului tău
]]>"
- - Confirmare - Salvare - Ștergere - Editare - Elimină - Elimină tot - Căutare DuckDuckGo @@ -670,23 +667,6 @@ Pop-up ascuns Modulele cookie au fost gestionate - - Permisiuni pentru site - Site-urile pe care le accesezi îți pot solicita accesul la locația dispozitivului, la camera foto, la microfon sau la software-ul DRM (Digital Rights Management). Acestea nu vor putea accesa aceste date decât dacă le oferi în mod explicit permisiunea. - Permite tuturor site-urilor să solicite: - Locație - Aparat foto - Microfon - Gestionează site-urile - Niciun site încă - Permisiuni eliminate pentru toate site-urile - Permisiuni pentru „%1$s” - Întreabă de fiecare dată - Refuză - Permite - Dezactivat pentru toate site-urile - Permisiune %1$s pentru %2$s - Află când sunt pregătite descărcările Primește o notificare când s-au finalizat descărcările. diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 0ffa6ec8817f..d7febdee7052 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -192,6 +192,7 @@ Защита от отслеживания онлайн Включена защита от отслеживания онлайн Подробнее...]]> + Learn More]]> Защита от всплывающих окон куки @@ -200,6 +201,7 @@ Кнопка «Тревога» + Data Clearing Разрешения @@ -211,6 +213,7 @@ Сохранить Автоматически сбрасывать… + Automatically Clear Data… Автоматически сбрасывать… Ничего Вкладки @@ -227,8 +230,10 @@ Несколько слов о DuckDuckGo + About Добро пожаловать на Утиную сторону! DuckDuckGo — основанная в 2008 году независимая компания, специализирующаяся на защите личных данных в Интернете. Мы предлагаем простое решение тем, кто хочет, чтобы за ними перестали следить онлайн. DuckDuckGo своим примером показывает, что защита конфиденциальности онлайн возможна без всяких компромиссов.\n\nВ универсальном браузере DuckDuckGo вы найдете все те же привычные функции — вкладки, закладки, пароли и многое другое, а также более десятка мощных средств защиты личной информации, которых нет в стандартных настройках других популярных веб-обозревателей . Такой исчерпывающий набор инструментов может скрыть от посторонних глаз всю сетевую активность, включая поиск, навигацию и почту.\n\nСредства защиты конфиденциальности не требуют от пользователей знания технических особенностей или понимания сложных настроек .Достаточно сменить свой браузер на DuckDuckGo на всех устройствах, и конфиденциальность станет вашим режимом по умолчанию.\n\nЕсли же вас интересует «подноготная», подробную информацию об особенностях защиты DuckDuckGo можно найти на страницах справки. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Нет предложений @@ -260,14 +265,6 @@ Что было отправлено "В отчет включаются следующие сведения (по которым невозможно установить вашу личность):

• адрес веб-страницы (без идентифицирующих данных);
• марка, модель и изготовитель устройства;
• номер операционной системы;
• номер версии приложения;
• анонимная экспериментальная группа для тестирования функций;
• версии задействованных функций защиты;
• номер версии движка браузера;
• список активных средств защиты и функций браузера;
• имена хостов заблокированных трекеров, суррогатные и проигнорированные запросы, а также запросы, не входящие в список блокировки трекеров;
• ошибки, зафиксированные браузером;
• коды состояния ответа сайта (HTTP);
• способ отправки отчета (через меню, панель управления и так далее);
• дата отправки последнего отчета по этому сайту;
• отметка о том, готовы ли вы раскрыть содержимое отчета;
• количество отключений функций защиты;
• скорость загрузки разных частей страницы;
• информация о том, как вы попали на данную страницу — через результаты поиска (в DuckDuckGo), путем навигации (по ссылке/URL-адресу) или иным (внешним) способом;
• количество обновлений страницы с момента ее загрузки;
• основной язык и регион вашего устройства.
]]>"
- - Подтвердить - Сохранить - Удалить - Редактировать - Удалить - Удалить все - Поиск в DuckDuckGo @@ -670,23 +667,6 @@ Всплывающее окно скрыто Kуки-файлы выбраны - - Разрешения для сайтов - Посещаемые вами сайты могут запрашивать доступ к геопозиции, камере, микрофону или программам DRM (защиты авторских прав) вашего устройства. Доступ предоставляется только с вашего разрешения. - Разрешить всем сайтам запрашивать: - Геопозиция - Камера - Микрофон - Управление сайтами - Пока нет сайтов - Разрешения удалены для всех сайтов - Разрешения для «%1$s» - Спрашивать каждый раз - Отказать - Разрешить - Отключено в отношении всех сайтов - Разрешение на доступ %2$s к %1$s - Уведомления о готовых загрузках Получайте уведомления по окончании загрузок. diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index ba6c8a7bf8b0..5b6cb48094d7 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -192,6 +192,7 @@ Ochrana pred sledovaním webu Ochrana pred sledovaním webu je povolená Zistiť viac]]> + Learn More]]> Ochrana proti automatickému otváraniu okien o súboroch cookie @@ -200,6 +201,7 @@ Tlačidlo Fire + Data Clearing Oprávnenia @@ -211,6 +213,7 @@ Uložiť Automaticky vymazať… + Automatically Clear Data… Automaticky vymazať… Žiadne Karty @@ -227,8 +230,10 @@ O DuckDuckGo + About Vitajte na Duck Side! DuckDuckGo je nezávislá spoločnosť na ochranu súkromia na internete založená v roku 2008 pre všetkých, ktorých už nebaví sledovanie na internete a chcú jednoduché riešenie. Sme dôkazom, že skutočnú online ochranu súkromia môžete získať bez kompromisov.\n\nPrehliadač DuckDuckGo je vybavený funkciami, ktoré očakávate od prehliadača, ako sú záložky, karty, heslá a ďalšie funkcie, a viac ako tuctom výkonných prvkov na ochranu súkromia, ktoré väčšina populárnych prehliadačov štandardne neponúka. Tento jedinečne komplexný súbor ochrany súkromia pomáha chrániť vaše online aktivity od vyhľadávania po prehliadanie, posielanie e-mailov a ďalšie.\n\nNaša ochrana súkromia funguje bez toho, aby ste museli poznať technické detaily alebo riešiť zložité nastavenia. Stačí prepnúť prehliadač na DuckDuckGo vo všetkých zariadeniach a získate predvolené súkromie.\n\nAk však máte záujem o podrobnejšie preskúmanie, viac informácií o tom, ako funguje ochrana súkromia v službe DuckDuckGo, nájdete na našich stránkach pomoci. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Žiadne návrhy @@ -260,14 +265,6 @@ Pozrite sa, čo bolo odoslané "Informácie odoslané v zostavách nie je možné použiť na vašu identifikáciu:

• Adresa URL stránky (bez identifikovateľných informácií)
• Značka, model a výrobca zariadenia
• Číslo verzie operačného systému
• Číslo verzie aplikácie
• Anonymná experimentálna skupina na testovanie funkcií
• Informácie o tom, ktoré verzie našich ochrán boli aktívne
• Číslo verzie webového prehliadača
• Zoznam aktívnych ochrán a funkcií prehliadača
• Názvy hostiteľov blokovaných sledovaní, žiadosti iných používateľovi, ignorované žiadosti a žiadosti, ktoré nie sú v zozname blokovania sledovačov
• Chyby nahlásené prehliadačom
• Kódy stavu odozvy webovej lokality (HTTP)
• Ktorý formulár zostáv ste použili (ponuka, informačný panel atď.)
• Dátum poslednej zostavy odoslanej pre túto lokalitu
• Či ste sa rozhodli zobraziť informácie o tejto zostave
• Koľkokrát boli ochrany vypnuté
• Ako rýchlo sa časti stránky načítali
• Ako ste sa dostali na túto stránku, buď: SERP (vyhľadávanie DuckDuckGo), Navigácia (odkaz/URL) alebo Externé (iné prostriedky)
• Počet obnovení od načítania stránky
• Primárny jazyk a krajina vášho zariadenia
]]>"
- - Potvrdiť - Uložiť - Vymazať - Upraviť - Odstrániť - Odstrániť všetky - Vyhľadať v DuckDuckGo @@ -670,23 +667,6 @@ Kontextové okno je skryté Spravované súbory cookie - - Oprávnenia na lokalitu - Stránky, ktoré navštívite, môžu požiadať o prístup k polohe vášho zariadenia, fotoaparátu, mikrofónu alebo softvéru DRM (Digital Rights Management). Nebudú mať k nim prístup, pokiaľ im to výslovne nepovolíte. - Povoliť všetkým lokalitám žiadať o: - Poloha - Kamera - Mikrofón - Správa lokalít - Zatiaľ žiadne lokality - Povolenia boli odstránené pre všetky lokality - Povolenia pre „%1$s” - Vždy sa opýtať - Odmietnuť - Povoliť - Zakázané pre všetky lokality - %1$s povolenie pre %2$s - Zistite, kedy budú stiahnuté súbory pripravené Dostávajte upozornenia po dokončení sťahovania. diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 928a708648d9..bab5f652e4d8 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -192,6 +192,7 @@ Zaščita pred spletnim sledenjem Zaščita spletnega sledenja je omogočena Več o tem]]> + Learn More]]> Zaščita pred pojavnimi okni piškotkov @@ -200,6 +201,7 @@ Gumb Fire Button + Data Clearing Dovoljenja @@ -211,6 +213,7 @@ Shrani Samodejno počisti … + Automatically Clear Data… Samodejno počisti … Brez Zavihki @@ -227,8 +230,10 @@ O DuckDuckGo + About Dobrodošli na strani Duck! DuckDuckGo je neodvisno podjetje za zasebnost v internetu, ustanovljeno leta 2008, in je namenjeno vsem, ki so naveličani sledenja v spletu in si želijo preproste rešitve. Dokazujemo, da je v spletu mogoče zagotoviti pravo zaščito zasebnosti brez sklepanja kompromisov.\n\nBrskalnik DuckDuckGo ima funkcije, ki jih pričakujete od priljubljenega brskalnika, kot so zaznamki, zavihki, gesla in drugo, ter več kot deset zmogljivih zaščit zasebnosti, ki jih večina priljubljenih brskalnikov ne ponuja privzeto. Ta edinstveni celovit sklop zaščite zasebnosti pomaga zaščititi vaše spletne dejavnosti, od iskanja do brskanja, pošiljanja e-pošte in še več.\n\nNaša zaščita zasebnosti deluje, ne da bi se vam bilo treba spoznati na tehnične podrobnosti ali se ukvarjati z zapletenimi nastavitvami. Vse, kar morate storiti, je, da brskalnik preklopite na DuckDuckGo v vseh napravah in zasebnost bo privzeta.\n\nČe pa želite pogledati v mehanizem delovanja, lahko več informacij o delovanju zaščite zasebnosti DuckDuckGo najdete na naših straneh s pomočjo. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Ni predlogov @@ -260,14 +265,6 @@ Oglejte si, kaj je poslano "Podatkov, poslanih v poročilih, ni mogoče uporabiti za vašo identifikacijo:

• URL strani (brez določljivih podatkov),
• znamka naprave, model in proizvajalec,
• številka različice operacijskega sistema,
• številka različice aplikacije,
• anonimna eksperimentalna skupina za testiranje funkcij,
• informacije o aktivnih različicah naših zaščit,
• številka različice pogona spletnega brskalnika,
• seznam aktivnih zaščit in funkcij brskalnika,
• imena gostiteljev blokiranih sledilnikov, nadomestne zahteve, prezrte zahteve in zahteve, ki niso na seznamu blokiranih sledilnikov,
• napake, ki jih je sporočil brskalnik,
• kode statusa odziva spletne strani (HTTP),
• kateri obrazec za poročanje ste uporabili (meni, nadzorna plošča itd.),
• datum zadnjega poslanega poročila za to spletno mesto,
• ali ste se odločili za prikaz informacij o tem poročilu,
• kolikokrat so bile zaščite izklopljene,
• kako hitro so bili naloženi deli strani,
• kako ste prišli do te strani: SERP (iskanje DuckDuckGo), navigacija (povezava/URL) ali zunanje (drugi načini),
• število osvežitev od nalaganja strani,
• primarni jezik in država vaše naprave.
]]>"
- - Potrdi - Shrani - Izbriši - Uredi - Odstrani - Odstrani vse - Poišči DuckDuckGo @@ -670,23 +667,6 @@ Pojavno okno je skrito Upravljani piškotki - - Dovoljenja za spletno mesto - Spletna mesta, ki jih obiščete, lahko zahtevajo dostop do lokacije, kamere, mikrofona ali programske opreme DRM (Digital Rights Management) vaše naprave. Do njih ne bodo mogla dostopati, razen če jim to izrecno dovolite. - Dovoli vsem mestom, da zahtevajo: - Lokacija - Kamera - Mikrofon - Upravljanje spletnih mest - Spletnih mest še ni - Dovoljenja so odstranjena za vsa spletna mesta - Dovoljenja za »%1$s« - Vprašaj vsakič - Zavrni - Dovoli - Onemogočeno za vsa spletna mesta - %1$s dovoljenje za %2$s - Ugotovite, kdaj so prenosi pripravljeni Prejmite obvestilo, ko so prenosi končani. diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index f3cb31b8747d..8b443f498634 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -192,6 +192,7 @@ Web Tracking Protection Skydd för webbspårning är aktiverat Mer information]]> + Learn More]]> Skydd mot popup-fönster för cookies @@ -200,6 +201,7 @@ Fire Button + Data Clearing Behörigheter @@ -211,6 +213,7 @@ Spara Autorensning … + Automatically Clear Data… Autorensning … Inga Flikar @@ -227,8 +230,10 @@ Om DuckDuckGo + About Välkommen till Duck-sidan! DuckDuckGo är det oberoende integritetsskyddsföretaget som grundades 2008 för alla som är trötta på att bli spårade online och vill ha en enkel lösning. Vi är beviset på att man kan få riktigt integritetsskydd på nätet utan att kompromissa.\n\nWebbläsaren DuckDuckGo har de funktioner man förväntar sig av en pålitlig webbläsare, som bokmärken, flikar, lösenord och mycket annat. Den har även ett tiotal kraftfulla integritetsskydd som inte erbjuds som standard i de flesta vanliga webbläsare. Den här omfattande uppsättningen av integritetsskydd hjälper dig att skydda dina onlineaktiviteter, från sökning och surfning till e-post och mycket mer.\n\nVårt integritetsskydd fungerar utan att du behöver känna till de tekniska detaljerna eller ta itu med komplicerade inställningar. Det enda du behöver göra är att byta webbläsare till DuckDuckGo på alla dina enheter för att få integritet som standard.\n\nMen om du vill ta en titt under huven, så finns det mer information om hur integritetsskyddet hos DuckDuckGo fungerar på våra hjälpsidor. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Inga förslag @@ -260,14 +265,6 @@ Se vad som skickats "Information som skickas i rapporter kan inte användas för att identifiera dig:

• Sidans URL (utan identifierbar information)
• Enhetens märke, modell och tillverkare
• Operativsystemets versionsnummer
• Appversionsnummer
• Anonym experimentgrupp för funktionstestning
• Information om vilka versioner av våra skydd som var aktiva
• Versionsnummer för webbläsarens motor
• Lista över vilka skydd och webbläsarfunktioner som var aktiva
• Värdnamn på blockerade spårare, surrogatförfrågningar, ignorerade förfrågningar och förfrågningar som inte finns i listan för spårningsblockering
• Webbläsarrapporterade fel
• HTTP-koder (webbplatsens svarsstatus)
• Vilken rapporteringsform du använde (meny, instrumentpanel osv.)
• Datum för den senaste rapport som skickades för webbplatsen
• Huruvida du valde att visa den här rapportinformationen
• Antal gånger som skydden har kopplats bort
• Hur snabbt delar av sidan lästes in
• Hur du kom till den här sidan, antingen: SERP (DuckDuckGo-sökning), Navigering (länk/URL) eller Externt (på annat sätt)
• Antal uppdateringar sedan sidan lästes in
• Primärt språk och land för din enhet
]]>"
- - Bekräfta - Spara - Ta bort - Redigera - Ta bort - Ta bort alla - Sök DuckDuckGo @@ -670,23 +667,6 @@ Popup-fönster dolt Cookies hanteras - - Webbplatsbehörigheter - Webbplatser som du besöker kan begära åtkomst till din enhets plats, kamera, mikrofon eller DRM-programvara (Digital Rights Management). De kan inte komma åt dessa om du inte uttryckligen tillåter det. - Tillåt alla webbplatser att be om: - Plats - Kamera - Mikrofon - Hantera webbplatser - Inga webbplatser ännu - Behörigheter har tagits bort för alla webbplatser - Behörigheter för %1$s - Fråga varje gång - Neka - Tillåt - Inaktiverat för alla webbplatser - %1$s-behörighet för %2$s - Få reda på när nerladdningar är klara Få ett meddelande när nerladdningar är klara. diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 19ce37cadbb0..f765dee9e5a4 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -192,6 +192,7 @@ Web İzleme Koruması Web İzleme Engelleyici Etkinleştirildi Daha fazla bilgi edin]]> + Learn More]]> Çerez Açılır Pencere Engelleyici @@ -200,6 +201,7 @@ Fire Button + Data Clearing İzinler @@ -211,6 +213,7 @@ Kaydet Otomatik Olarak Temizle... + Automatically Clear Data… Otomatik olarak temizle... Yok Sekmeler @@ -227,8 +230,10 @@ DuckDuckGo Hakkında + About Duck Side\'a hoş geldiniz! DuckDuckGo, çevrim içi takip edilmeyi hiç istemeyen ve pratik bir çözüm arayan herkese hizmet veren, 2008 yılında kurulmuş bağımsız bir İnternet gizlilik şirketidir. Biz, çevrim içi ortamda ödün vermeden gerçek gizlilik koruması elde edebileceğinizin kanıtıyız.\n\nDuckDuckGo tarayıcı; yer imleri, sekmeler, parolalar ve daha fazlası gibi bir tarayıcıdan beklediğiniz özelliklerin yanı sıra varsayılan olarak çoğu popüler tarayıcıda sunulmayan ondan fazla güçlü gizlilik koruması ile birlikte gelir. Son derece kapsamlı olan bu gizlilik koruma seti, aramadan gezinmeye, e-posta göndermeye ve daha fazlasına kadar çevrim içi etkinliklerinizde koruma sağlamaya yardımcı olur.\n\nGizlilik korumalarımız, teknik ayrıntılar hakkında hiçbir şey bilmenize veya karmaşık ayarlarla uğraşmanıza gerek kalmadan çalışır. Tüm cihazlarınızda tarayıcı olarak DuckDuckGo\'yu kullanarak aradığınız gizliliği sağlayabilirsiniz.\n\nAncak ayrıntılara göz atmak istiyorsanız, DuckDuckGo gizlilik korumalarının nasıl çalıştığıyla ilgili daha fazla bilgiyi yardım sayfalarımızdabulabilirsiniz. + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages Öneri yok @@ -260,14 +265,6 @@ Ne gönderildiğini gör "Raporlarda gönderilen bilgiler sizi tanımlamak için kullanılamaz:

• Sayfa URL'si (tanımlanabilir bilgiler olmadan)
• Cihaz markası, modeli ve üreticisi
• İşletim sistemi sürüm numarası
• Uygulama sürüm numarası
• Özellik testi için anonim deney grubu
• Korumalarımızın hangi sürümlerinin etkin olduğu hakkında bilgiler
• Web tarayıcı motoru sürüm numarası
• Hangi korumaların ve tarayıcı özelliklerinin etkin olduğunun listesi
• Engellenen izleyicilerin ana bilgisayar adları, yedek istekler, yok sayılan istekler ve izleyici engelleme listesinde olmayan istekler
• Tarayıcı tarafından bildirilen hatalar
• Web sitesi yanıt durumu (HTTP) kodları
• Hangi raporlama formunu kullandığınız (menü, kontrol paneli vb.)
• Bu site için gönderilen son raporun tarihi
• Bu rapor bilgisini göstermeyi seçip seçmediğiniz
• Korumaların kaç kez kapatıldığı
• Sayfanın bölümlerinin ne kadar hızlı yüklendiği
• Bu sayfaya nasıl ulaştığınız: SERP (DuckDuckGo araması), Gezinme (bağlantı/URL) veya Harici (diğer araçlar)
• Sayfanın yüklenmesinden bu yana yapılan yenileme sayısı
• Cihazınızın birincil dili ve ülkesi
]]>"
- - Onayla - Kaydet - Sil - Düzenle - Kaldır - Tümünü Kaldır - DuckDuckGo\'da Ara @@ -670,23 +667,6 @@ Açılır Pencere Gizli Yönetilen Çerezler - - Site İzinleri - Ziyaret ettiğiniz siteler cihazınızın konumuna, kamerasına, mikrofonuna veya DRM (Dijital Haklar Yönetimi) yazılımına erişim isteyebilir. Siz açıkça izin vermediğiniz sürece bunlara erişemezler. - Tüm sitelerin şunları istemesine izin ver: - Konum - Kamera - Mikrofon - Siteleri Yönet - Henüz site yok - Tüm Siteler İçin İzinler Kaldırıldı - \"%1$s\" için izinler - Her seferinde sor - Reddet - İzin ver - Tüm siteler için devre dışı - %2$s için %1$s izni - İndirmeler hazır olduğunda bildirim alın İndirmeler tamamlandığında bir bildirim alın. diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index c2fafd000233..a8438ccd8e0d 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -38,9 +38,6 @@ What site are you signing in to? (required) Site name (required) - - DRM - Could not access sound recorder Allow DuckDuckGo to ask for sound recorder access on this device diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 05fe9b410ec6..e5016e54ca41 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -264,14 +264,6 @@ See what\'s sent Info sent in reports can\'t be used to identify you:

• Page URL (without identifiable info)
• Device make, model, and manufacturer
• Operating system version number
• App version number
• Anonymous experiment group for feature testing
• Information about which versions of our protections were active
• Web browser engine version number
• List of which protections and browser features were active
• Hostnames of trackers blocked, surrogate requests, ignored requests, and requests not in tracker blocking list
• Browser-reported errors
• Website response status (HTTP) codes
• Which reporting form you used ("menu", "dashboard", etc.)
• Date of last report sent for this site
• Whether or not you opted to show this report info
• Number of times protections were toggled off
• How quickly parts of the page loaded
• How you got to this page, either: "SERP" (DuckDuckGo search), "Navigation" (link/URL), or "External" (other means)
• Number of refreshes since page load
• Primary language and country of your device
]]>
- - Confirm - Save - Delete - Edit - Remove - Remove All - Search DuckDuckGo @@ -674,23 +666,6 @@ Pop-up Hidden Cookies Managed - - Site Permissions - Sites you visit may ask for access to your device’s location, camera, microphone, or DRM (Digital Rights Management) software. They won’t be able to access these unless you explicitly give them permission. - Allow all sites to ask for: - Location - Camera - Microphone - Manage Sites - No sites yet - Permissions Removed for All Sites - Permissions for \"%1$s\" - Ask every time - Deny - Allow - Disabled for all sites - %1$s permission for %2$s - Find out when downloads are ready Get a notification when downloads complete. diff --git a/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml index da0f705874c8..0c8c4500bd9d 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Защита от изскачащи прозорци за бисквитки Научете повече]]> + Learn More]]> Позволете на DuckDuckGo да се погрижи за изскачащите прозорци за бисквитки \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml index 51d1dc1a99f1..b4b2661b1d69 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Ochrana před vyskakovacími okny ohledně cookies Další informace]]> + Learn More]]> Nech správu vyskakovacích oken ohledně cookie na DuckDuckGo \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml index ecf07884aaf0..a9337280c790 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Beskyttelse mod pop op-beskeder om cookies Lær mere]]> + Learn More]]> Lad DuckDuckGo håndtere pop op-beskeder om cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml index 242f9a07785d..5053c6bfd861 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Cookie-Pop-up-Schutz Mehr erfahren]]> + Learn More]]> Lass Cookie-Pop-ups von DuckDuckGo verwalten \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml index 91cb7107d825..0167027c5e6d 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Προστασία αναδυόμενων παραθύρων για cookies Μάθετε περισσότερα]]> + Learn More]]> Επιτρέψτε στο DuckDuckGo να διαχειρίζεται τα αναδυόμενα παράθυρα για cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml index f0359c60bcdc..afc320dc5d55 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Protección contra ventanas emergentes de cookies Más información]]> + Learn More]]> Deja que DuckDuckGo gestione las ventanas emergentes de cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml index 48a512755520..c398ee2a7674 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Küpsiste hüpikakna kaitse Lisateave]]> + Learn More]]> Lase DuckDuckGol küpsiste hüpikaknaid hallata \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml index beacafed26f2..171392945f45 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Evästeiden ponnahdusikkuna -suojaus Lue lisää]]> + Learn More]]> Anna DuckDuckGo hoitaa evästeiden ponnahdusikkunat \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml index f0158cf053ef..2c1f501bb5e2 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Protection contre les fenêtres contextuelles des cookies En savoir plus]]> + Learn More]]> Laisser DuckDuckGo gérer les fenêtres contextuelles des cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml index 800f8d2607cd..5b9723046215 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Zaštita od kolačića i skočnih prozora Saznaj više]]> + Learn More]]> Neka DuckDuckGo upravlja skočnim prozorima kolačića \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml index 010b092f9add..8c5052b8ac10 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Felugró sütiablak elleni védelem További részletek]]> + Learn More]]> A DuckDuckGo kezelje a felugró sütiablakokat \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml index 4a4ca618473c..6545f894ef03 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Protezione pop-up dei cookie Ulteriori informazioni]]> + Learn More]]> Lascia che DuckDuckGo gestisca i pop-up cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml index b32667ef344c..159e567520ad 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Apsauga nuo slapukų iškylančiųjų langų Sužinokite daugiau]]> + Learn More]]> Leiskite „DuckDuckGo“ tvarkyti slapukų iškylančiuosius langus \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml index b3f26fd4c3ee..d8482b77c129 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Sīkfailu uznirstošo logu aizsardzība Uzzināt vairāk]]> + Learn More]]> Ļauj DuckDuckGo apstrādāt sīkfailu uznirstošos logus \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml index 8bd53afb460b..264bba2ad6d6 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Beskyttelse mot popup-vinduer om informasjonskapsler Finn ut mer]]> + Learn More]]> La DuckDuckGo håndtere popup-vinduer om informasjonskapsler \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml index 96ea82587560..7befb6466160 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Bescherming tegen cookiepop-ups Meer informatie]]> + Learn More]]> Laat DuckDuckGo cookiepop-ups verwerken \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml index 3e75b19e32a3..8d3e4a79fd00 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Ochrona przed wyskakującymi okienkami dotyczącymi plików cookie Dowiedz się więcej]]> + Learn More]]> Pozwól DuckDuckGo zajmować się wyskakującymi okienkami plików cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml index dd849d0bde86..554917355673 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Proteção contra pop-ups de cookies Sabe mais]]> + Learn More]]> Permitir que o DuckDuckGo lide com pop-ups de cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml index e5c3ccd8cc07..855652fe9fd1 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Protecție pentru ferestre pop-up aferente modulelor cookie Află mai multe]]> + Learn More]]> Lasă DuckDuckGo să se ocupe de ferestrele pop-up aferente modulelor cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml index 2ec10112bc40..5785e72f3081 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Защита от всплывающих окон куки Подробнее...]]> + Learn More]]> Разрешить DuckDuckGo взять на себя окна выбора куки-файлов \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml index 9868e59d5d2e..696858e3def7 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Ochrana proti automatickému otváraniu okien o súboroch cookie Zistiť viac]]> + Learn More]]> Nechajte, aby sa DuckDuckGo postaral o vyskakovacie okná o súboroch cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml index a331cf917b70..9a7045f72872 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Zaščita pred pojavnimi okni piškotkov Več o tem]]> + Learn More]]> Naj DuckDuckGo poskrbi za pojavna okna piškotkov \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml index 10d7bdbee6f0..af5f589a2b8e 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Skydd mot popup-fönster för cookies Läs mer]]> + Learn More]]> Låt DuckDuckGo hantera popup-fönster för cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml index 9b939d79e8a3..a0dbf31ebb8d 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml @@ -16,8 +16,9 @@ --> - + Çerez Açılır Pencere Engelleyici Daha fazla bilgi edin]]> + Learn More]]> DuckDuckGo\'nun çerez açılır pencereleri için gereken işlemi yapmasına izin verin \ No newline at end of file diff --git a/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml index 0e1226b175bf..20dfcbeef06f 100644 --- a/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Изход от настройката Пароли + Passwords & Autofill Все още няма запазени пароли Запазване и автоматично попълване на паролите Паролите са криптирани. Никой освен Вас не може да ги види, дори ние. Научете повече diff --git a/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml index 1995126e9edd..e1746d3e7e66 100644 --- a/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Ukončit nastavení Hesla + Passwords & Autofill Zatím nemáš uložená žádná hesla Ukládání a automatické vyplňování hesel Hesla jsou šifrovaná. Nikdo kromě tebe je nevidí, dokonce ani my. Další informace diff --git a/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml index a9f04e598dca..9b8e43408d5d 100644 --- a/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Afslut opsætning Adgangskoder + Passwords & Autofill Ingen adgangskoder gemt endnu Gem og udfyld adgangskoder automatisk Adgangskoderne er krypterede. Ingen andre end dig kan se dem, ikke engang os. Få mere at vide diff --git a/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml index 17262521cae8..eef314203da5 100644 --- a/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Einrichtung beenden Passwörter + Passwords & Autofill Noch keine Passwörter gespeichert Passwörter speichern und automatisch ausfüllen Passwörter sind verschlüsselt. Niemand außer dir kann sie sehen, nicht einmal wir. Mehr erfahren diff --git a/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml index 51233e3c81ce..fa0162c1971c 100644 --- a/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Έξοδος από την εγκατάσταση Κωδικοί πρόσβασης + Passwords & Autofill Δεν έχουν αποθηκευτεί ακόμα κωδικοί πρόσβασης Αποθήκευση και αυτόματη συμπλήρωση κωδικών πρόσβασης Οι κωδικοί πρόσβασης είναι κρυπτογραφημένοι. Κανείς άλλος εκτός από εσάς δεν μπορεί να τους βλέπει, ούτε καν εμείς. Μάθετε περισσότερα diff --git a/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml index 67eb5565d003..e544cce783ec 100644 --- a/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Salir de Configuración Contraseñas + Passwords & Autofill Aún no hay contraseñas guardadas Guardar y autocompletar contraseñas Las contraseñas están cifradas. Nadie más que tú puede verlas, ni siquiera nosotros. Más información diff --git a/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml index b5ee917d25ec..47e442c59c81 100644 --- a/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Välju seadistusest Paroolid + Passwords & Autofill Paroole ei ole veel salvestatud Paroolide salvestamine ja automaatne sisestamine Paroolid on krüpteeritud. Keegi peale sinu ei näe neid, isegi mitte meie. Lisateave diff --git a/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml index 59d38e4302a5..4837eeb69dfe 100644 --- a/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Poistu asennuksesta Salasanat + Passwords & Autofill Salasanoja ei ole vielä tallennettu Tallenna ja täytä salasanat automaattisesti Salasanat salataan. Kukaan muu kuin sinä ei näe niitä, emme edes me. Lue lisää diff --git a/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml index dc2308315652..8cf40be92c8b 100644 --- a/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Quitter la configuration Mots de passe + Passwords & Autofill Aucun mot de passe n\'a été enregistré Enregistrer et saisir automatiquement les mots de passe Les mots de passe sont cryptés. Personne d\'autre que vous ne peut les voir, pas même nous. En savoir plus diff --git a/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml index 8c783c656154..d8e8a5059f4a 100644 --- a/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Izađi iz postavljanja Lozinke + Passwords & Autofill Još nema spremljenih lozinki Spremi i automatski popuni lozinke Lozinke su šifrirane. Nitko osim tebe ne može ih vidjeti, čak ni mi. Saznaj više diff --git a/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml index 88e020a2892d..4211762391e9 100644 --- a/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Kilépés a beállításokból Jelszavak + Passwords & Autofill Még nincsenek mentett jelszavak Jelszavak mentése és automatikus kitöltése A jelszavak titkosítva vannak. Rajtad kívül senki sem láthatja őket, még mi sem. További tudnivalók diff --git a/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml index 16275612b0ea..5fff14d1c304 100644 --- a/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Esci dalla configurazione Password + Passwords & Autofill Nessuna password ancora salvata Salva e compila automaticamente le password Le password sono crittografate. Nessuno tranne te può vederle, nemmeno noi. Ulteriori informazioni diff --git a/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml index 7f755fde4435..6383f5691ae7 100644 --- a/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Išeiti iš sąrankos Slaptažodžiai + Passwords & Autofill Dar nėra išsaugotų slaptažodžių Išsaugokite ir automatiškai užpildykite slaptažodžius Slaptažodžiai yra užšifruoti. Niekas, išskyrus jus, negali jų matyti – net mes. Sužinokite daugiau diff --git a/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml index b3fd3720e01a..3c7dc117bd64 100644 --- a/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Iziet no iestatīšanas Paroles + Passwords & Autofill Vēl nav saglabāta neviena parole Saglabāt un automātiski aizpildīt paroles Paroles ir šifrētas. Neviens, izņemot tevi, tās nevar redzēt – pat mēs ne. Uzzināt vairāk diff --git a/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml index c5f5fadb9c26..3421c3c06351 100644 --- a/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Avslutt oppsett Passord + Passwords & Autofill Ingen passord er lagret ennå Lagre og fyll ut passord automatisk Passord krypteres. Ingen andre enn du kan se dem, ikke engang vi. Les mer diff --git a/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml index e59b967bea7d..4e3fcf1255ba 100644 --- a/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Instellen beëindigen Wachtwoorden + Passwords & Autofill Nog geen wachtwoorden opgeslagen Wachtwoorden opslaan en automatisch invullen Wachtwoorden worden versleuteld. Niemand anders dan jij kunt ze zien, zelfs wij niet. Meer informatie diff --git a/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml index 23985257eb32..6831fa90a799 100644 --- a/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Wyjdź z konfiguracji Hasła + Passwords & Autofill Nie zapisano jeszcze żadnych haseł Zapisuj i automatycznie uzupełniaj hasła Hasła są szyfrowane. Nikt poza Tobą ich nie widzi, nawet my. Dowiedz się więcej diff --git a/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml index 59caffce35e5..be2002a88f2c 100644 --- a/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Sair da instalação Palavras-passe + Passwords & Autofill Ainda não há palavras-passe guardadas Guardar e preencher palavras-passe automaticamente As palavras-passe estão encriptadas. Ninguém além de ti pode vê-las, nem mesmo nós. Sabe mais diff --git a/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml index 05077904d231..0d2f277e3747 100644 --- a/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Ieși din configurare Parole + Passwords & Autofill Nici o parolă nu a fost salvată încă Salvează și completează automat parolele Parolele sunt criptate. Nimeni în afară de tine nu le poate vedea, nici măcar noi. Află mai multe diff --git a/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml index d647fafb26cd..cb7e27006f72 100644 --- a/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Выйти из настройки Пароли + Passwords & Autofill Сохраненных паролей пока нет Хранение и автозаполнение паролей Пароли подвергаются шифрованию. Никто, кроме вас, их не увидит. Даже мы. Подробнее... diff --git a/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml index f9ef8e52b9dc..6a58616d76b1 100644 --- a/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Odísť z nastavení Heslá + Passwords & Autofill Zatiaľ nie sú uložené žiadne heslá Ukladať a automaticky dopĺňať heslá Heslá sú zašifrované. Nikto okrem vás ich nemôže vidieť, dokonca ani my. Zistiť viac diff --git a/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml index 60eb076a3117..bc09d5f78eed 100644 --- a/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Izhod iz nastavitev Gesla + Passwords & Autofill Nobeno geslo še ni shranjeno Shranite in samodejno izpolnite gesla Gesla so šifrirana. Nihče razen vas jih ne more videti, niti mi. Več o tem diff --git a/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml index e6c50587d809..872e33e90207 100644 --- a/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Avsluta inställningen Lösenord + Passwords & Autofill Inga lösenord sparade ännu Spara och fyll i lösenord automatiskt Lösenorden är krypterade. Ingen annan än du kan se dem, inte ens vi. Läs mer diff --git a/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml index a108a2a4ea10..6c771f39fb30 100644 --- a/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml @@ -120,6 +120,7 @@ Kurulumdan Çık Şifreler + Passwords & Autofill Henüz şifre kaydedilmedi Şifreleri kaydedin ve otomatik doldurun Parolalar şifrelenir. Onları sizden başka kimse göremez. Biz bile. Daha Fazla Bilgi diff --git a/common/common-ui/src/main/res/values-bg/strings-common-ui.xml b/common/common-ui/src/main/res/values-bg/strings-common-ui.xml index aa9f050c61f1..25d47c4a7df1 100644 --- a/common/common-ui/src/main/res/values-bg/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-bg/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Уведомете ме + + + Добавяне + Редактиране + Запази + Потвърдете + Запази + Изтриване + Редактиране + Премахване + Премахване на всички + Отмяна + Отмени + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-cs/strings-common-ui.xml b/common/common-ui/src/main/res/values-cs/strings-common-ui.xml index fde56dee99f6..64e3497e208e 100644 --- a/common/common-ui/src/main/res/values-cs/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-cs/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Chci dostat upozornění + + + Přidat + Upravit + Uložit + Potvrdit + Uložit + Smazat + Upravit + Odstranit + Odstranit vše + Vrátit + Zrušit + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-da/strings-common-ui.xml b/common/common-ui/src/main/res/values-da/strings-common-ui.xml index eb60faeafde9..d7401d0009b2 100644 --- a/common/common-ui/src/main/res/values-da/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-da/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Underret mig + + + Tilføj + Rediger + Gem + Bekræft + Gem + Slet + Rediger + Fjern + Fjern alt + Fortryd + Annullér + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-de/strings-common-ui.xml b/common/common-ui/src/main/res/values-de/strings-common-ui.xml index 0e84940b7365..d68cb30d9ce3 100644 --- a/common/common-ui/src/main/res/values-de/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-de/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + ich möchte benachrichtigt werden + + + Hinzufügen + Bearbeiten + Speichern + Bestätigen + Speichern + Löschen + Bearbeiten + Entfernen + Alle entfernen + Rückgängig machen + Abbrechen + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-el/strings-common-ui.xml b/common/common-ui/src/main/res/values-el/strings-common-ui.xml index bed1b1398733..7a7d5d84c74b 100644 --- a/common/common-ui/src/main/res/values-el/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-el/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Να ειδοποιηθώ + + + Προσθήκη + Επεξεργασία + Αποθήκευση + Επιβεβαίωση + Αποθήκευση + Διαγραφή + Επεξεργασία + Αφαίρεση + Αφαίρεση όλων + Αναίρεση + Ακύρωση + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-es/strings-common-ui.xml b/common/common-ui/src/main/res/values-es/strings-common-ui.xml index bd9a46aa4591..2d981d50da10 100644 --- a/common/common-ui/src/main/res/values-es/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-es/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Notificarme + + + Añadir + Editar + Guardar + Confirmar + Guardar + Eliminar + Editar + Eliminar + Eliminar todo + Deshacer + Cancelar + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-et/strings-common-ui.xml b/common/common-ui/src/main/res/values-et/strings-common-ui.xml index 7d681f36001e..f7c2ec340c32 100644 --- a/common/common-ui/src/main/res/values-et/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-et/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Teavita mind + + + Lisa + Redigeeri + Salvesta + Kinnita + Salvesta + Kustuta + Redigeeri + Eemaldage + Eemalda kõik + Võta tagasi + Tühista + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-fi/strings-common-ui.xml b/common/common-ui/src/main/res/values-fi/strings-common-ui.xml index c2501f263b34..8b2e2c151394 100644 --- a/common/common-ui/src/main/res/values-fi/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-fi/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Ilmoita minulle + + + Lisää + Muokkaa + Tallenna + Vahvista + Tallenna + Poista + Muokkaa + Poista + Poista kaikki + Kumoa + Peruuta + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-fr/strings-common-ui.xml b/common/common-ui/src/main/res/values-fr/strings-common-ui.xml index acb0995d5e2e..df57afd0619d 100644 --- a/common/common-ui/src/main/res/values-fr/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-fr/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Me prévenir + + + Ajouter + Modifier + Enregistrer + Confirmer + Enregistrer + Supprimer + Modifier + Supprimer + Tout supprimer + Annuler + Annuler + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-hr/strings-common-ui.xml b/common/common-ui/src/main/res/values-hr/strings-common-ui.xml index 2944efbce3f5..17cc43087cc3 100644 --- a/common/common-ui/src/main/res/values-hr/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-hr/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Obavijesti me + + + Dodaj + Uredi + Spremi + Potvrdi + Spremi + Izbriši + Uredi + Ukloni + Odstrani sve + Poništi + Odustani + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-hu/strings-common-ui.xml b/common/common-ui/src/main/res/values-hu/strings-common-ui.xml index d77c1e4226bd..615597fe7f63 100644 --- a/common/common-ui/src/main/res/values-hu/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-hu/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Értesítést kérek + + + Hozzáadás + Szerkesztés + Mentés + Megerősítés + Mentés + Törlés + Szerkesztés + Eltávolítás + Összes eltávolítása + Visszavonás + Mégsem + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-it/strings-common-ui.xml b/common/common-ui/src/main/res/values-it/strings-common-ui.xml index 42af50da1790..50d4faf502bf 100644 --- a/common/common-ui/src/main/res/values-it/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-it/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Inviami una notifica + + + Aggiungi + Modifica + Salva + Conferma + Salva + Elimina + Modifica + Rimuovi + Elimina tutto + Annulla + Annulla + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-lt/strings-common-ui.xml b/common/common-ui/src/main/res/values-lt/strings-common-ui.xml index f4f48551ffc1..5eb4259353aa 100644 --- a/common/common-ui/src/main/res/values-lt/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-lt/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Informuoti + + + Papildyti + Redaguoti + Išsaugoti + Patvirtinti + Išsaugoti + Trinti + Redaguoti + Pašalinti + Pašalinti visus + Anuliuoti + Atšaukti + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-lv/strings-common-ui.xml b/common/common-ui/src/main/res/values-lv/strings-common-ui.xml index 3092e370b28e..8ea8f4ea275e 100644 --- a/common/common-ui/src/main/res/values-lv/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-lv/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + INFORMĒT MANI + + + Pievienot + Rediģēt + Saglabāt + Apstiprināt + Saglabāt + Dzēst + Rediģēt + Noņemt + Noņemt visu + Atsaukt + Atcelt + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-nb/strings-common-ui.xml b/common/common-ui/src/main/res/values-nb/strings-common-ui.xml index dcd52356b6c9..d22d024059dc 100644 --- a/common/common-ui/src/main/res/values-nb/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-nb/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Send meg et varsel + + + Legg til + Rediger + Lagre + Bekreft + Lagre + Slett + Rediger + Fjern + Fjern alle + Angre + Avbryt + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-nl/strings-common-ui.xml b/common/common-ui/src/main/res/values-nl/strings-common-ui.xml index f0d2d3ba08e9..b94f5cb4647e 100644 --- a/common/common-ui/src/main/res/values-nl/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-nl/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Melding sturen + + + Toevoegen + Bewerken + Opslaan + Bevestigen + Opslaan + Verwijderen + Bewerken + Verwijderen + Alles verwijderen + Ongedaan maken + Annuleren + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-pl/strings-common-ui.xml b/common/common-ui/src/main/res/values-pl/strings-common-ui.xml index aa567144df68..b7ee548f5294 100644 --- a/common/common-ui/src/main/res/values-pl/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-pl/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Powiadom mnie + + + Dodaj + Edytuj + Zapisz + Potwierdź + Zapisz + Usuń + Edytuj + Usuń + Usuń wszystko + Cofnij + Anuluj + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-pt/strings-common-ui.xml b/common/common-ui/src/main/res/values-pt/strings-common-ui.xml index ce9a2d102bc4..15889221f5e5 100644 --- a/common/common-ui/src/main/res/values-pt/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-pt/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Notificar-me + + + Adicionar + Editar + Guardar + Confirmar + Guardar + Eliminar + Editar + Remover + Remover tudo + Anular + Cancelar + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-ro/strings-common-ui.xml b/common/common-ui/src/main/res/values-ro/strings-common-ui.xml index d51686668f66..c84496cd8709 100644 --- a/common/common-ui/src/main/res/values-ro/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-ro/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + DORESC SĂ PRIMESC NOTIFICĂRI + + + Adaugă + Editează + Salvează + Confirmare + Salvare + Ștergere + Editare + Elimină + Elimină tot + Anulează + Anulează + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-ru/strings-common-ui.xml b/common/common-ui/src/main/res/values-ru/strings-common-ui.xml index 2a9f6c5134b8..c54b92d895b5 100644 --- a/common/common-ui/src/main/res/values-ru/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-ru/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Уведомить меня + + + Добавить + Редактировать + Сохранить + Подтвердить + Сохранить + Удалить + Редактировать + Удалить + Удалить все + Отменить + Отменить + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-sk/strings-common-ui.xml b/common/common-ui/src/main/res/values-sk/strings-common-ui.xml index 4606f15408e5..ba49777d6852 100644 --- a/common/common-ui/src/main/res/values-sk/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-sk/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Upozornite ma + + + Pridať + Upraviť + Uložiť + Potvrdiť + Uložiť + Vymazať + Upraviť + Odstrániť + Odstrániť všetky + Zrušiť zmenu + Zrušiť + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-sl/strings-common-ui.xml b/common/common-ui/src/main/res/values-sl/strings-common-ui.xml index 403fbdaa7447..9f53c38a520e 100644 --- a/common/common-ui/src/main/res/values-sl/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-sl/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Obveščajte me + + + Dodaj + Uredi + Shrani + Potrdi + Shrani + Izbriši + Uredi + Odstrani + Odstrani vse + Razveljavi + Preklic + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-sv/strings-common-ui.xml b/common/common-ui/src/main/res/values-sv/strings-common-ui.xml index ce9cb9f7b11e..52cc5a62b035 100644 --- a/common/common-ui/src/main/res/values-sv/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-sv/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Meddela mig + + + Lägg till + Redigera + Spara + Bekräfta + Spara + Ta bort + Redigera + Ta bort + Ta bort alla + Återställ + Avbryt + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values-tr/strings-common-ui.xml b/common/common-ui/src/main/res/values-tr/strings-common-ui.xml index eb78a2514837..e05a40dcc94d 100644 --- a/common/common-ui/src/main/res/values-tr/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-tr/strings-common-ui.xml @@ -16,7 +16,25 @@ --> - + Bana bildir + + + Ekle + Düzenle + Kaydet + Onayla + Kaydet + Sil + Düzenle + Kaldır + Tümünü Kaldır + Geri al + Vazgeç + + + Always On + On + Off diff --git a/common/common-ui/src/main/res/values/strings-common-ui.xml b/common/common-ui/src/main/res/values/strings-common-ui.xml index cdd1a7cac200..a968c0fc3072 100644 --- a/common/common-ui/src/main/res/values/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values/strings-common-ui.xml @@ -20,6 +20,19 @@ Notify me + + Add + Edit + Save + Confirm + Save + Delete + Edit + Remove + Remove All + Undo + Cancel + Always On On diff --git a/site-permissions/site-permissions-impl/build.gradle b/site-permissions/site-permissions-impl/build.gradle index 62c42b728311..8166b55b59d6 100644 --- a/site-permissions/site-permissions-impl/build.gradle +++ b/site-permissions/site-permissions-impl/build.gradle @@ -33,6 +33,7 @@ dependencies { implementation project(path: ':site-permissions-api') implementation project(path: ':privacy-config-api') implementation project(path: ':feature-toggles-api') + implementation project(path: ':navigation-api') api project(path: ':site-permissions-store') anvil project(path: ':anvil-compiler') diff --git a/site-permissions/site-permissions-impl/src/main/AndroidManifest.xml b/site-permissions/site-permissions-impl/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..25c0082f11df --- /dev/null +++ b/site-permissions/site-permissions-impl/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsActivity.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsActivity.kt similarity index 83% rename from app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsActivity.kt rename to site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsActivity.kt index 2ad5d5df52de..39e1cf7ba457 100644 --- a/app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsActivity.kt +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsActivity.kt @@ -14,26 +14,25 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions +package com.duckduckgo.site.permissions.impl.ui -import android.content.Context -import android.content.Intent import android.os.Bundle import androidx.core.text.HtmlCompat import androidx.lifecycle.Lifecycle.State.STARTED import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope +import com.duckduckgo.anvil.annotations.ContributeToActivityStarter import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.browser.databinding.ActivitySitePermissionsBinding import com.duckduckgo.app.browser.favicon.FaviconManager -import com.duckduckgo.app.sitepermissions.SitePermissionsViewModel.Command -import com.duckduckgo.app.sitepermissions.SitePermissionsViewModel.Command.LaunchWebsiteAllowed -import com.duckduckgo.app.sitepermissions.SitePermissionsViewModel.Command.ShowRemovedAllConfirmationSnackbar -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteActivity import com.duckduckgo.common.ui.DuckDuckGoActivity import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.site.permissions.impl.R +import com.duckduckgo.site.permissions.impl.databinding.ActivitySitePermissionsBinding +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel.Command +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel.Command.LaunchWebsiteAllowed +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel.Command.ShowRemovedAllConfirmationSnackbar +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteActivity import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionsEntity import com.google.android.material.snackbar.Snackbar import javax.inject.Inject @@ -41,6 +40,7 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch @InjectWith(ActivityScope::class) +@ContributeToActivityStarter(SitePermissionScreenNoParams::class) class SitePermissionsActivity : DuckDuckGoActivity() { @Inject @@ -93,7 +93,7 @@ class SitePermissionsActivity : DuckDuckGoActivity() { binding.root, message, Snackbar.LENGTH_LONG, - ).setAction(R.string.fireproofWebsiteSnackbarAction) { + ).setAction(com.duckduckgo.mobile.android.R.string.undo) { viewModel.onSnackBarUndoRemoveAllWebsites(removedSitePermissions) }.show() } @@ -116,10 +116,4 @@ class SitePermissionsActivity : DuckDuckGoActivity() { private fun launchWebsiteAllowed(domain: String) { startActivity(PermissionsPerWebsiteActivity.intent(this, domain)) } - - companion object { - fun intent(context: Context): Intent { - return Intent(context, SitePermissionsActivity::class.java) - } - } } diff --git a/app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsAdapter.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsAdapter.kt similarity index 85% rename from app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsAdapter.kt rename to site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsAdapter.kt index 0b1b08949e07..c8133774047e 100644 --- a/app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsAdapter.kt +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsAdapter.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions +package com.duckduckgo.site.permissions.impl.ui import android.view.LayoutInflater import android.view.View @@ -26,30 +26,29 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.RecyclerView import androidx.viewbinding.ViewBinding -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.browser.R.layout -import com.duckduckgo.app.browser.databinding.ViewSitePermissionsDescriptionBinding -import com.duckduckgo.app.browser.databinding.ViewSitePermissionsEmptyListBinding -import com.duckduckgo.app.browser.databinding.ViewSitePermissionsSiteBinding -import com.duckduckgo.app.browser.databinding.ViewSitePermissionsTitleBinding -import com.duckduckgo.app.browser.databinding.ViewSitePermissionsToggleBinding import com.duckduckgo.app.browser.favicon.FaviconManager -import com.duckduckgo.app.sitepermissions.SitePermissionListItem.Divider -import com.duckduckgo.app.sitepermissions.SitePermissionListItem.EmptySites -import com.duckduckgo.app.sitepermissions.SitePermissionListItem.SiteAllowedItem -import com.duckduckgo.app.sitepermissions.SitePermissionListItem.SitePermissionToggle -import com.duckduckgo.app.sitepermissions.SitePermissionListItem.SitePermissionsDescription -import com.duckduckgo.app.sitepermissions.SitePermissionListItem.SitePermissionsHeader -import com.duckduckgo.app.sitepermissions.SitePermissionsListViewType.DESCRIPTION -import com.duckduckgo.app.sitepermissions.SitePermissionsListViewType.DIVIDER -import com.duckduckgo.app.sitepermissions.SitePermissionsListViewType.HEADER -import com.duckduckgo.app.sitepermissions.SitePermissionsListViewType.SITES_EMPTY -import com.duckduckgo.app.sitepermissions.SitePermissionsListViewType.SITE_ALLOWED_ITEM -import com.duckduckgo.app.sitepermissions.SitePermissionsListViewType.TOGGLE import com.duckduckgo.common.ui.menu.PopupMenu import com.duckduckgo.common.ui.view.PopupMenuItemView import com.duckduckgo.common.ui.view.divider.HorizontalDivider import com.duckduckgo.common.ui.view.setEnabledOpacity +import com.duckduckgo.site.permissions.impl.R +import com.duckduckgo.site.permissions.impl.databinding.ViewSitePermissionsDescriptionBinding +import com.duckduckgo.site.permissions.impl.databinding.ViewSitePermissionsEmptyListBinding +import com.duckduckgo.site.permissions.impl.databinding.ViewSitePermissionsSiteBinding +import com.duckduckgo.site.permissions.impl.databinding.ViewSitePermissionsTitleBinding +import com.duckduckgo.site.permissions.impl.databinding.ViewSitePermissionsToggleBinding +import com.duckduckgo.site.permissions.impl.ui.SitePermissionListItem.Divider +import com.duckduckgo.site.permissions.impl.ui.SitePermissionListItem.EmptySites +import com.duckduckgo.site.permissions.impl.ui.SitePermissionListItem.SiteAllowedItem +import com.duckduckgo.site.permissions.impl.ui.SitePermissionListItem.SitePermissionToggle +import com.duckduckgo.site.permissions.impl.ui.SitePermissionListItem.SitePermissionsDescription +import com.duckduckgo.site.permissions.impl.ui.SitePermissionListItem.SitePermissionsHeader +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsListViewType.DESCRIPTION +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsListViewType.DIVIDER +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsListViewType.HEADER +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsListViewType.SITES_EMPTY +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsListViewType.SITE_ALLOWED_ITEM +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsListViewType.TOGGLE import kotlinx.coroutines.launch class SitePermissionsAdapter( @@ -172,7 +171,7 @@ class SitePermissionsAdapter( } private fun showOverflowMenu(removeDisabled: Boolean) { - val popupMenu = PopupMenu(layoutInflater, layout.popup_window_remove_all_menu) + val popupMenu = PopupMenu(layoutInflater, R.layout.popup_window_remove_all_menu) val menuItem = popupMenu.contentView.findViewById(R.id.removeAll) if (removeDisabled) { menuItem.isEnabled = false diff --git a/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsScreens.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsScreens.kt new file mode 100644 index 000000000000..24ba313951b1 --- /dev/null +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsScreens.kt @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.site.permissions.impl.ui + +import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams + +/** + * Use this model to launch the Site Permissions + */ +object SitePermissionScreenNoParams : ActivityParams diff --git a/app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsViewModel.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsViewModel.kt similarity index 94% rename from app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsViewModel.kt rename to site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsViewModel.kt index 9289746bf2bd..2b94e0812fd3 100644 --- a/app/src/main/java/com/duckduckgo/app/sitepermissions/SitePermissionsViewModel.kt +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/SitePermissionsViewModel.kt @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions +package com.duckduckgo.site.permissions.impl.ui import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.sitepermissions.SitePermissionsViewModel.Command.LaunchWebsiteAllowed -import com.duckduckgo.app.sitepermissions.SitePermissionsViewModel.Command.ShowRemovedAllConfirmationSnackbar import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.site.permissions.impl.R import com.duckduckgo.site.permissions.impl.SitePermissionsRepository +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel.Command.LaunchWebsiteAllowed +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel.Command.ShowRemovedAllConfirmationSnackbar import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionsEntity import com.duckduckgo.site.permissions.store.sitepermissionsallowed.SitePermissionAllowedEntity import javax.inject.Inject diff --git a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionSettingAdapter.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionSettingAdapter.kt similarity index 88% rename from app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionSettingAdapter.kt rename to site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionSettingAdapter.kt index 01369a33ac76..5b659b0d27e3 100644 --- a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionSettingAdapter.kt +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionSettingAdapter.kt @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions.permissionsperwebsite +package com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import com.duckduckgo.app.browser.databinding.ItemSitePermissionSettingSelectionBinding -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionSettingAdapter.ViewHolder +import com.duckduckgo.site.permissions.impl.databinding.ItemSitePermissionSettingSelectionBinding +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionSettingAdapter.ViewHolder class PermissionSettingAdapter(private val viewModel: PermissionsPerWebsiteViewModel) : RecyclerView.Adapter() { diff --git a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionsPerWebsiteActivity.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionsPerWebsiteActivity.kt similarity index 82% rename from app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionsPerWebsiteActivity.kt rename to site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionsPerWebsiteActivity.kt index 8d2c6512f021..0226fcd2537d 100644 --- a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionsPerWebsiteActivity.kt +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionsPerWebsiteActivity.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions.permissionsperwebsite +package com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite import android.content.Context import android.content.Intent @@ -25,20 +25,20 @@ import androidx.lifecycle.Lifecycle.State.STARTED import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.browser.databinding.ActivityPermissionPerWebsiteBinding -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.GoBackToSitePermissions -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.ShowPermissionSettingSelectionDialog -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSettingOption.ALLOW -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSettingOption.ASK -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSettingOption.Companion.getPermissionSettingOptionFromPosition -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSettingOption.DENY import com.duckduckgo.common.ui.DuckDuckGoActivity import com.duckduckgo.common.ui.view.dialog.RadioListAlertDialogBuilder import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.common.utils.extensions.websiteFromGeoLocationsApiOrigin import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.site.permissions.impl.R +import com.duckduckgo.site.permissions.impl.databinding.ActivityPermissionPerWebsiteBinding +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.GoBackToSitePermissions +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.ShowPermissionSettingSelectionDialog +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption.ALLOW +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption.ASK +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption.Companion.getPermissionSettingOptionFromPosition +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption.DENY import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import timber.log.Timber @@ -129,8 +129,8 @@ class PermissionsPerWebsiteActivity : DuckDuckGoActivity() { ), currentOption.setting.order, ) - .setPositiveButton(R.string.dialogSave) - .setNegativeButton(R.string.cancel) + .setPositiveButton(com.duckduckgo.mobile.android.R.string.dialogSave) + .setNegativeButton(com.duckduckgo.mobile.android.R.string.cancel) .addEventListener( object : RadioListAlertDialogBuilder.EventListener() { override fun onPositiveButtonClicked(selectedItem: Int) { diff --git a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionsPerWebsiteViewModel.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionsPerWebsiteViewModel.kt similarity index 93% rename from app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionsPerWebsiteViewModel.kt rename to site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionsPerWebsiteViewModel.kt index 8795c02116d2..770bfbc08060 100644 --- a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/PermissionsPerWebsiteViewModel.kt +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/PermissionsPerWebsiteViewModel.kt @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions.permissionsperwebsite +package com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.GoBackToSitePermissions -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.ShowPermissionSettingSelectionDialog -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSettingOption.ASK -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSettingOption.ASK_DISABLED import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.site.permissions.impl.R import com.duckduckgo.site.permissions.impl.SitePermissionsRepository +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.GoBackToSitePermissions +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.ShowPermissionSettingSelectionDialog +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption.ASK +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption.ASK_DISABLED import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionsEntity import javax.inject.Inject import kotlinx.coroutines.channels.Channel diff --git a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/WebsitePermissionSettingOption.kt b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/WebsitePermissionSettingOption.kt similarity index 94% rename from app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/WebsitePermissionSettingOption.kt rename to site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/WebsitePermissionSettingOption.kt index 819cf306eca1..10ee54c53818 100644 --- a/app/src/main/java/com/duckduckgo/app/sitepermissions/permissionsperwebsite/WebsitePermissionSettingOption.kt +++ b/site-permissions/site-permissions-impl/src/main/java/com/duckduckgo/site/permissions/impl/ui/permissionsperwebsite/WebsitePermissionSettingOption.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions.permissionsperwebsite +package com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite import androidx.annotation.StringRes -import com.duckduckgo.app.browser.R +import com.duckduckgo.site.permissions.impl.R import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionAskSettingType import java.io.Serializable diff --git a/app/src/main/res/drawable/ic_location_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_location_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_location_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_location_24.xml diff --git a/app/src/main/res/drawable/ic_location_blocked_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_location_blocked_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_location_blocked_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_location_blocked_24.xml diff --git a/app/src/main/res/drawable/ic_microphone_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_microphone_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_microphone_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_microphone_24.xml diff --git a/app/src/main/res/drawable/ic_microphone_blocked_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_microphone_blocked_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_microphone_blocked_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_microphone_blocked_24.xml diff --git a/app/src/main/res/drawable/ic_video_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_video_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_24.xml diff --git a/app/src/main/res/drawable/ic_video_blocked_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_blocked_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_video_blocked_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_blocked_24.xml diff --git a/app/src/main/res/drawable/ic_video_player_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_player_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_video_player_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_player_24.xml diff --git a/app/src/main/res/drawable/ic_video_player_blocked_24.xml b/site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_player_blocked_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_video_player_blocked_24.xml rename to site-permissions/site-permissions-impl/src/main/res/drawable/ic_video_player_blocked_24.xml diff --git a/app/src/main/res/layout/activity_permission_per_website.xml b/site-permissions/site-permissions-impl/src/main/res/layout/activity_permission_per_website.xml similarity index 100% rename from app/src/main/res/layout/activity_permission_per_website.xml rename to site-permissions/site-permissions-impl/src/main/res/layout/activity_permission_per_website.xml diff --git a/app/src/main/res/layout/activity_site_permissions.xml b/site-permissions/site-permissions-impl/src/main/res/layout/activity_site_permissions.xml similarity index 94% rename from app/src/main/res/layout/activity_site_permissions.xml rename to site-permissions/site-permissions-impl/src/main/res/layout/activity_site_permissions.xml index 5554fd1b35f2..82960c40869b 100644 --- a/app/src/main/res/layout/activity_site_permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/layout/activity_site_permissions.xml @@ -20,7 +20,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - tools:context="com.duckduckgo.app.sitepermissions.SitePermissionsActivity"> + tools:context="com.duckduckgo.site.permissions.impl.ui.SitePermissionsActivity"> + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_site_permissions_description.xml b/site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_description.xml similarity index 100% rename from app/src/main/res/layout/view_site_permissions_description.xml rename to site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_description.xml diff --git a/app/src/main/res/layout/view_site_permissions_empty_list.xml b/site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_empty_list.xml similarity index 100% rename from app/src/main/res/layout/view_site_permissions_empty_list.xml rename to site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_empty_list.xml diff --git a/app/src/main/res/layout/view_site_permissions_site.xml b/site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_site.xml similarity index 100% rename from app/src/main/res/layout/view_site_permissions_site.xml rename to site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_site.xml diff --git a/app/src/main/res/layout/view_site_permissions_title.xml b/site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_title.xml similarity index 100% rename from app/src/main/res/layout/view_site_permissions_title.xml rename to site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_title.xml diff --git a/app/src/main/res/layout/view_site_permissions_toggle.xml b/site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_toggle.xml similarity index 100% rename from app/src/main/res/layout/view_site_permissions_toggle.xml rename to site-permissions/site-permissions-impl/src/main/res/layout/view_site_permissions_toggle.xml diff --git a/site-permissions/site-permissions-impl/src/main/res/menu/menu_permissions_per_website_activity.xml b/site-permissions/site-permissions-impl/src/main/res/menu/menu_permissions_per_website_activity.xml new file mode 100644 index 000000000000..73630c133c57 --- /dev/null +++ b/site-permissions/site-permissions-impl/src/main/res/menu/menu_permissions_per_website_activity.xml @@ -0,0 +1,24 @@ + + + + + + diff --git a/site-permissions/site-permissions-impl/src/main/res/values-bg/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-bg/strings-site-permissions.xml index 9b5177c0c588..ae828c60851d 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-bg/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-bg/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + „%1$s“ иска да отвори софтуера за DRM + Софтуерът за управление на цифровите права (DRM) е необходим за възпроизвеждане на защитено мултимедийно съдържание, но освен това осигурява достъп до идентификаторите на устройствата. Дайте разрешение за използване на тези данни само на сайтове, на които имате доверие. Можете да управлявате разрешенията по всяко време в Настройки. Научете повече + Винаги + Само за тази сесия + Винаги да се отказва + Отказ само за тази сесия + + + „%1$s“ иска достъп до местоположението + Запомни моя избор + Използваме анонимното Ви местоположение само за да Ви осигурим по-добри резултати близо до мястото, на което се намирате. В Настройки можете да управлявате разрешенията за достъп до местоположението, които сте дали на отделни сайтове. + В Настройки можете да управлявате разрешенията за достъп до местоположението, които сте дали на отделни сайтове. + Разрешаване на DuckDuckGo да иска достъп до местоположението на това устройство + Сайтовете могат да използват местоположението, само ако разрешите на DuckDuckGo да поиска достъп. + Разрешаване на DuckDuckGo да иска достъп до местоположението + + + Разрешения за сайтове + В Настройки можете да управлявате разрешенията за достъп до микрофона и камерата, които сте дали на отделни сайтове. + В Настройки можете да управлявате разрешенията за достъп до микрофона, които сте дали на отделни сайтове. + В Настройки можете да управлявате разрешенията за достъп до камерата, които сте дали на отделни сайтове. „%1$s“ иска достъп до камерата и микрофона „%1$s“ иска достъп до микрофона „%1$s“ иска достъп до камерата @@ -35,4 +57,20 @@ Сайтовете могат да използват камерата и микрофона, само ако разрешите на DuckDuckGo да поиска достъп. Отвори Настройки Отмени + + Сайтовете, които посещавате, може да поискат достъп до местоположението, камерата, микрофона или софтуера за управление на цифровите права (DRM) на устройството. Те няма да имат достъп до тях, освен ако не им дадете изрично разрешение. + Разрешаване на всички сайтове да искат: + Местоположение + Камера + Микрофон + Управление на сайтове + Все още няма сайтове + Разрешенията са премахнати за всички сайтове + Разрешения за \"%1$s\" + Питай всеки път + Отказвам + Разрешавам + Деактивирано за всички сайтове + %1$s разрешение за %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-cs/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-cs/strings-site-permissions.xml index b36189006814..42f6826451fe 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-cs/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-cs/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + %1$s chce spustit tvůj DRM software + Software DRM (tedy software pro správu digitálních oprávnění) je nutný k přehrávání chráněného mediálního obsahu, poskytuje ale taky přístup k identifikátorům zařízení. Povolení je vhodné udělit jen stránkám, kterým důvěřuješ. Oprávnění můžeš kdykoli spravovat v Nastaveních. Další informace + Vždy + Pouze pro tuto relaci + Vždy odmítnout + Odmítnout pro tuto relaci + + + %1$s chce získat přístup ke tvé poloze + Zapamatovat mou volbu + Tvou anonymní polohu používáme jen k tomu, abychom ti mohli poskytovat lepší výsledky v tvojí blízkosti. Oprávnění k přístupu k poloze udělené jednotlivým webovým stránkám můžeš spravovat v Nastaveních. + Oprávnění k přístupu k poloze, která jste udělili jednotlivým webovým stránkám, můžete spravovat v Nastavení. + Povolit DuckDuckGo žádat na tomto zařízení o přístup k poloze + Weby můžou používat tvoji polohu, jen když službě DuckDuckGo povolíš žádat o přístup. + Povolit DuckDuckGo žádat o přístup k poloze + + + Oprávnění webu + Oprávnění k přístupu k mikrofonu a fotoaparátu udělená jednotlivým webovým stránkám můžeš spravovat v Nastavení. + Oprávnění k přístupu k mikrofonu udělená jednotlivým webovým stránkám můžeš spravovat v Nastavení. + Oprávnění k přístupu k fotoaparátu udělená jednotlivým webovým stránkám můžeš spravovat v Nastavení. %1$s žádá o přístup ke kameře a mikrofonu %1$s žádá o přístup k mikrofonu %1$s žádá o přístup ke kameře @@ -35,4 +57,20 @@ Weby můžou používat tvůj fotoaparát a mikrofon, jen když službě DuckDuckGo povolíš žádat o přístup. Otevřít nastavení Zrušit + + Stránky, které navštívíš, můžou žádat o přístup k fotoaparátu, mikrofonu, softwaru DRM (Digital Rights Management) nebo k poloze tvého zařízení. Přístup mít nebudou, pokud jim ho výslovně nepovolíš. + Povolit všem webům, aby žádaly o: + Poloha + Fotoaparát + Mikrofon + Správa webů + Zatím žádné weby + Oprávnění odebrána všem webům + Oprávnění „%1$s“ + Vždycky se ptát + Odmítnout + Povolit + Zakázáno pro všechny weby + %1$s – povolení pro web %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-da/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-da/strings-site-permissions.xml index b3113e4f0544..b4d7db25d202 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-da/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-da/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" ønsker at åbne din DRM-software + Digital Rights Management-software er nødvendig for at afspille beskyttet medieindhold, men giver også adgang til enhedsidentifikatorer. Giv kun tilladelse til sider, du stoler på, til at bruge disse data. Du kan til enhver tid administrere tilladelser i Indstillinger. Få mere at vide + Altid + Kun for denne session + Afvis altid + Afvis for denne session + + + \"%1$s\" ønsker at få adgang til din placering + Husk mit valg + Vi bruger kun din anonyme placering til at levere bedre resultater tættere på dig. Du kan administrere de tilladelser til placeringsadgang, du har givet til individuelle websteder under Indstillinger. + Du kan administrere de tilladelser til placeringsadgang, du har givet til individuelle websteder under Indstillinger. + Tillad DuckDuckGo at bede om adgang til placering på denne enhed + Websteder kan kun bruge din placering, hvis du giver DuckDuckGo tilladelse til at bede om adgang. + Tillad DuckDuckGo at bede om adgang til placering + + + Tilladelser til webstedet + Du kan administrere de tilladelser til mikrofon- og placeringsadgang, du har givet til individuelle websteder under Indstillinger. + Du kan administrere de tilladelser til mikrofonadgang, du har givet til individuelle websteder under Indstillinger. + Du kan administrere de tilladelser til kameraadgang, du har givet til individuelle websteder under Indstillinger. \"%1$s\" ønsker at få adgang til kameraet og mikrofonen \"%1$s\" ønsker at få adgang til mikrofonen \"%1$s\" ønsker at få adgang til kameraet @@ -35,4 +57,20 @@ Websteder kan kun bruge dit kamera og din mikrofon, hvis du giver DuckDuckGo tilladelse til at bede om adgang. Åbn indstillinger Afbestil + + Websteder, du besøger, kan bede om adgang til din enheds placering, kamera, mikrofon eller DRM-software (Digital Rights Management). De vil ikke kunne få adgang til disse, medmindre du udtrykkeligt giver dem tilladelse. + Tillad, at alle websteder beder om: + Placering + Kamera + Mikrofon + Administrer websteder + Ingen websteder endnu + Tilladelser fjernet for alle websteder + Tilladelser til \"%1$s\" + Spørg hver gang + Afvis + Tillad + Deaktiveret for alle websteder + %1$s tilladelse til %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-de/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-de/strings-site-permissions.xml index a90d509c35cb..d46eba785433 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-de/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-de/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + „%1$s“ möchte deine DRM-Software öffnen + Zum Abspielen geschützter Medieninhalte ist eine Digital Rights Management-Software erforderlich, die aber auch Zugriff auf Gerätekennungen ermöglicht. Erlaube nur Websites, denen du vertraust, den Zugriff auf diese Daten. Du kannst die Berechtigungen jederzeit in den Einstellungen verwalten. Mehr erfahren + Immer + Nur für diese Sitzung + Immer ablehnen + Für diese Sitzung ablehnen + + + „%1$s“ möchte auf deinen Standort zugreifen + Meine Auswahl merken + Wir verwenden deinen anonymen Standort nur, um dir bessere Ergebnisse in deiner Nähe zu liefern. Du kannst die Berechtigungen in den Einstellungen verwalten. Dort siehst du, welchen Websites du Zugriffsberechtigungen auf den Gerätestandort gewährt hast. + Du kannst die Berechtigungen in den Einstellungen verwalten. Dort siehst du, welchen Websites du Zugriffsberechtigungen auf den Gerätestandort gewährt hast. + DuckDuckGo erlauben, um Zugriff auf den Standort auf diesem Gerät zu bitten + Websites können deinen Standort nur verwenden, wenn du DuckDuckGo erlaubst, um Zugriff zu bitten. + DuckDuckGo erlauben, um Zugriff auf den Standort zu bitten + + + Website-Berechtigungen + Du kannst die Mikrofon- und Kamerazugriffsberechtigungen in den Einstellungen verwalten. Dort siehst du, welchen Websites du Zugriffsberechtigungen auf den Gerätestandort gewährt hast. + Du kannst die Mikrofonzugriffsberechtigungen in den Einstellungen verwalten. Dort siehst du, welchen Websites du Zugriffsberechtigungen auf den Gerätestandort gewährt hast. + Du kannst die Kamerazugriffsberechtigungen in den Einstellungen verwalten. Dort siehst du, welchen Websites du Zugriffsberechtigungen auf den Gerätestandort gewährt hast. „%1$s“ möchte auf die Kamera und das Mikrofon zugreifen „%1$s“ möchte auf das Mikrofon zugreifen „%1$s“ möchte auf die Kamera zugreifen @@ -35,4 +57,20 @@ Websites können deine Kamera und dein Mikrofon nur verwenden, wenn du DuckDuckGo erlaubst, um Zugriff zu bitten. Einstellungen öffnen Abbrechen + + Von dir besuchte Websites bitten möglicherweise um Zugriff auf den Standort, die Kamera, das Mikrofon oder die DRM-Software (Digital Rights Management) deines Geräts. Sie können darauf nicht zugreifen, es sei denn, du erteilst ihnen ausdrücklich die Erlaubnis. + Allen Websites erlauben, um Folgendes zu bitten: + Standort + Kamera + Mikrofon + Websites verwalten + Noch keine Websites + Berechtigungen für alle Websites entfernt + Berechtigungen für „%1$s“ + Jedes Mal fragen + Ablehnen + Zulassen + Für alle Websites deaktiviert + %1$s-Berechtigung für %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-el/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-el/strings-site-permissions.xml index 87cf97213003..f4954545de63 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-el/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-el/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + Η εφαρμογή «%1$s» θέλει να ανοίξει το λογισμικό σας DRM + Το λογισμικό Διαχείριση ψηφιακών δικαιωμάτων απαιτείται για αναπαραγωγή προστατευμένου περιεχομένου πολυμέσων, ωστόσο παρέχει επίσης πρόσβαση σε αναγνωριστικά συσκευών. Χορηγήστε άδεια μόνο σε ιστότοπους που εμπιστεύεστε για αυτά τα δεδομένα. Μπορείτε να διαχειριστείτε τα δικαιώματα οποιαδήποτε στιγμή από τις Ρυθμίσεις. Μάθετε περισσότερα + Πάντα + Μόνο γι\' αυτή τη σύνδεση + Άρνηση για πάντα + Άρνηση γι\' αυτή τη σύνδεση + + + Η εφαρμογή «%1$s» θέλει να αποκτήσει πρόσβαση στην τοποθεσία σας + Θυμηθείτε την επιλογή μου + Χρησιμοποιούμε την ανώνυμη τοποθεσία σας αποκλειστικά και μόνο για να προσφέρουμε καλύτερα αποτελέσματα, πιο κοντά σε εσάς. Μπορείτε να διαχειριστείτε τα δικαιώματα πρόσβασης τοποθεσίας που έχετε εκχωρήσει σε μεμονωμένους ιστότοπους από τις Ρυθμίσεις. + Μπορείτε να διαχειριστείτε τα δικαιώματα πρόσβασης τοποθεσίας που έχετε εκχωρήσει σε μεμονωμένους ιστότοπους από τις Ρυθμίσεις. + Επιτρέψτε στο DuckDuckGo να αιτηθεί πρόσβαση στην τοποθεσία της συσκευής αυτής + Οι ιστότοποι μπορούν να χρησιμοποιούν την τοποθεσία σας μόνο εάν επιτρέψετε στο DuckDuckGo να αιτηθεί πρόσβαση. + Επιτρέψτε στο DuckDuckGo να αιτηθεί πρόσβαση στην τοποθεσία + + + Δικαιώματα ιστότοπου + Μπορείτε να διαχειριστείτε τα δικαιώματα πρόσβασης του μικροφώνου και της κάμερας που έχετε εκχωρήσει σε μεμονωμένους ιστότοπους από τις Ρυθμίσεις. + Μπορείτε να διαχειριστείτε τα δικαιώματα πρόσβασης του μικροφώνου που έχετε εκχωρήσει σε μεμονωμένους ιστότοπους από τις Ρυθμίσεις. + Μπορείτε να διαχειριστείτε τα δικαιώματα πρόσβασης κάμερας που έχετε εκχωρήσει σε μεμονωμένους ιστότοπους από τις Ρυθμίσεις. Η εφαρμογή «%1$s» επιθυμεί να αποκτήσει πρόσβαση στην κάμερα και στο μικρόφωνο Η εφαρμογή «%1$s» επιθυμεί να αποκτήσει πρόσβαση στο μικρόφωνο Η εφαρμογή «%1$s» επιθυμεί να αποκτήσει πρόσβαση στην κάμερα @@ -35,4 +57,20 @@ Οι ιστότοποι μπορούν να χρησιμοποιούν την κάμερα και το μικρόφωνό σας μόνο εάν επιτρέψετε στο DuckDuckGo να αιτηθεί πρόσβαση. Άνοιγμα ρυθμίσεων Ακύρωση + + Οι ιστότοποι που επισκέπτεστε ενδέχεται να ζητήσουν πρόσβαση στην τοποθεσία, την κάμερα, το μικρόφωνο ή το λογισμικό DRM (Διαχείριση ψηφιακών δικαιωμάτων) της συσκευής σας. Δεν θα μπορούν να έχουν πρόσβαση σε αυτά εάν δεν τους παρέχετε ρητά την άδειά σας. + Να επιτρέπεται σε όλους τους ιστότοπους να αιτούνται: + Τοποθεσία + Κάμερα + Μικρόφωνο + Διαχείριση ιστότοπων + Δεν υπάρχουν ακόμη ιστότοποι + Τα δικαιώματα καταργήθηκαν για όλους τους ιστότοπους + Δικαιώματα για «%1$s» + Να γίνεται ερώτηση κάθε φορά + Απόρριψη + Αποδοχή + Απενεργοποιήθηκε για όλους τους ιστότοπους + %1$s άδεια για %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-es/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-es/strings-site-permissions.xml index 7d44715f9fd8..93f8720eb3c7 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-es/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-es/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + «%1$s» quiere abrir tu software DRM + El software de gestión de derechos digitales(DRM, por sus siglas en inglés) es necesario para reproducir contenido multimedia protegido, pero también proporciona acceso a identificadores de dispositivos. Concede permiso solo a los sitios a los que confíes estos datos. Puedes gestionar los permisos en cualquier momento en Ajustes. Más información + Siempre + Solo para esta sesión + Rechazar siempre + Rechazar para esta sesión + + + «%1$s» quiere acceder a tu ubicación + Recordar mi elección + Solo utilizamos tu ubicación anónima para ofrecer mejores resultados, más cerca de ti. Puedes gestionar los permisos de acceso a la ubicación que has concedido a sitios específicos en Ajustes. + Puedes gestionar los permisos de acceso a la ubicación que has concedido a sitios específicos en Ajustes. + Permitir que DuckDuckGo solicite acceso a la ubicación en este dispositivo + Los sitios solo pueden usar tu ubicación si permites que DuckDuckGo solicite acceso. + Permitir que DuckDuckGo solicite acceso a la ubicación + + + Permisos del sitio + Puedes gestionar los permisos de acceso al micrófono y a la cámara que has concedido a sitios específicos en Ajustes. + Puedes gestionar los permisos de acceso al micrófono que has concedido a sitios específicos en Ajustes. + Puedes gestionar los permisos de acceso a la cámara que has concedido a sitios específicos en Ajustes. \"%1$s\" quiere acceder a la cámara y al micrófono \"%1$s\" quiere acceder al micrófono \"%1$s\" quiere acceder a la cámara @@ -35,4 +57,20 @@ Los sitios solo pueden usar tu cámara y tu micrófono si permites que DuckDuckGo solicite acceso. Abrir configuración Cancelar + + Los sitios que visites pueden pedirte acceso a la ubicación de tu dispositivo, a la cámara, al micrófono o al software DRM (Gestión de Derechos Digitales). No podrán acceder a ellos a menos que les des permiso explícitamente. + Permitir que todos los sitios soliciten: + Ubicación + Cámara + Micrófono + Administrar sitios + Aún no hay sitios + Permisos eliminados para todos los sitios + Permisos para \"%1$s\" + Preguntar cada vez + Rechazar + Permitir + Desactivado para todos los sitios + %1$s permiso para %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-et/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-et/strings-site-permissions.xml index 4524f19e1c4a..eebb27aa8613 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-et/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-et/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + „%1$s“ soovib avada teie DRM-tarkvara + Digitaalsete õiguste haldamise tarkvara on vajalik kaitstud meediasisu esitamiseks, kuid see võimaldab ka juurdepääsu seadme identifikaatoritele. Anna luba ainult saitidele, mida sa usaldad. Saad õigusi igal ajal seadetes hallata. Lisateave + Alati + Ainult selle seansi jaoks + Keela alati + Keela selle seansi jaoks + + + „%1$s“ soovib juurdepääsu teie asukohale + Jäta mu valik meelde + Kasutame sinu anonüümset asukohta ainult selleks, et pakkuda paremaid tulemusi, mis on sulle lähemal. Saad hallata asukohale juurdepääsu luba, mille sa oled andnud üksikutele saitidele valikus Seaded. + Saad hallata asukohale juurdepääsu luba, mille sa oled andnud üksikutele saitidele valikus Seaded. + Luba DuckDuckGo’l küsida juurdepääsu selle seadme asukohale + Saidid saavad teie asukohta kasutada ainult siis, kui lubate DuckDuckGo’l küsida sellele juurdepääsu. + Luba DuckDuckGo’l küsida juurdepääsu asukohale + + + Saidi load + Saate hallata mikrofoni ja kaamera juurdepääsu lube, mille olete andnud üksikutele saitidele jaotises Seaded. + Saate hallata mikrofoni juurdepääsu lube, mille olete andnud üksikutele saitidele jaotises Seaded. + Saate hallata kaamera juurdepääsu lube, mille olete andnud üksikutele saitidele jaotises Seaded. „%1$s“ soovib juurdepääsu kaamerale ja mikrofonile „%1$s“ soovib juurdepääsu mikrofonile „%1$s“ soovib juurdepääsu kaamerale @@ -35,4 +57,20 @@ Saidid saavad sinu kaamerat ja mikrofoni kasutada ainult siis, kui lubad DuckDuckGo’l küsida sellele juurdepääsu. Ava sätted Tühista + + Külastatavad veebisaidid võivad küsida juurdepääsu sinu seadme asukohale, kaamerale, mikrofonile või DRM-i (Digital Rights Management) tarkvarale. Need ei saa juurdepääsu enne, kui oled selleks andnud selgesõnalise loa. + Luba kõigil saitidel küsida järgmist. + Asukoht + Kaamera + Mikrofon + Saitide haldamine + Saite pole veel + Kõikide saitide load on eemaldatud + Saidi „%1$s“ load + Küsi iga kord + Keela + Luba + Kõigi saitide jaoks keelatud + Luba %1$s saidile %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-fi/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-fi/strings-site-permissions.xml index 39d2b52aa2c3..4f03659d0c72 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-fi/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-fi/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" haluaa avata DRM-ohjelmistosi + Suojatun mediasisällön toistaminen vaatii Digital Rights Management -ohjelmiston, mutta se antaa lisäksi laitteen tunnisteiden käyttöluvan. Myönnä lupa vain sivustoille, joihin luotat näiden tietojen suhteen. Voit hallita lupia milloin vain asetuksissa. Lue lisää + Aina + Vain tässä istunnossa + Kiellä aina + Kiellä tässä istunnossa + + + \"%1$s\" haluaa käyttää sijaintiasi + Muista valintani + Käytämme anonyymiä sijaintia pelkästään tarjotaksemme parempia tuloksia lähempää sijaintiasi. Voit hallita yksittäisille sivustoille antamiasi sijaintilupia asetuksista. + Voit hallita yksittäisille sivustoille antamiasi sijaintilupia asetuksista. + Salli DuckDuckGon pyytää sijainnin käyttöoikeutta tällä laitteella + Sivustot voivat käyttää sijaintiasi vain, jos sallit DuckDuckGon pyytää sen käyttöoikeutta. + Salli DuckDuckGon pyytää sijainnin käyttöoikeutta + + + Sivuston käyttöoikeudet + Voit hallita yksittäisille sivustoille antamiasi mikrofonin ja kameran käyttöoikeuksia asetuksista. + Voit hallita yksittäisille sivustoille antamiasi mikrofonin käyttöoikeuksia asetuksista. + Voit hallita yksittäisille sivustoille antamiasi kameran käyttöoikeuksia asetuksista. \"%1$s\" haluaa käyttää kameraa ja mikrofonia \"%1$s\" haluaa käyttää mikrofonia \"%1$s\" haluaa käyttää kameraa @@ -35,4 +57,20 @@ Sivustot voivat käyttää kameraa ja mikrofonia vain, jos annat DuckDuckGon pyytää niiden käyttöoikeutta. Avaa asetukset Peruuta + + Käyttämäsi sivustot saattavat pyytää pääsyä laitteesi sijaintiin, kameraan, mikrofoniin tai DRM-ohjelmistoon (Digital Rights Management). Ne eivät voi käyttää tietoja, ellet myönnä niille erillistä käyttöoikeutta. + Salli kaikkien sivustojen pyytää: + Sijainti + Kamera + Mikrofoni + Hallitse sivustoja + Ei vielä yhtään sivustoa + Käyttöoikeudet poistettu kaikilta sivustoilta + Oikeudet: %1$s + Kysy joka kerta + Estä + Salli + Poistettu käytöstä kaikilla sivustoilla + %1$s: käyttöoikeus – lupa %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-fr/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-fr/strings-site-permissions.xml index cc9f69dee044..b4b124d8d934 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-fr/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-fr/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + « %1$s » souhaite ouvrir votre logiciel DRM + Le logiciel de gestion des droits numériques est nécessaire pour lire du contenu multimédia protégé, mais il permet également d\'accéder aux identifiants des appareils. N\'accordez l\'autorisation d\'accès à ces données qu\'aux sites auxquels vous faites confiance. Vous pouvez gérer les autorisations à tout moment dans Paramètres. En savoir plus + Toujours + Seulement pour cette session + Toujours refuser + Refuser pour cette session + + + « %1$s » souhaite accéder à votre position + Mémoriser mon choix + Nous n\'utilisons votre localisation anonyme que pour vous fournir de meilleurs résultats, plus proches de vous. Vous pouvez gérer les autorisations d\'accès à la localisation accordées aux différents sites depuis les paramètres. + Vous pouvez gérer les autorisations d\'accès à la localisation accordées aux différents sites depuis les paramètres. + Autoriser DuckDuckGo à demander l\'accès à la localisation sur cet appareil + Les sites ne peuvent utiliser votre position que si vous autorisez DuckDuckGo à demander l\'accès. + Autoriser DuckDuckGo à demander l\'accès à la localisation + + + Autorisations du site + Vous pouvez gérer les autorisations d\'accès au micro et à l\'appareil photo accordées aux différents sites depuis les paramètres. + Vous pouvez gérer les autorisations d\'accès au micro accordées aux différents sites depuis les paramètres. + Vous pouvez gérer les autorisations d\'accès à l\'appareil photo accordées aux différents sites depuis les paramètres. « %1$s » souhaite accéder à l\'appareil photo et au micro « %1$s » souhaite accéder au micro « %1$s » souhaite accéder à l\'appareil photo @@ -35,4 +57,20 @@ Les sites ne peuvent utiliser votre appareil photo et votre micro que si vous autorisez DuckDuckGo à demander l\'accès. Ouvrir les paramètres Annuler + + Les sites que vous visitez sont susceptibles de demander l\'accès à la localisation, à l\'appareil photo, au micro ou au logiciel DRM (gestion des droits numériques) de votre appareil. Ils ne pourront y accéder que si vous leur en donnez explicitement la permission. + Autoriser tous les sites à demander : + Localisation + Appareil photo + Micro + Gérer les sites + Pas encore de sites + Autorisations supprimées pour tous les sites + Autorisations pour « %1$s » + Toujours demander + Refuser + Autoriser + Désactivé pour tous les sites + Autorisation de %1$s pour %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-hr/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-hr/strings-site-permissions.xml index 496137844f2f..d23fe9afca33 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-hr/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-hr/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" želi otvoriti tvoj DRM softver + Softver za upravljanje digitalnim pravima potreban je za reprodukciju zaštićenog medijskog sadržaja, ali i za pristup identifikatorima uređaja. Pruži dopuštenje samo web lokacijama kojima vjeruješ u vezi s rukovanjem ovim podacima. Dopuštenjima možeš upravljati u svakom trenutku u Postavkama. Saznaj više + Uvijek + Samo za ovu sesiju + Uvijek odbij + Odbij za ovu sesiju + + + \"%1$s\" želi pristupiti tvojoj lokaciji + Zapamti moj izbor + Tvoju anonimnu lokaciju koristimo samo za postizanje boljih rezultata, bliže tebi. U postavkama možeš upravljati dozvolama za pristup lokaciji koje si dodijelio pojedinim web-mjestima. + U postavkama možete upravljati dozvolama za pristup lokaciji koje ste dodijelili pojedinim web-mjestima. + Dopusti DuckDuckGou da zatraži pristup lokaciji na ovom uređaju + Web-mjesta mogu koristiti tvoju lokaciju samo ako dopustiš DuckDuckGou da zatraži pristup. + Dopusti DuckDuckGou da zatraži pristup lokaciji + + + Dozvole web lokacija + U postavkama možeš upravljati dozvolama za pristup mikrofonu i kameri koje si dodijelio pojedinim web-mjestima. + U postavkama možeš upravljati dozvolama za pristup mikrofonu koje si dodijelio pojedinim web-mjestima. + U postavkama možeš upravljati dozvolama za pristup kameri koje si dodijelio pojedinim web-mjestima. \"%1$s\" želi pristupiti kameri i mikrofonu \"%1$s\" želi pristupiti mikrofonu \"%1$s\" želi pristupiti kameri @@ -35,4 +57,20 @@ Stranice mogu koristiti tvoju kameru i mikrofon samo ako dopustiš DuckDuckGou da zatraži pristup. Otvori postavke Otkaži + + Stranice koje posjećuješ mogu tražiti pristup lokaciji tvog uređaja, fotoaparatu, mikrofonu ili DRM (Digital Rights Management) softveru. Neće im moći pristupiti osim ako im za to izričito ne daš dopuštenje. + Dopusti svim web-lokacijama da zatraže: + Lokacija + Kamera + Mikrofon + Upravljanje web-lokacijama + Još nema ni jedne web-lokacije + Uklonjena su dopuštenja za sve web lokacije + Dopuštenja za „%1$s“ + Pitaj svaki puta + Odbij + Dopusti + Onemogućeno za sva web-mjesta + %1$s dopuštenje za %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-hu/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-hu/strings-site-permissions.xml index efe07328d238..1b1a665460c3 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-hu/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-hu/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + A(z) „%1$s” meg akarja nyitni a DRM-szoftveredet + A digitális jogosultságokat kezelő szoftver a védett médiatartalmak lejátszásához szükséges, de az eszközazonosítókhoz is hozzáférést biztosít. Csak olyan webhelyeknek adj engedélyt ezekhez az adatokhoz, amelyekben megbízol. Az engedélyek bármikor kezelhetők a Beállításokban. További tudnivalók + Mindig + Csak erre a munkamenetre + Mindig megtagad + Megtagad erre a munkamenetre + + + A(z) „%1$s” hozzá akar férni a tartózkodási helyedhez + Választott beállítás megjegyzése + Az anonim tartózkodási helyedet csak arra használjuk, hogy jobb, hozzád közelebbi találatokat tudjunk adni. A Beállításokban kezelheted az egyes webhelyeknek megadott helyhozzáférési engedélyeket. + Az egyes webhelyeknek megadott helyhozzáférési engedélyeket a Beállításokban kezelheted. + Engedélyezés, hogy a DuckDuckGo hozzáférést kérjen a tartózkodási helyhez ezen az eszközön + A webhelyek csak akkor használhatják a tartózkodási helyet, ha engedélyezed, hogy a DuckDuckGo hozzáférést kérjen. + Engedélyezés, hogy a DuckDuckGo hozzáférést kérjen a tartózkodási helyhez + + + Webhelyengedélyek + A Beállításokban kezelheted az egyes webhelyeknek megadott mikrofon- és kamera-hozzáférési engedélyeket. + A Beállításokban kezelheted az egyes webhelyeknek megadott mikrofon-hozzáférési engedélyeket. + A Beállításokban kezelheted az egyes webhelyeknek megadott kamera-hozzáférési engedélyeket. A(z) „%1$s” hozzá akar férni a kamerához és a mikrofonhoz A(z) „%1$s” hozzá akar férni a mikrofonhoz A(z) „%1$s” hozzá akar férni a kamerához @@ -35,4 +57,20 @@ A webhelyek csak akkor használhatják a kamerát és a mikrofont, ha engedélyezed, hogy a DuckDuckGo hozzáférést kérjen. Beállítások megnyitása Mégsem + + A meglátogatott webhelyek hozzáférést kérhetnek az eszköz helyéhez, kamerájához, mikrofonjához vagy a digitális jogosultságokat kezelő (DRM) szoftveréhez. Ezekhez nem férhetnek hozzá, hacsak nem adsz rá kifejezett engedélyt. + Minden webhely kérheti a következőket: + Hely + Kamera + Mikrofon + Webhelyek kezelése + Még nincsenek oldalak + Minden webhely engedélye eltávolítva + Engedélyek a következőhöz: „%1$s” + Kérdezzen rá minden alkalommal + Megtagadás + Engedélyezés + Letiltva minden webhely számára + %1$s engedély a(z) %2$s számára + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-it/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-it/strings-site-permissions.xml index c749814115a4..a2051ff4349c 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-it/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-it/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" vuole aprire il tuo software DRM + Il software di gestione dei diritti digitali è necessario per riprodurre contenuti multimediali protetti, ma consente anche di accedere agli identificatori dei dispositivi. Concedi l\'autorizzazione per questi dati solo ai siti di cui ti fidi. Puoi gestire le autorizzazioni in qualsiasi momento in Impostazioni. Maggiori informazioni + Sempre + Solo per questa sessione + Nega sempre + Nega per questa sessione + + + \"%1$s\" vuole accedere alla tua posizione + Ricorda la mia scelta + Usiamo la tua posizione anonima solo per offrirti risultati migliori, più vicini a te. Puoi gestire le autorizzazioni di accesso alla posizione concesse ai singoli siti in Impostazioni. + Puoi gestire le autorizzazioni di accesso alla posizione concesse ai singoli siti in Impostazioni. + Consenti a DuckDuckGo di chiedere l\'accesso alla posizione su questo dispositivo + I siti possono utilizzare la tua posizione solo se consenti a DuckDuckGo di richiederne l\'accesso. + Consenti a DuckDuckGo di chiedere la posizione + + + Autorizzazioni del sito + Puoi gestire le autorizzazioni di accesso al microfono e alla fotocamera concesse ai singoli siti in Impostazioni. + Puoi gestire le autorizzazioni di accesso al microfono concesse ai singoli siti in Impostazioni. + Puoi gestire le autorizzazioni di accesso alla fotocamera concesse ai singoli siti in Impostazioni. \"%1$s\" vuole accedere alla fotocamera e al microfono \"%1$s\" vuole accedere al microfono \"%1$s\" vuole accedere alla fotocamera @@ -35,4 +57,20 @@ I siti possono utilizzare la fotocamera e il microfono solo se consenti a DuckDuckGo di richiederne l\'accesso. Apri Impostazioni Annulla + + I siti che visiti potrebbero richiedere l\'accesso al software di localizzazione, videocamera, microfono o DRM (Digital Rights Management) del tuo dispositivo. Non potranno accedervi finché non darai il consenso esplicito. + Consenti a tutti i siti di richiedere: + Posizione + Fotocamera + Microfono + Gestisci siti + Non esistono ancora siti + Autorizzazioni rimosse per tutti i siti + Autorizzazioni per \"%1$s\" + Chiedi ogni volta + Rifiuta + Consenti + Disattivato per tutti i siti + Autorizzazione %1$s per %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-lt/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-lt/strings-site-permissions.xml index 43969d70a886..7373e62646cf 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-lt/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-lt/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + „%1$s“ nori atidaryti jūsų DRM programinę įrangą + Skaitmeninių teisių valdymo programinė įranga reikalinga norint atkurti apsaugotą medijos turinį, bet taip pat suteikia prieigą prie įrenginio identifikatorių. Suteikite leidimą tik toms svetainėms, kurioms patikite šiuos duomenis. Leidimus bet kada galite tvarkyti nustatymuose. Sužinokite daugiau + Visada + Tik šiam seansui + Visada atsisakyti + Atsisakyti šiam seansui + + + „%1$s“ nori pasiekti jūsų vietą + Įsiminti mano pasirinkimą + Jūsų anoniminę buvimo vietą naudojame tik tam, kad galėtume pateikti geresnius rezultatus arčiau jūsų. Galite tvarkyti vietos prieigos leidimus, kuriuos nustatymuose suteikėte pavienėms svetainėms. + Galite tvarkyti vietos prieigos leidimus, kuriuos nustatymuose suteikėte pavienėms svetainėms. + Leisti „DuckDuckGo“ prašyti vietos prieigos šiame įrenginyje + Svetainės gali naudoti jūsų buvimo vietą tik tada, jei leisite „DuckDuckGo“ prašyti prieigos. + Leisti „DuckDuckGo“ prašyti vietos prieigos + + + Svetainės leidimai + Galite tvarkyti mikrofonų ir kamerų prieigos leidimus, kuriuos Nustatymuose suteikėte atskiroms svetainėms. + Galite tvarkyti mikrofonų prieigos leidimus, kuriuos Nustatymuose suteikėte atskiroms svetainėms. + Galite tvarkyti kamerų prieigos leidimus, kuriuos Nustatymuose suteikėte atskiroms svetainėms. „%1$s“ nori gauti prieigą prie fotoaparato ir mikrofono „%1$s“ nori gauti prieigą prie mikrofono „%1$s“ nori gauti prieigą prie fotoaparato @@ -35,4 +57,20 @@ Svetainės gali naudoti jūsų kamerą ir mikrofoną tik tada, jei leisite „DuckDuckGo“ prašyti prieigos. Atidaryti nustatymus Atšaukti + + Svetainėse, kuriose lankotės, gali būti prašoma prieigos prie jūsų įrenginio buvimo vietos, kameros, mikrofono arba DRM (skaitmeninių teisių valdymo) programinės įrangos. Jos negalės prie jų prisijungti, nebent aiškiai suteiksite joms leidimą. + Leisti visoms svetainėms prašyti: + Vieta + Fotoaparatas + Mikrofonas + Tvarkyti svetaines + Svetainių dar nėra + Pašalinti visų svetainių leidimai + Leidimai „%1$s“ + Klausti kiekvieną kartą + Atsisakyti + Leisti + Išjungta visose svetainėse + %1$s leidimas %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-lv/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-lv/strings-site-permissions.xml index 0f2235179a9a..2af8ef88cef8 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-lv/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-lv/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" grib atvērt tavu DRM programmatūru + Lai atskaņotu aizsargātu multivides saturu, ir nepieciešama digitālo tiesību pārvaldības programmatūra, kas nodrošina arī piekļuvi ierīces identifikatoriem. Piešķir atļauju tikai tām vietnēm, kurām uztici šos datus. Atļaujas jebkurā laikā vari pārvaldīt iestatījumos. Uzzināt vairāk + Vienmēr + Tikai šai sesijai + Vienmēr aizliegt + Aizliegt šai sesijai + + + \"%1$s\" grib piekļūt tavai atrašanās vietai + Atcerēties manu izvēli + Mēs izmantojam tavu anonīmo atrašanās vietu tikai tam, lai sniegtu labākus rezultātus tuvāk tev. Iestatījumu sadaļā vari pārvaldīt atrašanās vietas piekļuves atļaujas, kas piešķirtas atsevišķām vietnēm. + Iestatījumu sadaļā vari pārvaldīt atrašanās vietas piekļuves atļaujas, ko piešķīri atsevišķām vietnēm. + Atļaut DuckDuckGo pieprasīt piekļuvi atrašanās vietai šajā ierīcē + Vietnes var izmantot tavu atrašanās vietu tikai tad, ja tu atļauj DuckDuckGo pieprasīt piekļuvi. + Atļauj DuckDuckGo prasīt piekļuvi atrašanās vietai + + + Vietnes atļaujas + Iestatījumu sadaļā tu vari pārvaldīt mikrofonam un kamerai piešķirtās piekļuves atļaujas atsevišķām vietnēm. + Iestatījumu sadaļā tu vari pārvaldīt mikrofona piekļuves atļaujas, kas ir piešķirtas atsevišķām vietnēm. + Iestatījumu sadaļā tu vari pārvaldīt kameras piekļuves atļaujas, kas ir piešķirtas atsevišķām vietnēm. \"%1$s\" vēlas piekļūt kamerai un mikrofonam \"%1$s\" vēlas piekļūt mikrofonam \"%1$s\" vēlas piekļūt kamerai @@ -35,4 +57,20 @@ Vietnes var izmantot tavu kameru un mikrofonu tikai tad, ja tu atļauj DuckDuckGo prasīt piekļuvi. Atvērt iestatījumus Atcelt + + Apmeklētās vietnes var pieprasīt piekļuvi tavas ierīces atrašanās vietai, kamerai, mikrofonam vai DRM (digitālā satura tiesību pārvaldības) programmatūrai. Tās nevarēs tiem piekļūt, ja vien īpaši nedosi attiecīgo atļauju. + Ļaut visām vietnēm prasīt: + Atrašanās vieta + Kamera + Mikrofons + Pārvaldīt vietnes + Vēl nav nevienas vietnes + Atļaujas ir noņemtas visām vietnēm + Atļaujas vietnei \"%1$s\" + Jautāt katru reizi + Liegt + Atļaut + Atspējots visām vietnēm + %1$s – atļauja vietnei %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-nb/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-nb/strings-site-permissions.xml index 8d8c51a1b28f..006f3f8392c3 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-nb/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-nb/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + «%1$s» ønsker å åpne DRM-programvaren din + Programvare for digital rettighetsadministrasjon er nødvendig for å spille av beskyttet medieinnhold, men gir også tilgang til enhetsidentifikatorer. Gi bare tillatelse til nettsteder du stoler på med disse dataene. Du kan administrere tillatelser når som helst i Innstillinger. Les mer + Alltid + Kun for denne økten + Aldri tillat + Ikke tillat for denne økten + + + «%1$s» ønsker tilgang til posisjonen din + Husk valget mitt + Vi bruker den anonyme posisjonen kun til å levere bedre resultater, i nærheten av deg. I innstillingene kan du administrere posisjonstillatelser du har gitt til enkeltsider. + Du kan administrere posisjonstillatelser du har gitt til enkeltsider under Innstillinger. + La DuckDuckGo be om posisjonstilgang på denne enheten + Nettsteder kan bare bruke posisjonen din hvis du lar DuckDuckGo be om tilgang. + La DuckDuckGo be om posisjonstilgang + + + Nettstedstillatelser + Du kan administrere mikrofon- og kameratillatelser du har gitt individuelle nettsteder, i Innstillinger. + Du kan administrere mikrofontillatelser du har gitt individuelle nettsteder, i Innstillinger. + Du kan administrere kameratillatelser du har gitt individuelle nettsteder, i Innstillinger. «%1$s» vil ha tilgang til kameraet og mikrofonen «%1$s» vil ha tilgang til mikrofonen «%1$s» vil ha tilgang til kameraet @@ -35,4 +57,20 @@ Nettsteder kan bare bruke kameraet og mikrofonen din hvis du lar DuckDuckGo be om tilgang. Åpne innstillinger Avbryt + + Nettsteder du besøker, kan be om tilgang til enhetens posisjon, kamera, mikrofon eller DRA-programvare (digital rettighetsadministrasjon). De får ikke tilgang til disse med mindre du uttrykkelig gir dem tillatelse. + Tillat alle nettsteder å be om: + Posisjon + Kamera + Mikrofon + Administrer nettsteder + Ingen nettsteder ennå + Tillatelser fjernet for alle nettsteder + Tillatelser for «%1$s» + Spør hver gang + Avvis + Tillat + Deaktivert for alle nettsteder + %1$stillatelse for %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-nl/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-nl/strings-site-permissions.xml index 45cf76a5af48..beeb1ba96ff5 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-nl/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-nl/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \'%1$s\' wil je DRM-software openen + Digital Rights Management-software is nodig om beveiligde mediacontent af te spelen, maar biedt ook toegang tot apparaatherkenners. Geef alleen toestemming aan sites die je vertrouwt met deze gegevens. Je kunt de machtigingen op elk moment beheren in de instellingen. Meer informatie + Altijd + Alleen voor deze sessie + Altijd weigeren + Weigeren voor deze sessie + + + \'%1$s\' wil toegang tot je locatie + Mijn keuze onthouden + We gebruiken je anonieme locatie alleen om betere resultaten bij je in de buurt aan te bieden. De locatietoegangsmachtigingen die je aan individuele sites hebt gegeven, kun je beheren in Instellingen. + De locatietoegangsmachtigingen die je aan individuele sites hebt gegeven, kun je beheren in Instellingen. + DuckDuckGo toestaan om toegang tot de locatie op dit apparaat te vragen + Sites kunnen je locatie alleen gebruiken als je DuckDuckGo toestaat om toegang te vragen. + DuckDuckGo toestaan om toegang tot locatie te vragen + + + Sitetoestemmingen + Je kunt de toegangsrechten voor microfoon en camera die je aan individuele sites hebt verleend, beheren in Instellingen. + Je kunt de toegangsrechten voor microfoon die je aan individuele sites hebt verleend, beheren in Instellingen. + Je kunt de toegangsrechten voor camera die je aan individuele sites hebt verleend, beheren in Instellingen. \'%1$s\' wil toegang tot de camera en microfoon \'%1$s\' wil toegang tot de microfoon \'%1$s\' wil toegang tot de camera @@ -35,4 +57,20 @@ Sites kunnen je camera en microfoon alleen gebruiken als je DuckDuckGo toestaat om toegang te vragen. Open Instellingen Annuleren + + Sites die je bezoekt, kunnen toegang vragen tot de software, je camera, je microfoon of DRM (Digital Rights Management) op je apparaat. Ze krijgen die toegang alleen als je daar expliciet toestemming voor geeft. + Sta alle sites toe om het volgende vragen: + Locatie + Camera + Microfoon + Sites beheren + Nog geen sites + Toestemmingen verwijderd voor alle sites + Toestemmingen voor \'%1$s\' + Elke keer vragen + Weigeren + Toestaan + Uitgeschakeld voor alle sites + Toestemming voor %1$s voor %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-pl/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-pl/strings-site-permissions.xml index 925bfa4cd434..79668ba057e5 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-pl/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-pl/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + „%1$s” chce uzyskać dostęp do oprogramowania DRM + Oprogramowanie Digital Rights Management jest wymagane do odtwarzania chronionych treści multimedialnych, ale zapewnia również dostęp do identyfikatorów urządzeń. Udzielaj zgody na dostęp do tych danych tylko witrynom, którym ufasz. W każdej chwili możesz zarządzać uprawnieniami w ustawieniach. Dowiedz się więcej + Zawsze + Tylko dla tej sesji + Zawsze odmawiaj + Odmów w tej sesji + + + „%1$s” chce uzyskać dostęp do lokalizacji + Zapamiętaj mój wybór + Używamy Twojej anonimowej lokalizacji tylko po to, aby zapewnić lepsze wyniki bliżej Ciebie. Uprawnieniami dostępu do lokalizacji przyznanymi poszczególnym witrynom możesz zarządzać w Ustawieniach. + Uprawnieniami dostępu do lokalizacji przyznanymi poszczególnym witrynom możesz zarządzać w Ustawieniach. + Zezwól aplikacji DuckDuckGo na żądanie dostępu do lokalizacji na tym urządzeniu + Witryny będą mogły wykorzystać Twoją lokalizację, tylko jeśli zezwolisz aplikacji DuckDuckGo na żądanie dostępu. + Zezwól DuckDuckGo na żądanie dostępu do lokalizacji + + + Uprawnienia witryny + Uprawnieniami dostępu do mikrofonu i kamery przyznanymi poszczególnym witrynom możesz zarządzać w ustawieniach. + Uprawnieniami dostępu do lokalizacji przyznanymi poszczególnym witrynom możesz zarządzać w ustawieniach. + Uprawnieniami dostępu do kamery przyznanymi poszczególnym witrynom możesz zarządzać w ustawieniach. „%1$s” chce uzyskać dostęp do aparatu i mikrofonu „%1$s” chce uzyskać dostęp do mikrofonu „%1$s” chce uzyskać dostęp do aparatu @@ -35,4 +57,20 @@ Witryny mogą korzystać z Twojej kamery i mikrofonu tylko wtedy, gdy pozwolisz DuckDuckGo poprosić o dostęp. Otwórz ustawienia Anuluj + + Strony, które odwiedzasz, mogą prosić o dostęp do lokalizacji urządzenia, kamery, mikrofonu lub oprogramowania DRM (Digital Rights Management). Nie będą miały do nich dostępu, jeśli nie udzielisz im zgody. + Pozwól wszystkim stronom prosić o: + Lokalizacja + Aparat + Mikrofon + Zarządzaj witrynami + Nie masz jeszcze witryn + Usunięto uprawnienia wszystkich witryn + Uprawnienia dla: „%1$s” + Pytaj za każdym razem + Odmów + Zezwól + Wyłączono dla wszystkich witryn + Pozwolenie dla witryny %2$s na dostęp do urządzenia: %1$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-pt/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-pt/strings-site-permissions.xml index 26d867e42dfb..423bd6d39470 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-pt/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-pt/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" quer abrir o teu software DRM + O software de gestão de direitos digitais é necessário para reproduzir conteúdo multimédia protegido, mas também fornece acesso a identificadores do dispositivo. Concede permissão apenas a sites de confiança. Podes gerir as permissões em qualquer altura nas Definições. Sabe mais + Sempre + Apenas para esta sessão + Negar sempre + Negar para esta sessão + + + \"%1$s\" quer aceder à tua localização + Memorizar a minha opção + Só utilizamos a tua localização anónima para apresentar resultados melhores mais perto de ti. Podes gerir as permissões de acesso à localização concedidas a sites individuais nas Definições. + Pode gerir as permissões de acesso à localização concedidas a sites individuais nas Definições. + Permitir que o DuckDuckGo peça acesso à localização neste dispositivo + Os sites só podem utilizar a tua localização se autorizares o DuckDuckGo a pedir acesso. + Permitir que o DuckDuckGo peça acesso à localização + + + Permissões dos sites + Podes gerir as permissões de acesso ao microfone e à câmara concedidas a sites individuais nas Definições. + Podes gerir as permissões de acesso ao microfone concedidas a sites individuais nas Definições. + Podes gerir as permissões de acesso à câmara concedidas a sites individuais nas Definições. \"%1$s\" pretende aceder à câmara e ao microfone \"%1$s\" pretende aceder ao microfone \"%1$s\" pretende aceder à câmara @@ -35,4 +57,20 @@ Os sites só podem utilizar a tua câmara e microfone se autorizares o DuckDuckGo a pedir acesso. Abrir Definições Cancelar + + Os sites que visitas podem pedir acesso à localização, câmara, microfone ou DRM (Digital Rights Management) do teu dispositivo. Não poderão aceder a estas funcionalidades sem que concedas permissão explicitamente. + Permitir que todos os sites peçam: + Localização + Câmara + Microfone + Gerir sites + Ainda não há sites + As permissões foram removidas para todos os sites + Permissões para \"%1$s\" + Pergunte todas as vezes + Recusar + Permitir + Desativado para todos os sites + Permissão para %2$s utilizar %1$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-ro/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-ro/strings-site-permissions.xml index 1037c86efd16..45cc763b45a1 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-ro/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-ro/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + „%1$s” dorește să-ți deschidă software-ul DRM + Software-ul DRM este necesar pentru a reda conținut media protejat, dar oferă, de asemenea, acces la identificatorii dispozitivelor. Acordă permisiunea de a utiliza aceste date numai site-urilor în care ai încredere. Poți gestiona oricând permisiunile din Setări. Află mai multe + Întotdeauna + Numai pentru această sesiune + Respinge întotdeauna + Respinge pentru această sesiune + + + „%1$s” dorește să-ți acceseze locația + Reține alegerea mea + Utilizăm locația ta anonimă doar pentru a oferi rezultate mai bune, mai aproape de tine. Poți gestiona permisiunile de acces la locație pe care le-ai acordat site-urilor individuale în Setări. + Poți gestiona permisiunile de acces la locație pe care le-ai acordat site-urilor individuale în Setări. + Permite DuckDuckGo să solicite acces la locația ta pe acest dispozitiv + Site-urile îți pot utiliza locația numai dacă permiți ca DuckDuckGo să solicite accesul. + Permite ca DuckDuckGo să solicite accesul la locație + + + Permisiuni pentru site + Poți gestiona permisiunile de acces la microfon și cameră pe care le-ai acordat site-urilor individuale în Setări. + Poți gestiona permisiunile de acces la microfon pe care le-ai acordat site-urilor individuale în Setări. + Poți gestiona permisiunile de acces la cameră pe care le-ai acordat site-urilor individuale în Setări. „%1$s” dorește să acceseze camera și microfonul „%1$s” dorește să acceseze microfonul „%1$s” dorește să acceseze camera @@ -35,4 +57,20 @@ Site-urile îți pot utiliza camera și microfonul numai dacă permiți ca DuckDuckGo să solicite accesul. Deschide Setări Anulează + + Site-urile pe care le accesezi îți pot solicita accesul la locația dispozitivului, la camera foto, la microfon sau la software-ul DRM (Digital Rights Management). Acestea nu vor putea accesa aceste date decât dacă le oferi în mod explicit permisiunea. + Permite tuturor site-urilor să solicite: + Locație + Aparat foto + Microfon + Gestionează site-urile + Niciun site încă + Permisiuni eliminate pentru toate site-urile + Permisiuni pentru „%1$s” + Întreabă de fiecare dată + Refuză + Permite + Dezactivat pentru toate site-urile + Permisiune %1$s pentru %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-ru/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-ru/strings-site-permissions.xml index 883865652975..a4237adc9431 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-ru/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-ru/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + Сайт «%1$s» хочет открывать ваши программы DRM (защиты авторских прав) + Программы защиты авторских прав (DRM) необходимы для воспроизведения защищенного медиаконтента, однако они также открывают доступ к идентификатором устройства. Предоставляйте доступ только тем сайтам, которым вы доверяете. Права доступа можно изменить в «Настройках». Подробнее... + Всегда + Только для этой сессии + Всегда отказывать + Отказать для этой сессии + + + Сайт «%1$s» запрашивает доступ к вашей геопозиции + Запомнить выбор + Анонимная геопозиция нужна только для поиска подходящих результатов поблизости. Доступ к геопозиции, предоставленный отдельным сайтам, можно проконтролировать в настройках. + Вы можете управлять разрешениями на доступ к геопозиции, которые вы предоставили отдельным сайтам, в настройках. + Разрешить DuckDuckGo запрашивать доступ к геопозиции на этом устройстве + Если разрешить DuckDuckGo запрашивать доступ, сайты получат только вашу геопозицию. + Разрешить DuckDuckGo запрашивать доступ к геопозиции + + + Разрешения для сайтов + Доступ к микрофону и камере, предоставленный отдельным сайтам, можно проконтролировать в настройках. + Доступ к микрофону, предоставленный отдельным сайтам, можно проконтролировать в настройках. + Доступ к камере, предоставленный отдельным сайтам, можно проконтролировать в настройках. «%1$s» запрашивает доступ к камере и микрофону «%1$s» запрашивает доступ к микрофону «%1$s» запрашивает доступ к камере @@ -35,4 +57,20 @@ Если вы разрешите DuckDuckGo запрашивать доступ, сайты смогут использовать только камеру и микрофон. Открыть Настройки Отменить + + Посещаемые вами сайты могут запрашивать доступ к геопозиции, камере, микрофону или программам DRM (защиты авторских прав) вашего устройства. Доступ предоставляется только с вашего разрешения. + Разрешить всем сайтам запрашивать: + Геопозиция + Камера + Микрофон + Управление сайтами + Пока нет сайтов + Разрешения удалены для всех сайтов + Разрешения для «%1$s» + Спрашивать каждый раз + Отказать + Разрешить + Отключено в отношении всех сайтов + Разрешение на доступ %2$s к %1$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-sk/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-sk/strings-site-permissions.xml index a0dddf41140e..040b64469c45 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-sk/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-sk/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + „%1$s“ chce otvoriť tvoj softvér DRM + Softvér Digital Rights Management je potrebný na prehrávanie chráneného mediálneho obsahu, no poskytuje aj prístup k identifikátorom zariadenia. Povolenie pre tieto údaje povoľte iba stránkam, ktorým dôverujete. Povolenia môžete kedykoľvek spravovať v Nastaveniach. Zistiť viac + Vždy + Iba pre túto reláciu + Vždy odmietnuť + Odmietnuť pre túto reláciu + + + „%1$s“ chce získať prístup k tvojej polohe + Zapamätať si moju voľbu + Používame vašu anonymnú polohu len na to, aby sme vám mohli ponúknuť lepšie výsledky, ktoré sú bližšie k vám. Povolenia na prístup k polohe, ktoré ste udelili jednotlivým webovým stránkam, môžete spravovať v Nastaveniach. + Povolenia na prístup k polohe, ktoré ste udelili jednotlivým webovým stránkam, môžete spravovať v Nastaveniach. + Povoliť aplikácii DuckDuckGo žiadať o prístup k polohe v tomto zariadení + Lokality môžu používať tvoju polohu len vtedy, ak povolíš aplikácii DuckDuckGo žiadať o prístup k nej. + Povoliť aplikácii DuckDuckGo žiadať o prístup k polohe + + + Oprávnenia na lokalitu + Povolenia na prístup k mikrofónu a kamere, ktoré si udelil/-a jednotlivým webovým stránkam, môžeš spravovať v Nastaveniach. + V Nastaveniach môžeš spravovať povolenia na prístup k mikrofónu, ktoré si udelil/-a jednotlivým webovým stránkam. + Povolenia na prístup ku kamere, ktoré si udelil/-a jednotlivým webovým stránkam, môžeš spravovať v Nastaveniach. \"%1$s\" chce získať prístup k fotoaparátu a mikrofónu \"%1$s\"chce získať prístup k mikrofónu \"%1$s\" chce mať prístup k fotoaparátu @@ -35,4 +57,20 @@ Lokality môžu používať váš fotoaparát a mikrofón len vtedy, ak povolíte aplikácii DuckDuckGo žiadať o prístup. Otvoriť nastavenia Zrušiť + + Stránky, ktoré navštívite, môžu požiadať o prístup k polohe vášho zariadenia, fotoaparátu, mikrofónu alebo softvéru DRM (Digital Rights Management). Nebudú mať k nim prístup, pokiaľ im to výslovne nepovolíte. + Povoliť všetkým lokalitám žiadať o: + Poloha + Kamera + Mikrofón + Správa lokalít + Zatiaľ žiadne lokality + Povolenia boli odstránené pre všetky lokality + Povolenia pre „%1$s” + Vždy sa opýtať + Odmietnuť + Povoliť + Zakázané pre všetky lokality + %1$s povolenie pre %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-sl/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-sl/strings-site-permissions.xml index b3e4763f9476..2021ab6125de 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-sl/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-sl/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + »%1$s« želi odpreti vašo programsko opremo DRM. + Programska oprema za upravljanje digitalnih pravic je potrebna za predvajanje zaščitene medijske vsebine, omogoča pa tudi dostop do identifikatorjev naprave. Dovoljenje za uporabo teh podatkov podelite le spletnim mestom, ki jim zaupate te podatke. Dovoljenja lahko kadar koli upravljate v nastavitvah. Več o tem + Vedno + Samo za to sejo + Vedno zavrni + Zavrni za to sejo + + + »%1$s« želi dostopati do vaše lokacije + Zapomni si mojo izbiro + Vašo anonimno lokacijo uporabljamo le za zagotavljanje boljših rezultatov, bližje vam. Dovoljenja za dostop do lokacije, ki ste jih podelili posameznim spletnim mestom, lahko upravljate v nastavitvah. + Dovoljenja za dostop do lokacije, ki ste jih podelili posameznim spletnim mestom, lahko upravljate v nastavitvah. + Dovolite DuckDuckGo, da zahteva dostop do lokacije v tej napravi + Spletna mesta lahko uporabljajo vašo lokacijo le, če dovolite, da DuckDuckGo zaprosi za dostop. + Dovolite, da lahko spletno mesto DuckDuckGo zahteva dostop do lokacije + + + Dovoljenja za spletno mesto + Dovoljenja za dostop do mikrofona in fotoaparata, ki ste jih podelili posameznim spletnim mestom, lahko upravljate v nastavitvah. + Dovoljenja za dostop do mikrofona, ki ste jih podelili posameznim spletnim mestom, lahko upravljate v nastavitvah. + Dovoljenja za dostop do fotoaparata, ki ste jih podelili posameznim spletnim mestom, lahko upravljate v nastavitvah. »%1$s« želi dostopati do kamere in mikrofona »%1$s« želi dostopati do mikrofona »%1$s« želi dostopati do kamere @@ -35,4 +57,20 @@ Spletna mesta lahko uporabljajo vašo kamero in mikrofon le, če dovolite, da DuckDuckGo zaprosi za dostop. Odpri nastavitve Preklic + + Spletna mesta, ki jih obiščete, lahko zahtevajo dostop do lokacije, kamere, mikrofona ali programske opreme DRM (Digital Rights Management) vaše naprave. Do njih ne bodo mogla dostopati, razen če jim to izrecno dovolite. + Dovoli vsem mestom, da zahtevajo: + Lokacija + Kamera + Mikrofon + Upravljanje spletnih mest + Spletnih mest še ni + Dovoljenja so odstranjena za vsa spletna mesta + Dovoljenja za »%1$s« + Vprašaj vsakič + Zavrni + Dovoli + Onemogočeno za vsa spletna mesta + %1$s dovoljenje za %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-sv/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-sv/strings-site-permissions.xml index d94cf406c675..21df8c31fb47 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-sv/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-sv/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + ”%1$s” vill öppna din DRM-programvara + DRM-programvara (Digital Rights Management) krävs för att spela upp skyddat medieinnehåll, men ger också tillgång till enhetsidentifierare. Ge endast behörighet att hantera dessa uppgifter till webbplatser du litar på.Du kan hantera behörigheter när som helst i Inställningar. Läs mer + Alltid + Endast för denna session + Neka alltid + Neka för denna session + + + ”%1$s” vill komma åt din plats + Kom ihåg mitt val + Vi använder bara din anonyma plats för att ge dig bättre resultat, närmare dig. Du kan gå till Inställningar för att hantera åtkomster till din enhets platsinformation som du har beviljat för enskilda webbplatser. + Du kan gå till Inställningar för att hantera åtkomster till din enhets platsinf\bormation som du har beviljat för enskilda webbplatser. + Tillåt DuckDuckGo att be om platsåtkomst på den här enheten + Webbplatser kan endast använda din plats om du tillåter DuckDuckGo att be om åtkomst. + Tillåt DuckDuckGo att be om platsåtkomst + + + Webbplatsbehörigheter + Du kan gå till Inställningar för att hantera åtkomst som du har beviljat för enskilda webbplatser till enhetens mikrofon och kamera. + Du kan gå till Inställningar för att hantera åtkomst som du har beviljat för enskilda webbplatser till enhetens mikrofon. + Du kan gå till Inställningar för att hantera åtkomst som du har beviljat för enskilda webbplatser till enhetens kamera. ”%1$s” vill komma åt kameran och mikrofonen ”%1$s” vill komma åt mikrofonen ”%1$s” vill komma åt kameran @@ -35,4 +57,20 @@ Webbplatser kan endast använda din kamera och mikrofon om du tillåter DuckDuckGo att be om åtkomst. Öppna inställningar Avbryt + + Webbplatser som du besöker kan begära åtkomst till din enhets plats, kamera, mikrofon eller DRM-programvara (Digital Rights Management). De kan inte komma åt dessa om du inte uttryckligen tillåter det. + Tillåt alla webbplatser att be om: + Plats + Kamera + Mikrofon + Hantera webbplatser + Inga webbplatser ännu + Behörigheter har tagits bort för alla webbplatser + Behörigheter för %1$s + Fråga varje gång + Neka + Tillåt + Inaktiverat för alla webbplatser + %1$s-behörighet för %2$s + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values-tr/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values-tr/strings-site-permissions.xml index 880aed38abc6..5586c2bc3137 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values-tr/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values-tr/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" DRM yazılımınızı açmak istiyor + Dijital Haklar Yönetimi yazılımı, korumalı medya içeriğini yürütmek için gereklidir, ancak aynı zamanda cihaz tanımlayıcılara erişim sağlar. Bu veriler için yalnızca güvendiğiniz sitelere izin verin. İzinleri istediğiniz zaman Ayarlar\'dan yönetebilirsiniz. Daha Fazla Bilgi + Her zaman + Yalnızca Bu Oturum için + Her Zaman Reddet + Bu Oturum için Reddet + + + \"%1$s\" konumunuza erişmek istiyor + Seçimimi hatırla + Anonim konumunuzu yalnızca size daha yakın, daha iyi sonuçlar sunmak için kullanıyoruz. Ayrı ayrı sitelere verdiğiniz konum erişimi izinlerini Ayarlar bölümünden yönetebilirsiniz. + Sitelere verdiğiniz konuma erişim izinlerini Ayarlar bölümünden yönetebilirsiniz. + DuckDuckGo\'nun bu cihazda konum erişimi istemesine izin ver + Siteler konumunuzu yalnızca DuckDuckGo\'nun erişim istemesine izin verirseniz kullanabilir. + DuckDuckGo\'nun konum erişimi istemesine izin ver + + + Site İzinleri + Sitelere verdiğiniz mikrofon ve kamera erişim izinlerini Ayarlar bölümünden yönetebilirsiniz. + Sitelere verdiğiniz mikrofona erişim izinlerini Ayarlar bölümünden yönetebilirsiniz. + Sitelere verdiğiniz kamera erişim izinlerini Ayarlar bölümünden yönetebilirsiniz. \"%1$s\" kameraya ve mikrofona erişmek istiyor \"%1$s\" mikrofona erişmek istiyor \"%1$s\" kameraya erişmek istiyor @@ -35,4 +57,20 @@ Siteler kameranızı ve mikrofonunuzu yalnızca DuckDuckGo\'nun erişim istemesine izin verirseniz kullanabilir. Ayarları Aç İptal + + Ziyaret ettiğiniz siteler cihazınızın konumuna, kamerasına, mikrofonuna veya DRM (Dijital Haklar Yönetimi) yazılımına erişim isteyebilir. Siz açıkça izin vermediğiniz sürece bunlara erişemezler. + Tüm sitelerin şunları istemesine izin ver: + Konum + Kamera + Mikrofon + Siteleri Yönet + Henüz site yok + Tüm Siteler İçin İzinler Kaldırıldı + \"%1$s\" için izinler + Her seferinde sor + Reddet + İzin ver + Tüm siteler için devre dışı + %2$s için %1$s izni + \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values/donottranslate.xml b/site-permissions/site-permissions-impl/src/main/res/values/donottranslate.xml index 0133047e20a0..6f2f770f3502 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values/donottranslate.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values/donottranslate.xml @@ -15,26 +15,6 @@ --> - - \"%1$s\" wants to open your DRM software - Digital Rights Management software is required to play protected media content, but also provides access to device identifiers. Only grant permission to sites you trust with this data. You can manage permissions at any time in Settings. Learn More - Always - Only for This Session - Deny Always - Deny for This Session - - - \"%1$s\" wants to access your location - Remember my choice - We only use your anonymous location to deliver better results, closer to you. You can manage the location access permissions you’ve granted to individual sites in Settings. - You can manage the location access permissions you’ve granted to individual sites in Settings. - Allow DuckDuckGo to ask for location access on this device - Sites can only use your location if you allow DuckDuckGo to ask for access. - Allow DuckDuckGo to ask for location access - - - You can manage the microphone and camera access permissions you’ve granted to individual sites in Settings. - You can manage the microphone access permissions you’ve granted to individual sites in Settings. - You can manage the camera access permissions you’ve granted to individual sites in Settings. - + + DRM \ No newline at end of file diff --git a/site-permissions/site-permissions-impl/src/main/res/values/strings-site-permissions.xml b/site-permissions/site-permissions-impl/src/main/res/values/strings-site-permissions.xml index 29cee1962a50..83b93d514da9 100644 --- a/site-permissions/site-permissions-impl/src/main/res/values/strings-site-permissions.xml +++ b/site-permissions/site-permissions-impl/src/main/res/values/strings-site-permissions.xml @@ -17,6 +17,28 @@ + + \"%1$s\" wants to open your DRM software + Digital Rights Management software is required to play protected media content, but also provides access to device identifiers. Only grant permission to sites you trust with this data. You can manage permissions at any time in Settings. Learn More + Always + Only for This Session + Deny Always + Deny for This Session + + + \"%1$s\" wants to access your location + Remember my choice + We only use your anonymous location to deliver better results, closer to you. You can manage the location access permissions you’ve granted to individual sites in Settings. + You can manage the location access permissions you’ve granted to individual sites in Settings. + Allow DuckDuckGo to ask for location access on this device + Sites can only use your location if you allow DuckDuckGo to ask for access. + Allow DuckDuckGo to ask for location access + + + Site Permissions + You can manage the microphone and camera access permissions you’ve granted to individual sites in Settings. + You can manage the microphone access permissions you’ve granted to individual sites in Settings. + You can manage the camera access permissions you’ve granted to individual sites in Settings. \"%1$s\" wants to access the camera and microphone \"%1$s\" wants to access the microphone \"%1$s\" wants to access the camera @@ -35,4 +57,20 @@ Sites can only use your camera and microphone if you allow DuckDuckGo to ask for access. Open Settings Cancel + + Sites you visit may ask for access to your device’s location, camera, microphone, or DRM (Digital Rights Management) software. They won’t be able to access these unless you explicitly give them permission. + Allow all sites to ask for: + Location + Camera + Microphone + Manage Sites + No sites yet + Permissions Removed for All Sites + Permissions for \"%1$s\" + Ask every time + Deny + Allow + Disabled for all sites + %1$s permission for %2$s + \ No newline at end of file diff --git a/app/src/test/java/com/duckduckgo/app/sitepermissions/PermissionsPerWebsiteViewModelTest.kt b/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui/sitepermissions/PermissionsPerWebsiteViewModelTest.kt similarity index 89% rename from app/src/test/java/com/duckduckgo/app/sitepermissions/PermissionsPerWebsiteViewModelTest.kt rename to site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui/sitepermissions/PermissionsPerWebsiteViewModelTest.kt index 5895875cf281..77e06316cfcc 100644 --- a/app/src/test/java/com/duckduckgo/app/sitepermissions/PermissionsPerWebsiteViewModelTest.kt +++ b/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui/sitepermissions/PermissionsPerWebsiteViewModelTest.kt @@ -14,28 +14,29 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions +package com.duckduckgo.site.permissions.impl.ui.sitepermissions import app.cash.turbine.test -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.GoBackToSitePermissions -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.ShowPermissionSettingSelectionDialog -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSetting -import com.duckduckgo.app.sitepermissions.permissionsperwebsite.WebsitePermissionSettingOption import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.site.permissions.impl.R import com.duckduckgo.site.permissions.impl.SitePermissionsRepository +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.GoBackToSitePermissions +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.PermissionsPerWebsiteViewModel.Command.ShowPermissionSettingSelectionDialog +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSetting +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption +import com.duckduckgo.site.permissions.impl.ui.permissionsperwebsite.WebsitePermissionSettingOption.ASK import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionAskSettingType import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionsEntity +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.stub +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test -import org.mockito.kotlin.mock -import org.mockito.kotlin.stub -import org.mockito.kotlin.verify -import org.mockito.kotlin.whenever class PermissionsPerWebsiteViewModelTest { @@ -148,7 +149,7 @@ class PermissionsPerWebsiteViewModelTest { viewModel.websitePermissionSettings(domain) val websitePermissionSetting = - WebsitePermissionSetting(R.drawable.ic_video_24, R.string.sitePermissionsSettingsCamera, WebsitePermissionSettingOption.ASK) + WebsitePermissionSetting(R.drawable.ic_video_24, R.string.sitePermissionsSettingsCamera, ASK) viewModel.permissionSettingSelected(websitePermissionSetting) viewModel.commands.test { diff --git a/app/src/test/java/com/duckduckgo/app/sitepermissions/SitePermissionsViewModelTest.kt b/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui/sitepermissions/SitePermissionsViewModelTest.kt similarity index 91% rename from app/src/test/java/com/duckduckgo/app/sitepermissions/SitePermissionsViewModelTest.kt rename to site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui/sitepermissions/SitePermissionsViewModelTest.kt index 49d4d44646ea..ea0432e6bfad 100644 --- a/app/src/test/java/com/duckduckgo/app/sitepermissions/SitePermissionsViewModelTest.kt +++ b/site-permissions/site-permissions-impl/src/test/java/com/duckduckgo/site/permissions/impl/ui/sitepermissions/SitePermissionsViewModelTest.kt @@ -14,15 +14,19 @@ * limitations under the License. */ -package com.duckduckgo.app.sitepermissions +package com.duckduckgo.site.permissions.impl.ui.sitepermissions import app.cash.turbine.test -import com.duckduckgo.app.browser.R -import com.duckduckgo.app.sitepermissions.SitePermissionsViewModel.Command.LaunchWebsiteAllowed -import com.duckduckgo.app.sitepermissions.SitePermissionsViewModel.Command.ShowRemovedAllConfirmationSnackbar import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.site.permissions.impl.R import com.duckduckgo.site.permissions.impl.SitePermissionsRepository +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel.Command.LaunchWebsiteAllowed +import com.duckduckgo.site.permissions.impl.ui.SitePermissionsViewModel.Command.ShowRemovedAllConfirmationSnackbar import com.duckduckgo.site.permissions.store.sitepermissions.SitePermissionsEntity +import com.nhaarman.mockitokotlin2.mock +import com.nhaarman.mockitokotlin2.verify +import com.nhaarman.mockitokotlin2.whenever import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals @@ -31,9 +35,6 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test -import org.mockito.kotlin.mock -import org.mockito.kotlin.verify -import org.mockito.kotlin.whenever class SitePermissionsViewModelTest { diff --git a/sync/sync-impl/src/main/res/values-bg/strings-sync.xml b/sync/sync-impl/src/main/res/values-bg/strings-sync.xml index b5afaf788373..c4d915a3c43f 100644 --- a/sync/sync-impl/src/main/res/values-bg/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-bg/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Синхронизирането и архивирането не е достъпно\nСъжаляваме, но функцията за синхронизиране и архивиране в момента не е достъпна. Моля, опитайте отново по-късно. Синхронизирането и архивирането не е достъпно\nСъжаляваме, но функцията за синхронизиране и архивиране вече не се предлага в тази версия на приложението. Моля, актуализирайте DuckDuckGo до най-новата версия, за да продължите. @@ -36,6 +36,7 @@ Сигурно синхронизиране на отметките и паролите между отделни устройства. Данните Ви са изцяло криптирани и DuckDuckGo няма достъп до ключа за криптиране. Настройка на едно устройство + Other Options Възстановяване на синхронизирани данни Синхронизиране и архивиране на това устройство diff --git a/sync/sync-impl/src/main/res/values-cs/strings-sync.xml b/sync/sync-impl/src/main/res/values-cs/strings-sync.xml index dcfb361e9f59..63807cc000d9 100644 --- a/sync/sync-impl/src/main/res/values-cs/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-cs/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synchronizace a zálohování není k dispozici\nOmlouváme se, ale funkce synchronizace a zálohování teď není dostupná. Zkus to znovu později. Synchronizace a zálohování není k dispozici\nOmlouváme se, ale funkce synchronizace a zálohování není v téhle verzi aplikace dostupná. Pro pokračování aktualizuj DuckDuckGo na nejnovější verzi. @@ -36,6 +36,7 @@ Bezpečně synchronizuj záložky a hesla mezi svými zařízeními. U tvých dat se uplatňuje end-to-end šifrování a DuckDuckGo nemá přístup k šifrovacímu klíči. Nastavení jednoho zařízení + Other Options Obnovit synchronizovaná data Synchronizace a záloha tohoto zařízení diff --git a/sync/sync-impl/src/main/res/values-da/strings-sync.xml b/sync/sync-impl/src/main/res/values-da/strings-sync.xml index 1d36bc89c513..2fe5fafe92c4 100644 --- a/sync/sync-impl/src/main/res/values-da/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-da/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synkronisering og sikkerhedskopiering ikke tilgængelige\nBeklager, men synkronisering og sikkerhedskopiering er ikke tilgængelige i øjeblikket. Prøv igen senere. Synkronisering og sikkerhedskopiering ikke tilgængelige\nBeklager, men synkronisering og sikkerhedskopiering er ikke længere tilgængelige i denne app-version. Opdater DuckDuckGo til den nyeste version for at fortsætte. @@ -36,6 +36,7 @@ Synkroniser sikkert bogmærker og adgangskoder mellem dine enheder. Dine data er fuldt krypterede, og DuckDuckGo har ikke adgang til krypteringsnøglen. Opsætning af en enkelt enhed + Other Options Gendan synkroniserede data Synkroniser og sikkerhedskopier denne enhed diff --git a/sync/sync-impl/src/main/res/values-de/strings-sync.xml b/sync/sync-impl/src/main/res/values-de/strings-sync.xml index 0e38b8e352ef..5e4e14ee47c1 100644 --- a/sync/sync-impl/src/main/res/values-de/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-de/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synchronisieren und sichern nicht verfügbar\nEntschuldigung, aber Synchronisieren und sichern ist derzeit nicht verfügbar. Bitte versuche es zu einem späteren Zeitpunkt erneut. Synchronisieren und Sichern nicht verfügbar\nLeider ist Synchronisieren und Sichern in dieser App-Version nicht mehr verfügbar. Bitte aktualisiere DuckDuckGo auf die neueste Version, um fortzufahren. @@ -36,6 +36,7 @@ Lesezeichen und Passwörter sicher zwischen deinen Geräten synchronisieren. Deine Daten sind Ende-zu-Ende-verschlüsselt. DuckDuckGo hat keinen Zugriff auf den Verschlüsselungsschlüssel. Einrichtung für ein einzelnes Gerät + Other Options Synchronisierte Daten wiederherstellen Dieses Gerät synchronisieren und sichern diff --git a/sync/sync-impl/src/main/res/values-el/strings-sync.xml b/sync/sync-impl/src/main/res/values-el/strings-sync.xml index bc32dce68ac9..319ba2623844 100644 --- a/sync/sync-impl/src/main/res/values-el/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-el/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Ο Συγχρονισμός και η δημιουργία αντιγράφων ασφάλειας δεν είναι διαθέσιμα\nΔυστυχώς, η λειτουργία Συγχρονισμός και δημιουργία αντιγράφων ασφάλειας δεν είναι διαθέσιμη αυτήν τη στιγμή. Ξαναδοκιμάστε αργότερα. Ο Συγχρονισμός και η δημιουργία αντιγράφων ασφάλειας δεν είναι διαθέσιμα\nΔυστυχώς,η λειτουργία Συγχρονισμός και δημιουργία αντιγράφων ασφάλειας δεν είναι διαθέσιμη σε αυτήν την έκδοση της εφαρμογής. Ενημερώστε το DuckDuckGo στην πιο πρόσφατη έκδοση για να συνεχίσετε. @@ -36,6 +36,7 @@ Συγχρονίστε με ασφάλεια σελιδοδείκτες και κωδικούς πρόσβασης μεταξύ των συσκευών σας. Τα δεδομένα σας είναι κρυπτογραφημένα από άκρο σε άκρο και το DuckDuckGo δεν έχει πρόσβαση στο κλειδί κρυπτογράφησης. Εγκατάσταση μίας συσκευής + Other Options Ανάκτηση συγχρονισμένων δεδομένων Συγχρονισμός και δημιουργία αντιγράφων ασφάλειας αυτής της συσκευής diff --git a/sync/sync-impl/src/main/res/values-es/strings-sync.xml b/sync/sync-impl/src/main/res/values-es/strings-sync.xml index be159e5e766e..b4893b2df82e 100644 --- a/sync/sync-impl/src/main/res/values-es/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-es/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sincronización y copia de seguridad no disponibles\nLo sentimos, pero la sincronización y copia de seguridad no están disponibles en este momento. Inténtalo de nuevo más tarde. Sincronización y copia de seguridad no disponibles\nLo sentimos, pero la sincronización y la copia de seguridad ya no están disponibles en esta versión de la aplicación. Actualiza DuckDuckGo a la versión más reciente para continuar. @@ -36,6 +36,7 @@ Sincroniza de forma segura los marcadores y las contraseñas entre tus dispositivos. Tus datos están encriptados de extremo a extremo y DuckDuckGo no tiene acceso a la clave de encriptación. Configuración para un solo dispositivo + Other Options Recuperar datos sincronizados Sincronizar y hacer una copia de seguridad de este dispositivo diff --git a/sync/sync-impl/src/main/res/values-et/strings-sync.xml b/sync/sync-impl/src/main/res/values-et/strings-sync.xml index 7e5e234fa626..9fb182435445 100644 --- a/sync/sync-impl/src/main/res/values-et/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-et/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sünkroonimine ja varundamine pole saadaval\nKahjuks pole sünkroonimine ja varundamine praegu saadaval. Proovi hiljem uuesti. Sünkroonimine ja varundus pole saadaval\nVabandust, sünkroonimine ja varundus pole selles rakenduse versioonis enam saadaval. Jätkamiseks värskenda DuckDuckGo uusimale versioonile. @@ -36,6 +36,7 @@ Sünkrooni järjehoidjaid ja paroole turvaliselt oma seadmete vahel. Sinu andmed on otsast lõpuni krüptitud ja DuckDuckGo ei pääse krüpteerimisvõtmele ligi. Ühe seadme seadistamine + Other Options Taasta sünkroonitud andmed Selle seadme sünkroonimine ja varundamine diff --git a/sync/sync-impl/src/main/res/values-fi/strings-sync.xml b/sync/sync-impl/src/main/res/values-fi/strings-sync.xml index 98552040c3cc..46d46251547e 100644 --- a/sync/sync-impl/src/main/res/values-fi/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-fi/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synkronointi ja varmuuskopiointi ei käytettävissä\nSynkronointi ja varmuuskopiointi ei valitettavasti ole tällä hetkellä käytettävissä. Yritä myöhemmin uudelleen. Synkronointi ja varmuuskopiointi ei käytettävissä\nSynkronointi ja varmuuskopiointi ei valitettavasti ole enää käytettävissä tässä sovellusversiossa. Päivitä DuckDuckGo uusimpaan versioon jatkaaksesi. @@ -36,6 +36,7 @@ Synkronoi kirjanmerkit ja salasanat turvallisesti laitteittesi välillä. Tietosi on salattu päästä päähän, eikä DuckDuckGolla ole hallussaan salausavainta. Yhden laitteen asennus + Other Options Palauta synkronoidut tiedot Synkronoi ja varmuuskopioi tämä laite diff --git a/sync/sync-impl/src/main/res/values-fr/strings-sync.xml b/sync/sync-impl/src/main/res/values-fr/strings-sync.xml index ad02b0dada0d..0b67dc52e9fd 100644 --- a/sync/sync-impl/src/main/res/values-fr/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-fr/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synchronisation et sauvegarde est indisponible\nDésolé, mais Synchronisation et sauvegarde n’est pas disponible pour le moment. Veuillez réessayer plus tard. Synchronisation et sauvegarde est indisponible\nDésolé, mais Synchronisation et sauvegarde n’est plus disponible dans cette version de l\'application. Veuillez mettre à jour DuckDuckGo avec la dernière version pour continuer. @@ -36,6 +36,7 @@ Synchronisez en toute sécurité les signets et mots de passe entre vos appareils. Vos données sont cryptées de bout en bout et DuckDuckGo n\'a pas accès à la clé de chiffrement. Configuration d\'un seul appareil + Other Options Récupérer les données synchronisées Synchroniser et sauvegarder cet appareil diff --git a/sync/sync-impl/src/main/res/values-hr/strings-sync.xml b/sync/sync-impl/src/main/res/values-hr/strings-sync.xml index f6a06ea20b05..c69cf347b92b 100644 --- a/sync/sync-impl/src/main/res/values-hr/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-hr/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sinkronizacija i sigurnosno kopiranje nisu dostupni\nNažalost, sinkronizacija i sigurnosno kopiranje trenutačno nisu dostupni. Pokušaj ponovno nešto kasnije. Sinkronizacija i sigurnosno kopiranje nisu dostupni\nNažalost, sinkronizacija i sigurnosno kopiranje više nisu dostupni u ovoj verziji aplikacije. Za nastavak, ažuriraj DuckDuckGo na najnoviju verziju. @@ -36,6 +36,7 @@ Sigurno sinkroniziraj oznake i lozinke između svojih uređaja. Tvoji su podaci šifrirani od početka do kraja, a DuckDuckGo nema pristup ključu za šifriranje. Postavljanje jednog uređaja + Other Options Oporavak sinkroniziranih podataka Sinkroniziraj i izradi sigurnosnu kopiju ovog uređaja diff --git a/sync/sync-impl/src/main/res/values-hu/strings-sync.xml b/sync/sync-impl/src/main/res/values-hu/strings-sync.xml index 8ccedbbbb874..c80c7449efc4 100644 --- a/sync/sync-impl/src/main/res/values-hu/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-hu/strings-sync.xml @@ -16,7 +16,7 @@ --> - + A szinkronizálás és a biztonságai másolatkészítés nem érhető el\nA szinkronizálás és biztonsági másolatkészítés jelenleg sajnos nem érhető el. Próbálkozz újra később. A szinkronizálás és a biztonsági másolatkészítés nem érhető el\nA szinkronizálás és biztonsági másolatkészítés az alkalmazás ezen verziójában sajnos már nem érhető el. A folytatáshoz frissíts a DuckDuckGo a legújabb verziójára. @@ -36,6 +36,7 @@ Szinkronizáld biztonságosan a könyvjelzőket és jelszavakat az eszközök között. Az adataid végponttól végpontig titkosítva vannak, a DuckDuckGo pedig nem fér hozzá a titkosítási kulcshoz. Egyeszközös beállítás + Other Options Szinkronizált adatok helyreállítása Az eszköz szinkronizálása és biztonsági mentése diff --git a/sync/sync-impl/src/main/res/values-it/strings-sync.xml b/sync/sync-impl/src/main/res/values-it/strings-sync.xml index 0931a9743e8e..04158bb8e6f5 100644 --- a/sync/sync-impl/src/main/res/values-it/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-it/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sincronizzazione e backup non disponibile\nSpiacenti, Sincronizzazione e backup non è attualmente disponibile. Riprova più tardi. Sincronizzazione e backup non disponibile\nSpiacenti, Sincronizzazione e backup non è più disponibile in questa versione dell\'app. Per continuare, aggiorna DuckDuckGo all\'ultima versione. @@ -36,6 +36,7 @@ Sincronizza in sicurezza i segnalibri e le password tra i tuoi dispositivi. I tuoi dati sono crittografati end-to-end e DuckDuckGo non ha accesso alla chiave di crittografia. Configurazione di un singolo dispositivo + Other Options Recupera i dati sincronizzati Sincronizza ed esegui il backup di questo dispositivo diff --git a/sync/sync-impl/src/main/res/values-lt/strings-sync.xml b/sync/sync-impl/src/main/res/values-lt/strings-sync.xml index c88597ab0a7a..eba727b6d5dd 100644 --- a/sync/sync-impl/src/main/res/values-lt/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-lt/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sinchronizavimas ir atsarginės kopijos kūrimas nepasiekiami\nAtsiprašome, bet šiuo metu sinchronizavimas ir atsarginės kopijos kūrimas nepasiekiami. Pabandykite dar kartą vėliau. Sinchronizavimas ir atsarginės kopijos kūrimas nepasiekiami\nAtsiprašome, bet sinchronizavimas ir atsarginės kopijos kūrimas šioje programos versijoje nebepasiekiami. Norėdami tęsti, atnaujinkite „DuckDuckGo“ į naujausią versiją. @@ -36,6 +36,7 @@ Saugiai sinchronizuokite žymes ir slaptažodžius tarp savo įrenginių. Jūsų duomenys šifruojami ištisiniu būdu, o „DuckDuckGo“ neturi prieigos prie šifravimo rakto. Vieno įrenginio sąranka + Other Options Atkurti sinchronizuotus duomenis Sinchronizuokite ir sukurkite atsarginę šio įrenginio kopiją diff --git a/sync/sync-impl/src/main/res/values-lv/strings-sync.xml b/sync/sync-impl/src/main/res/values-lv/strings-sync.xml index c0ebba5ea5f1..0a65a8b10969 100644 --- a/sync/sync-impl/src/main/res/values-lv/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-lv/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sinhronizācija un dublēšana nav pieejama\nDiemžēl sinhronizācija un dublēšana pašlaik nav pieejama. Lūdzu, mēģini vēlreiz vēlāk. Sinhronizācija un dublēšana nav pieejama\nDiemžēl sinhronizācija un dublēšana vairs nav pieejama šajā lietotnes versijā. Lai turpinātu, lūdzu, atjaunini DuckDuckGo uz jaunāko versiju. @@ -36,6 +36,7 @@ Droši sinhronizē grāmatzīmes un paroles starp ierīcēm. Tavi dati tiek šifrēti no gala līdz galam, un DuckDuckGo nav piekļuves šifrēšanas atslēgai. Vienas ierīces iestatīšana + Other Options Sinhronizēto datu atgūšana Šīs ierīces sinhronizācija un dublēšana diff --git a/sync/sync-impl/src/main/res/values-nb/strings-sync.xml b/sync/sync-impl/src/main/res/values-nb/strings-sync.xml index 91f93b60a481..96c624f323f1 100644 --- a/sync/sync-impl/src/main/res/values-nb/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-nb/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synkronisering og sikkerhetskopiering er utilgjengelig\nBeklager, men synkronisering og sikkerhetskopiering er ikke tilgjengelig for øyeblikket. Prøv igjen senere. Synkronisering og sikkerhetskopiering er utilgjengelig\nBeklager, men synkronisering og sikkerhetskopiering er ikke lenger tilgjengelig i denne appversjonen. Oppdater DuckDuckGo til den nyeste versjonen for å fortsette. @@ -36,6 +36,7 @@ Synkroniser bokmerker og passord på en sikker måte mellom enhetene dine. Dataene dine er ende-til-ende-kryptert og DuckDuckGo har ikke tilgang til krypteringsnøkkelen. Oppsett for én enhet + Other Options Gjenopprett synkroniserte data Synkroniser og sikkerhetskopier denne enheten diff --git a/sync/sync-impl/src/main/res/values-nl/strings-sync.xml b/sync/sync-impl/src/main/res/values-nl/strings-sync.xml index 7cfb20184e2c..a48cba1ce8d2 100644 --- a/sync/sync-impl/src/main/res/values-nl/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-nl/strings-sync.xml @@ -16,7 +16,7 @@ --> - + \'Synchronisatie en back-up\' niet beschikbaar\n\'Synchronisatie en back-up\' is momenteel niet beschikbaar. Probeer het later opnieuw. \'Synchronisatie en back-up\' niet beschikbaar\n\'Synchronisatie en back-up\' is helaas niet langer beschikbaar in deze app-versie. Werk DuckDuckGo bij naar de nieuwste versie om door te gaan. @@ -36,6 +36,7 @@ Synchroniseer bladwijzers en wachtwoorden veilig tussen je apparaten. Je gegevens zijn volledig versleuteld en DuckDuckGo heeft geen toegang tot de versleutelingscode. Configuratie van één apparaat + Other Options Gesynchroniseerde gegevens herstellen Dit apparaat synchroniseren en back-up maken diff --git a/sync/sync-impl/src/main/res/values-pl/strings-sync.xml b/sync/sync-impl/src/main/res/values-pl/strings-sync.xml index 88dac3d33bf5..ae9c6e42ad53 100644 --- a/sync/sync-impl/src/main/res/values-pl/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-pl/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synchronizacja i kopia zapasowa niedostępna\nNiestety synchronizacja i kopia zapasowa jest obecnie niedostępna. Spróbuj ponownie później. Synchronizacja i kopia zapasowa niedostępna\nNiestety synchronizacja i kopia zapasowa nie jest już dostępna w tej wersji aplikacji. Aby kontynuować, zaktualizuj DuckDuckGo do najnowszej wersji. @@ -36,6 +36,7 @@ Bezpiecznie synchronizuj zakładki i hasła między swoimi urządzeniami. Twoje dane są kompleksowo szyfrowane, a DuckDuckGo nie ma dostępu do klucza szyfrowania. Konfiguracja na jednym urządzeniu + Other Options Odzyskaj zsynchronizowane dane Synchronizuj i twórz kopie zapasowe tego urządzenia diff --git a/sync/sync-impl/src/main/res/values-pt/strings-sync.xml b/sync/sync-impl/src/main/res/values-pt/strings-sync.xml index b242876358b7..bb3f4464c408 100644 --- a/sync/sync-impl/src/main/res/values-pt/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-pt/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sincronização e cópia de segurança indisponíveis\nLamentamos, mas a sincronização e a cópia de segurança não estão disponíveis de momento. Tenta novamente mais tarde. Sincronização e cópia de segurança indisponíveis\nLamentamos, mas a sincronização e a cópia de segurança já não estão disponíveis nesta versão da aplicação. Atualiza o DuckDuckGo para a versão mais recente para continuar. @@ -36,6 +36,7 @@ Sincroniza os marcadores e palavras-passe entre os teus dispositivos em segurança. Os teus dados são encriptados de ponta a ponta e o DuckDuckGo não tem acesso à chave de encriptação. Configuração de dispositivo único + Other Options Recuperar dados sincronizados Sincronizar e fazer cópia de segurança deste dispositivo diff --git a/sync/sync-impl/src/main/res/values-ro/strings-sync.xml b/sync/sync-impl/src/main/res/values-ro/strings-sync.xml index 41aed8875aa1..125500b9d484 100644 --- a/sync/sync-impl/src/main/res/values-ro/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-ro/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sincronizare și backup indisponibilă\nNe pare rău, dar Sincronizare și backup nu este disponibilă în prezent. Încearcă din nou mai târziu. Sincronizare și backup indisponibil\nNe pare rău, dar Sincronizare și backup nu mai este disponibil în această versiune a aplicației. Actualizează DuckDuckGo la cea mai recentă versiune pentru a continua. @@ -36,6 +36,7 @@ Sincronizează în siguranță marcajele și parolele între dispozitivele tale. Datele tale sunt criptate integral, iar DuckDuckGo nu are acces la cheia de criptare. Configurare pe un singur dispozitiv + Other Options Recuperează datele sincronizate Sincronizează și fă backup pentru acest dispozitiv diff --git a/sync/sync-impl/src/main/res/values-ru/strings-sync.xml b/sync/sync-impl/src/main/res/values-ru/strings-sync.xml index 20f6b6911b18..af04a64284d6 100644 --- a/sync/sync-impl/src/main/res/values-ru/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-ru/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Синхронизация и резервное копирование недоступны\nК сожалению, функция «Синхронизация и резервное копирование» сейчас недоступна. Повторите попытку позже. Синхронизация и резервное копирование недоступны\nК сожалению, функция «Синхронизация и резервное копирование» больше не работает в этой версии приложения. Для продолжения обновите DuckDuckGo до последней версии. @@ -36,6 +36,7 @@ Безопасная синхронизация закладок и паролей на ваших устройствах. Ваши данные защищены сквозным шифрованием. У DuckDuckGo нет доступа к ключу шифрования. Настройка на одном устройстве + Other Options Восстановить синхронизированные данные Синхронизация и резервное копирование устройства diff --git a/sync/sync-impl/src/main/res/values-sk/strings-sync.xml b/sync/sync-impl/src/main/res/values-sk/strings-sync.xml index 5b7e7b5ba6c1..5eada8423bff 100644 --- a/sync/sync-impl/src/main/res/values-sk/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-sk/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synchronizácia a zálohovanie nie sú dostupné\nJe nám to ľúto, ale Synchronizácia a zálohovanie momentálne nie sú dostupné. Prosím, skúste to neskôr znova. Synchronizácia a zálohovanie sú nedostupné\nĽutujeme, ale synchronizácia a zálohovanie už nie sú v tejto verzii aplikácie k dispozícii. Ak chcete pokračovať, aktualizujte DuckDuckGo na najnovšiu verziu. @@ -36,6 +36,7 @@ Bezpečne synchronizujte záložky a heslá medzi svojimi zariadeniami. Vaše údaje sú šifrované na oboch koncoch (end-to-end) a DuckDuckGo nemá prístup k šifrovaciemu kľúču. Nastavenie jedného zariadenia + Other Options Obnovenie synchronizovaných údajov Synchronizujte a zálohujte toto zariadenie diff --git a/sync/sync-impl/src/main/res/values-sl/strings-sync.xml b/sync/sync-impl/src/main/res/values-sl/strings-sync.xml index 0bafabefeb29..e10923f29932 100644 --- a/sync/sync-impl/src/main/res/values-sl/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-sl/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Sinhronizacija in varnostno kopiranje nista na voljo\nSinhronizacija in varnostno kopiranje žal trenutno nista na voljo. Poskusite znova pozneje. Sinhronizacija in varnostno kopiranje nista na voljo\nSinhronizacija in varnostno kopiranje v tej različici aplikacije žal nista več na voljo. Če želite nadaljevati, DuckDuckGo posodobite na najnovejšo različico. @@ -36,6 +36,7 @@ Varno sinhronizirajte zaznamke in gesla med napravami. Vaši podatki so celovito šifrirani in DuckDuckGo nima dostopa do šifrirnega ključa. Nastavitev ene naprave + Other Options Obnovitev sinhroniziranih podatkov Sinhronizirajte in varnostno kopirajte to napravo diff --git a/sync/sync-impl/src/main/res/values-sv/strings-sync.xml b/sync/sync-impl/src/main/res/values-sv/strings-sync.xml index 9892d6396431..fc18134bf3f9 100644 --- a/sync/sync-impl/src/main/res/values-sv/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-sv/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Synkronisering och säkerhetskopiering inte tillgänglig\nTyvärr är synkronisering och säkerhetskopiering inte tillgänglig för närvarande. Försök igen senare. Synkronisering och säkerhetskopiering inte tillgängligt\nSynkronisering och säkerhetskopiering är dessvärre inte längre tillgängligt i denna version av appen. Uppdatera DuckDuckGo till den senaste versionen för att fortsätta. @@ -36,6 +36,7 @@ Synkronisera bokmärken och lösenord mellan dina enheter på ett säkert sätt. Dina data krypteras under hela vägen och DuckDuckGo har inte tillgång till krypteringsnyckeln. Konfiguration för en enda enhet + Other Options Återställ synkroniserade data Synkronisera och säkerhetskopiera denna enhet diff --git a/sync/sync-impl/src/main/res/values-tr/strings-sync.xml b/sync/sync-impl/src/main/res/values-tr/strings-sync.xml index 118916a03640..f36ebf13edd4 100644 --- a/sync/sync-impl/src/main/res/values-tr/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-tr/strings-sync.xml @@ -16,7 +16,7 @@ --> - + Senkronizasyon ve Yedekleme Kullanılamıyor\nÜzgünüz, Senkronizasyon ve Yedekleme şu anda kullanılamıyor. Lütfen daha sonra tekrar deneyin. Senkronizasyon ve Yedekleme Kullanılamıyor\nÜzgünüz, Senkronizasyon ve Yedekleme artık bu uygulama sürümünde kullanılamıyor. Devam etmek için lütfen DuckDuckGo\'yu en son sürüme güncelleyin. @@ -36,6 +36,7 @@ Yer imlerini ve parolaları cihazlarınız arasında güvenli bir şekilde senkronize edin. Verileriniz uçtan uca şifrelenir ve DuckDuckGo\'nun şifreleme anahtarına erişimi yoktur. Tek Cihaz Kurulumu + Other Options Senkronize Edilen Verileri Kurtar Bu Cihazı Senkronize Et ve Yedekle From f0e5e1bae23cb18a823b4aab4355eafee40715cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gonz=C3=A1lez?= Date: Thu, 12 Dec 2024 23:27:20 +0100 Subject: [PATCH 02/32] Navigational links as top hits (#5374) Task/Issue URL: https://app.asana.com/0/1174433894299346/1208855071397751/f ### Description Ensure that Navigational links can be shown as Top Hits ### Steps to test this PR Check https://app.asana.com/0/1174433894299346/1208909865959915/f for different scenarios --- .../app/browser/BrowserTabViewModelTest.kt | 7 +- .../app/autocomplete/api/AutoComplete.kt | 26 +- .../BrowserAutoCompleteSuggestionsAdapter.kt | 2 + .../SuggestionViewHolderFactory.kt | 6 +- .../autocomplete/api/AutoCompleteApiTest.kt | 374 +++++++++++++++--- .../systemsearch/SystemSearchViewModelTest.kt | 7 +- 6 files changed, 352 insertions(+), 70 deletions(-) diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt index fc0aac1180cb..f871a63015af 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt @@ -521,7 +521,6 @@ class BrowserTabViewModelTest { mockAutoCompleteRepository, mockTabRepository, mockUserStageStore, - coroutineRule.testDispatcherProvider, mockAutocompleteTabsFeature, ) val fireproofWebsiteRepositoryImpl = FireproofWebsiteRepositoryImpl( @@ -2368,9 +2367,9 @@ class BrowserTabViewModelTest { fun whenSearchSuggestionSubmittedWithBookmarksThenAutoCompleteSearchSelectionPixelSent() = runTest { whenever(mockSavedSitesRepository.hasBookmarks()).thenReturn(true) whenever(mockNavigationHistory.hasHistory()).thenReturn(false) - val suggestions = listOf(AutoCompleteSearchSuggestion("", false), AutoCompleteBookmarkSuggestion("", "", "")) + val suggestions = listOf(AutoCompleteSearchSuggestion("", false, false), AutoCompleteBookmarkSuggestion("", "", "")) testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteResult("", suggestions)) - testee.fireAutocompletePixel(AutoCompleteSearchSuggestion("example", false)) + testee.fireAutocompletePixel(AutoCompleteSearchSuggestion("example", false, false)) val argumentCaptor = argumentCaptor>() verify(mockPixel).fire(eq(AppPixelName.AUTOCOMPLETE_SEARCH_PHRASE_SELECTION), argumentCaptor.capture(), any(), any()) @@ -2384,7 +2383,7 @@ class BrowserTabViewModelTest { whenever(mockSavedSitesRepository.hasBookmarks()).thenReturn(false) whenever(mockNavigationHistory.hasHistory()).thenReturn(false) testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteResult("", emptyList())) - testee.fireAutocompletePixel(AutoCompleteSearchSuggestion("example", false)) + testee.fireAutocompletePixel(AutoCompleteSearchSuggestion("example", false, false)) val argumentCaptor = argumentCaptor>() verify(mockPixel).fire(eq(AppPixelName.AUTOCOMPLETE_SEARCH_PHRASE_SELECTION), argumentCaptor.capture(), any(), any()) diff --git a/app/src/main/java/com/duckduckgo/app/autocomplete/api/AutoComplete.kt b/app/src/main/java/com/duckduckgo/app/autocomplete/api/AutoComplete.kt index 9e3b9ad4507a..d2db0087d9e2 100644 --- a/app/src/main/java/com/duckduckgo/app/autocomplete/api/AutoComplete.kt +++ b/app/src/main/java/com/duckduckgo/app/autocomplete/api/AutoComplete.kt @@ -39,7 +39,6 @@ import com.duckduckgo.app.tabs.model.TabEntity import com.duckduckgo.app.tabs.model.TabRepository import com.duckduckgo.common.utils.AppUrl import com.duckduckgo.common.utils.AppUrl.Url -import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.common.utils.UrlScheme import com.duckduckgo.common.utils.baseHost import com.duckduckgo.common.utils.toStringDropScheme @@ -80,6 +79,7 @@ interface AutoComplete { data class AutoCompleteSearchSuggestion( override val phrase: String, val isUrl: Boolean, + val isAllowedInTopHits: Boolean, ) : AutoCompleteSuggestion(phrase) data class AutoCompleteDefaultSuggestion( @@ -134,7 +134,6 @@ class AutoCompleteApi @Inject constructor( private val autoCompleteRepository: AutoCompleteRepository, private val tabRepository: TabRepository, private val userStageStore: UserStageStore, - private val dispatcherProvider: DispatcherProvider, private val autocompleteTabsFeature: AutocompleteTabsFeature, ) : AutoComplete { @@ -155,7 +154,8 @@ class AutoCompleteApi @Inject constructor( val bookmarksFavoritesTabsAndHistory = combineBookmarksFavoritesTabsAndHistory(bookmarks, favorites, tabs, historyResults) val topHits = getTopHits(bookmarksFavoritesTabsAndHistory, searchResults) val filteredBookmarksFavoritesTabsAndHistory = filterBookmarksAndTabsAndHistory(bookmarksFavoritesTabsAndHistory, topHits) - val distinctSearchResults = getDistinctSearchResults(searchResults, topHits, filteredBookmarksFavoritesTabsAndHistory) + val middleSectionSearchResults = makeSearchResultsNotAllowedInTopHits(searchResults) + val distinctSearchResults = getDistinctSearchResults(middleSectionSearchResults, topHits, filteredBookmarksFavoritesTabsAndHistory) (topHits + distinctSearchResults + filteredBookmarksFavoritesTabsAndHistory).distinctBy { Pair(it.phrase, it::class.java) @@ -193,11 +193,12 @@ class AutoCompleteApi @Inject constructor( bookmarksAndFavoritesAndTabsAndHistory: List, searchResults: List, ): List { - return (searchResults + bookmarksAndFavoritesAndTabsAndHistory).filter { + return (bookmarksAndFavoritesAndTabsAndHistory + searchResults).filter { when (it) { is AutoCompleteHistorySearchSuggestion -> it.isAllowedInTopHits is AutoCompleteHistorySuggestion -> it.isAllowedInTopHits is AutoCompleteUrlSuggestion -> true + is AutoCompleteSearchSuggestion -> it.isAllowedInTopHits else -> false } }.take(maximumNumberOfTopHits) @@ -213,13 +214,24 @@ class AutoCompleteApi @Inject constructor( .take(maxBottomSection) } + private fun makeSearchResultsNotAllowedInTopHits(searchResults: List): List { + // we allow for search results to show navigational links if they are not favorites or bookmarks and not in top hits + return searchResults.map { + it.copy( + isAllowedInTopHits = false, + ) + } + } + private fun getDistinctSearchResults( searchResults: List, topHits: List, filteredBookmarksAndTabsAndHistory: List, ): List { - val distinctPhrases = (topHits + filteredBookmarksAndTabsAndHistory).distinctBy { it.phrase }.map { it.phrase }.toSet() + // we allow for navigational search results if they are not part of top hits + val distinctPhrases = (filteredBookmarksAndTabsAndHistory).distinctBy { it.phrase }.map { it.phrase }.toSet() val distinctPairs = (topHits + filteredBookmarksAndTabsAndHistory).distinctBy { Pair(it.phrase, it::class.java) }.size + val maxSearchResults = maximumNumberOfSuggestions - distinctPairs return searchResults.distinctBy { it.phrase }.filterNot { it.phrase in distinctPhrases }.take(maxSearchResults) } @@ -300,6 +312,7 @@ class AutoCompleteApi @Inject constructor( val searchSuggestion = AutoCompleteSearchSuggestion( phrase = rawResult.phrase.formatIfUrl(), isUrl = rawResult.isNav ?: UriString.isWebUrl(rawResult.phrase), + isAllowedInTopHits = rawResult.isNav ?: UriString.isWebUrl(rawResult.phrase), ) searchSuggestionsList.add(searchSuggestion) } @@ -422,6 +435,7 @@ class AutoCompleteApi @Inject constructor( isAllowedInTopHits = isAllowedInTopHits(entry), ) } + is VisitedSERP -> { AutoCompleteHistorySearchSuggestion( phrase = entry.query.formatIfUrl(), @@ -484,7 +498,7 @@ class AutoCompleteApi @Inject constructor( return this.toUri().toStringDropScheme().removePrefix("www.") } - private data class RankedSuggestion ( + private data class RankedSuggestion( val suggestion: T, val score: Int = DEFAULT_SCORE, ) diff --git a/app/src/main/java/com/duckduckgo/app/browser/autocomplete/BrowserAutoCompleteSuggestionsAdapter.kt b/app/src/main/java/com/duckduckgo/app/browser/autocomplete/BrowserAutoCompleteSuggestionsAdapter.kt index eebc10b4da5c..5117cfb2b808 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/autocomplete/BrowserAutoCompleteSuggestionsAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/autocomplete/BrowserAutoCompleteSuggestionsAdapter.kt @@ -24,6 +24,7 @@ import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.A import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteHistoryRelatedSuggestion.AutoCompleteHistorySearchSuggestion import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteHistoryRelatedSuggestion.AutoCompleteHistorySuggestion import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteHistoryRelatedSuggestion.AutoCompleteInAppMessageSuggestion +import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteUrlSuggestion import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteUrlSuggestion.AutoCompleteBookmarkSuggestion import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteUrlSuggestion.AutoCompleteSwitchToTabSuggestion import com.duckduckgo.app.browser.autocomplete.AutoCompleteViewHolder.EmptySuggestionViewHolder @@ -81,6 +82,7 @@ class BrowserAutoCompleteSuggestionsAdapter( suggestions[position] is AutoCompleteInAppMessageSuggestion -> IN_APP_MESSAGE_TYPE suggestions[position] is AutoCompleteDefaultSuggestion -> DEFAULT_TYPE suggestions[position] is AutoCompleteSwitchToTabSuggestion -> SWITCH_TO_TAB_TYPE + suggestions[position] is AutoCompleteUrlSuggestion -> SWITCH_TO_TAB_TYPE else -> SUGGESTION_TYPE } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/autocomplete/SuggestionViewHolderFactory.kt b/app/src/main/java/com/duckduckgo/app/browser/autocomplete/SuggestionViewHolderFactory.kt index 144ea194c1e3..223ef547e4ab 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/autocomplete/SuggestionViewHolderFactory.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/autocomplete/SuggestionViewHolderFactory.kt @@ -271,7 +271,11 @@ sealed class AutoCompleteViewHolder(itemView: View) : RecyclerView.ViewHolder(it editQueryImage.setImageResource(R.drawable.ic_autocomplete_down_20dp) } - root.tag = SEARCH_ITEM + if (item.isAllowedInTopHits) { + root.tag = OTHER_ITEM + } else { + root.tag = SEARCH_ITEM + } } } diff --git a/app/src/test/java/com/duckduckgo/app/autocomplete/api/AutoCompleteApiTest.kt b/app/src/test/java/com/duckduckgo/app/autocomplete/api/AutoCompleteApiTest.kt index 494be477bede..9455fab5af85 100644 --- a/app/src/test/java/com/duckduckgo/app/autocomplete/api/AutoCompleteApiTest.kt +++ b/app/src/test/java/com/duckduckgo/app/autocomplete/api/AutoCompleteApiTest.kt @@ -108,7 +108,6 @@ class AutoCompleteApiTest { mockAutoCompleteRepository, mockTabRepository, mockUserStageStore, - coroutineTestRule.testDispatcherProvider, mockAutocompleteTabsFeature, ) } @@ -185,7 +184,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "example.com", "title", "https://example.com", isFavorite = true), AutoCompleteBookmarkSuggestion(phrase = "bar.com", "title", "https://bar.com", isFavorite = false), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteBookmarkSuggestion(phrase = "baz.com", "title", "https://baz.com", isFavorite = false), ), value.suggestions, @@ -231,7 +230,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "example.com", "title", "https://example.com", isFavorite = true), AutoCompleteSwitchToTabSuggestion(phrase = "bar.com", "title", "https://bar.com", tabId = "1"), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteSwitchToTabSuggestion(phrase = "baz.com", title = "title", url = "https://baz.com", tabId = "2"), AutoCompleteBookmarkSuggestion(phrase = "baz.com", "title", "https://baz.com", isFavorite = false), ), @@ -283,7 +282,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "example.com", "title", "https://example.com", isFavorite = true), AutoCompleteSwitchToTabSuggestion(phrase = "bar.com", "title", "https://bar.com", tabId = "1"), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteSwitchToTabSuggestion(phrase = "baz.com", title = "title", url = "https://baz.com", tabId = "4"), AutoCompleteBookmarkSuggestion(phrase = "baz.com", "title", "https://baz.com", isFavorite = false), ), @@ -345,11 +344,11 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "iii.com", title = "title", url = "https://iii.com", isFavorite = true), AutoCompleteSwitchToTabSuggestion(phrase = "lll.com", title = "title", url = "https://lll.com", tabId = "1"), - AutoCompleteSearchSuggestion(phrase = "aaa", isUrl = false), - AutoCompleteSearchSuggestion(phrase = "bbb", isUrl = false), - AutoCompleteSearchSuggestion(phrase = "ccc", isUrl = false), - AutoCompleteSearchSuggestion(phrase = "ddd", isUrl = false), - AutoCompleteSearchSuggestion(phrase = "eee", isUrl = false), + AutoCompleteSearchSuggestion(phrase = "aaa", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "bbb", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "ccc", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "ddd", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "eee", isUrl = false, isAllowedInTopHits = false), AutoCompleteSwitchToTabSuggestion(phrase = "mmm.com", title = "title", url = "https://mmm.com", tabId = "2"), AutoCompleteSwitchToTabSuggestion(phrase = "nnn.com", title = "title", url = "https://nnn.com", tabId = "3"), AutoCompleteSwitchToTabSuggestion(phrase = "ooo.com", title = "title", url = "https://ooo.com", tabId = "4"), @@ -402,7 +401,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "bar.com", "title", "https://bar.com", isFavorite = false), AutoCompleteBookmarkSuggestion(phrase = "example.com", "title", "https://example.com", isFavorite = true), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteBookmarkSuggestion(phrase = "baz.com", "title", "https://baz.com", isFavorite = false), ), value.suggestions, @@ -454,7 +453,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteHistorySuggestion(phrase = "bar.com", "title", "https://bar.com", isAllowedInTopHits = true), AutoCompleteHistorySuggestion(phrase = "foo.com", "title", "https://foo.com", isAllowedInTopHits = true), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteBookmarkSuggestion(phrase = "example.com", "title", "https://example.com", isFavorite = true), AutoCompleteBookmarkSuggestion(phrase = "baz.com", "title", "https://baz.com", isFavorite = false), ), @@ -496,7 +495,7 @@ class AutoCompleteApiTest { assertEquals( listOf( AutoCompleteHistorySearchSuggestion(phrase = "query", true), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), ), value.suggestions, ) @@ -525,7 +524,7 @@ class AutoCompleteApiTest { assertEquals( listOf( - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteHistorySearchSuggestion(phrase = "query", false), ), value.suggestions, @@ -577,7 +576,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "example.com", "title", "https://example.com", isFavorite = true), AutoCompleteBookmarkSuggestion(phrase = "baz.com", "title", "https://baz.com", isFavorite = false), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteHistorySuggestion(phrase = "bar.com/test", "title", "https://bar.com/test", isAllowedInTopHits = false), AutoCompleteHistorySuggestion(phrase = "foo.com/test", "title", "https://foo.com/test", isAllowedInTopHits = false), ), @@ -614,7 +613,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "example.com", "title", "https://example.com", isFavorite = true), AutoCompleteBookmarkSuggestion(phrase = "foo.com", "title", "https://foo.com", isFavorite = true), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteBookmarkSuggestion(phrase = "bar.com", "title", "https://bar.com", isFavorite = true), ), value.suggestions, @@ -656,67 +655,97 @@ class AutoCompleteApiTest { } @Test - fun whenAutoCompleteReturnsDuplicatedItemsThenDedup() = runTest { - whenever(mockAutoCompleteService.autoComplete("title")).thenReturn( + fun whenNavResultsReturnedThenItShowsAsMiddleSectionIfUrlIsBookmarkAndTab() = runTest { + whenever(mockAutoCompleteService.autoComplete("example")).thenReturn( listOf( - AutoCompleteServiceRawResult("example.com", false), - AutoCompleteServiceRawResult("foo.com", true), - AutoCompleteServiceRawResult("bar.com", true), - AutoCompleteServiceRawResult("baz.com", true), + AutoCompleteServiceRawResult("example", false), + AutoCompleteServiceRawResult("example.com", true), + AutoCompleteServiceRawResult("foo", false), + AutoCompleteServiceRawResult("bar", false), + AutoCompleteServiceRawResult("baz", false), ), ) whenever(mockSavedSitesRepository.getBookmarks()).thenReturn( flowOf( listOf( bookmark(title = "title example", url = "https://example.com"), - bookmark(title = "title foo", url = "https://foo.com/path/to/foo"), - bookmark(title = "title foo", url = "https://foo.com"), - bookmark(title = "title bar", url = "https://bar.com"), ), ), ) - whenever(mockSavedSitesRepository.getFavorites()).thenReturn( + whenever(mockSavedSitesRepository.getFavorites()).thenReturn(flowOf(emptyList())) + + whenever(mockTabRepository.flowTabs).thenReturn( flowOf( listOf( - favorite(title = "title example", url = "https://example.com"), - favorite(title = "title foo", url = "https://foo.com/path/to/foo"), - favorite(title = "title foo", url = "https://foo.com"), - favorite(title = "title bar", url = "https://bar.com"), + TabEntity(tabId = "1", position = 1, title = "example", url = "https://example.com"), ), ), ) - val result = testee.autoComplete("title") + val result = testee.autoComplete("example") val value = result.first() assertEquals( listOf( - AutoCompleteBookmarkSuggestion( - phrase = "example.com", - "title example", - "https://example.com", - isFavorite = true, - ), - AutoCompleteBookmarkSuggestion( - phrase = "foo.com/path/to/foo", - "title foo", - "https://foo.com/path/to/foo", - isFavorite = true, + AutoCompleteSwitchToTabSuggestion(phrase = "example.com", "example", "https://example.com", tabId = "1"), + AutoCompleteBookmarkSuggestion(phrase = "example.com", "title example", "https://example.com", isFavorite = false), + AutoCompleteSearchSuggestion(phrase = "example", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "example.com", isUrl = true, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "foo", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "bar", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "baz", isUrl = false, isAllowedInTopHits = false), + ), + value.suggestions, + ) + } + + @Test + fun whenNavResultsReturnedThenItShowsAsMiddleSectionIfUrlIsFavouriteAndTab() = runTest { + whenever(mockAutoCompleteService.autoComplete("example")).thenReturn( + listOf( + AutoCompleteServiceRawResult("example", false), + AutoCompleteServiceRawResult("example.com", true), + AutoCompleteServiceRawResult("foo", false), + AutoCompleteServiceRawResult("bar", false), + AutoCompleteServiceRawResult("baz", false), + ), + ) + whenever(mockSavedSitesRepository.getBookmarks()).thenReturn( + flowOf( + listOf( + bookmark(title = "title example", url = "https://example.com"), ), - AutoCompleteSearchSuggestion(phrase = "baz.com", true), - AutoCompleteBookmarkSuggestion( - phrase = "foo.com", - title = "title foo", - url = "https://foo.com", - isFavorite = true, + ), + ) + whenever(mockSavedSitesRepository.getFavorites()).thenReturn( + flowOf( + listOf( + favorite(title = "title example", url = "https://example.com"), ), - AutoCompleteBookmarkSuggestion( - phrase = "bar.com", - title = "title bar", - url = "https://bar.com", - isFavorite = true, + ), + ) + + whenever(mockTabRepository.flowTabs).thenReturn( + flowOf( + listOf( + TabEntity(tabId = "1", position = 1, title = "example", url = "https://example.com"), ), ), + ) + + val result = testee.autoComplete("example") + val value = result.first() + + assertEquals( + listOf( + AutoCompleteSwitchToTabSuggestion(phrase = "example.com", "example", "https://example.com", tabId = "1"), + AutoCompleteBookmarkSuggestion(phrase = "example.com", "title example", "https://example.com", isFavorite = true), + AutoCompleteSearchSuggestion(phrase = "example", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "example.com", isUrl = true, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "foo", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "bar", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "baz", isUrl = false, isAllowedInTopHits = false), + ), value.suggestions, ) } @@ -771,7 +800,7 @@ class AutoCompleteApiTest { fun whenAutoCompleteReturnsDuplicatedItemsThenDedupConsideringQueryParams() = runTest { whenever(mockAutoCompleteService.autoComplete("title")).thenReturn( listOf( - AutoCompleteServiceRawResult("example.com", false), + AutoCompleteServiceRawResult("example.com", true), AutoCompleteServiceRawResult("foo.com", true), AutoCompleteServiceRawResult("bar.com", true), AutoCompleteServiceRawResult("baz.com", true), @@ -795,8 +824,9 @@ class AutoCompleteApiTest { listOf( AutoCompleteBookmarkSuggestion(phrase = "foo.com?key=value", "title foo", "https://foo.com?key=value"), AutoCompleteBookmarkSuggestion(phrase = "foo.com", "title foo", "https://foo.com"), - AutoCompleteSearchSuggestion(phrase = "example.com", false), - AutoCompleteSearchSuggestion(phrase = "baz.com", true), + AutoCompleteSearchSuggestion(phrase = "example.com", isUrl = true, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "foo.com", isUrl = true, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "baz.com", isUrl = true, isAllowedInTopHits = false), AutoCompleteBookmarkSuggestion(phrase = "bar.com", "title bar", "https://bar.com"), ), value.suggestions, @@ -1099,7 +1129,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteHistorySuggestion(phrase = "example.com", "Title", "https://example.com", isAllowedInTopHits = true), AutoCompleteHistorySuggestion(phrase = "foo.com", "Title", "https://foo.com", isAllowedInTopHits = true), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteHistorySuggestion(phrase = "bar.com", "Title", "https://bar.com", isAllowedInTopHits = true), ), value.suggestions, @@ -1152,7 +1182,7 @@ class AutoCompleteApiTest { listOf( AutoCompleteHistorySuggestion(phrase = "example.com", "Title", "https://example.com", isAllowedInTopHits = true), AutoCompleteHistorySuggestion(phrase = "foo.com", "Title", "https://foo.com", isAllowedInTopHits = true), - AutoCompleteSearchSuggestion("foo", false), + AutoCompleteSearchSuggestion("foo", isUrl = false, isAllowedInTopHits = false), AutoCompleteHistorySuggestion(phrase = "bar.com", "Title", "https://bar.com", isAllowedInTopHits = true), ), value.suggestions, @@ -1359,6 +1389,236 @@ class AutoCompleteApiTest { assertEquals("example.com/path?query1=1&query2=1", "https://www.example.com/path?query1=1&query2=1".formatIfUrl()) } + @Test + fun whenAutoCompleteReturnsNavigationalLinkThatIsNotTabOrFavouriteOrBookmarkThenResultsAreShown() = runTest { + val searchTerm = "espn" + whenever(mockAutoCompleteService.autoComplete(searchTerm)).thenReturn( + listOf( + AutoCompleteServiceRawResult("espn", isNav = false), + AutoCompleteServiceRawResult("espn.com", isNav = true), + AutoCompleteServiceRawResult("espn fantasy football", isNav = false), + AutoCompleteServiceRawResult("espn sports", isNav = false), + AutoCompleteServiceRawResult("espn nba", isNav = false), + ), + ) + + whenever(mockSavedSitesRepository.getBookmarks()).thenReturn(flowOf(emptyList())) + whenever(mockSavedSitesRepository.getFavorites()).thenReturn(flowOf(emptyList())) + whenever(mockTabRepository.flowTabs).thenReturn(flowOf(emptyList())) + + val result = testee.autoComplete(searchTerm) + val value = result.first() + + assertEquals(5, value.suggestions.size) + assertEquals( + listOf( + AutoCompleteSearchSuggestion(phrase = "espn.com", isUrl = true, isAllowedInTopHits = true), + AutoCompleteSearchSuggestion(phrase = "espn", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn fantasy football", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn sports", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn nba", isUrl = false, isAllowedInTopHits = false), + ), + value.suggestions, + ) + } + + @Test + fun whenAutoCompleteReturnsNavigationalLinkThatIsTabAndNotFavouriteOrBookmarkThenResultsAreShown() = runTest { + val searchTerm = "espn" + whenever(mockAutoCompleteService.autoComplete(searchTerm)).thenReturn( + listOf( + AutoCompleteServiceRawResult("espn", isNav = false), + AutoCompleteServiceRawResult("espn.com", isNav = true), + AutoCompleteServiceRawResult("espn fantasy football", isNav = false), + AutoCompleteServiceRawResult("espn sports", isNav = false), + AutoCompleteServiceRawResult("espn nba", isNav = false), + ), + ) + + whenever(mockSavedSitesRepository.getBookmarks()).thenReturn(flowOf(emptyList())) + whenever(mockSavedSitesRepository.getFavorites()).thenReturn(flowOf(emptyList())) + + whenever(mockTabRepository.flowTabs).thenReturn( + flowOf( + listOf( + TabEntity(tabId = "1", position = 1, title = "espn", url = "https://espn.com"), + TabEntity(tabId = "2", position = 2, title = "title", url = "https://baz.com"), + ), + ), + ) + + val result = testee.autoComplete(searchTerm) + val value = result.first() + + assertEquals(6, value.suggestions.size) + assertEquals( + listOf( + AutoCompleteSwitchToTabSuggestion(phrase = "espn.com", "espn", "https://espn.com", tabId = "1"), + AutoCompleteSearchSuggestion(phrase = "espn.com", isUrl = true, isAllowedInTopHits = true), + AutoCompleteSearchSuggestion(phrase = "espn", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn fantasy football", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn sports", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn nba", isUrl = false, isAllowedInTopHits = false), + ), + value.suggestions, + ) + } + + @Test + fun whenAutoCompleteReturnsNavigationalLinkThatIsTabAndBookmarkThenResultsAreShown() = runTest { + val searchTerm = "espn" + whenever(mockAutoCompleteService.autoComplete(searchTerm)).thenReturn( + listOf( + AutoCompleteServiceRawResult("espn", isNav = false), + AutoCompleteServiceRawResult("espn.com", isNav = true), + AutoCompleteServiceRawResult("espn fantasy football", isNav = false), + AutoCompleteServiceRawResult("espn sports", isNav = false), + AutoCompleteServiceRawResult("espn nba", isNav = false), + ), + ) + + whenever(mockSavedSitesRepository.getBookmarks()).thenReturn( + flowOf( + listOf( + bookmark(title = "espn", url = "https://espn.com"), + bookmark(title = "title bar", url = "https://bar.com"), + bookmark(title = "the title foo", url = "https://foo.com"), + bookmark(title = "title foo baz", url = "https://baz.com"), + ), + ), + ) + whenever(mockSavedSitesRepository.getFavorites()).thenReturn(flowOf(emptyList())) + + whenever(mockTabRepository.flowTabs).thenReturn( + flowOf( + listOf( + TabEntity(tabId = "1", position = 1, title = "espn", url = "https://espn.com"), + TabEntity(tabId = "2", position = 2, title = "title", url = "https://baz.com"), + ), + ), + ) + + val result = testee.autoComplete(searchTerm) + val value = result.first() + + assertEquals(7, value.suggestions.size) + assertEquals( + listOf( + AutoCompleteSwitchToTabSuggestion(phrase = "espn.com", "espn", "https://espn.com", tabId = "1"), + AutoCompleteBookmarkSuggestion(phrase = "espn.com", title = "espn", url = "https://espn.com", isFavorite = false), + AutoCompleteSearchSuggestion(phrase = "espn", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn.com", isUrl = true, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn fantasy football", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn sports", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn nba", isUrl = false, isAllowedInTopHits = false), + ), + value.suggestions, + ) + } + + @Test + fun whenAutoCompleteReturnsNavigationalLinkThatIsTabAndFavoriteThenResultsAreShown() = runTest { + val searchTerm = "espn" + whenever(mockAutoCompleteService.autoComplete(searchTerm)).thenReturn( + listOf( + AutoCompleteServiceRawResult("espn", isNav = false), + AutoCompleteServiceRawResult("espn.com", isNav = true), + AutoCompleteServiceRawResult("espn fantasy football", isNav = false), + AutoCompleteServiceRawResult("espn sports", isNav = false), + AutoCompleteServiceRawResult("espn nba", isNav = false), + ), + ) + + whenever(mockSavedSitesRepository.getBookmarks()).thenReturn( + flowOf( + listOf( + bookmark(title = "espn", url = "https://espn.com"), + bookmark(title = "title bar", url = "https://bar.com"), + bookmark(title = "the title foo", url = "https://foo.com"), + bookmark(title = "title foo baz", url = "https://baz.com"), + ), + ), + ) + + whenever(mockSavedSitesRepository.getFavorites()).thenReturn( + flowOf( + listOf( + favorite(title = "espn", url = "https://espn.com"), + ), + ), + ) + + whenever(mockTabRepository.flowTabs).thenReturn( + flowOf( + listOf( + TabEntity(tabId = "1", position = 1, title = "espn", url = "https://espn.com"), + TabEntity(tabId = "2", position = 2, title = "title", url = "https://baz.com"), + ), + ), + ) + + val result = testee.autoComplete(searchTerm) + val value = result.first() + + assertEquals(7, value.suggestions.size) + assertEquals( + listOf( + AutoCompleteBookmarkSuggestion(phrase = "espn.com", title = "espn", url = "https://espn.com", isFavorite = true), + AutoCompleteSwitchToTabSuggestion(phrase = "espn.com", "espn", "https://espn.com", tabId = "1"), + AutoCompleteSearchSuggestion(phrase = "espn", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn.com", isUrl = true, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn fantasy football", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn sports", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn nba", isUrl = false, isAllowedInTopHits = false), + ), + value.suggestions, + ) + } + + @Test + fun whenAutoCompleteReturnsNavigationalLinkThatIsTabAndAnotherTabResultAppearsThenResultsAreShown() = runTest { + val searchTerm = "espn" + whenever(mockAutoCompleteService.autoComplete(searchTerm)).thenReturn( + listOf( + AutoCompleteServiceRawResult("espn", isNav = false), + AutoCompleteServiceRawResult("espn.com", isNav = true), + AutoCompleteServiceRawResult("espn fantasy football", isNav = false), + AutoCompleteServiceRawResult("espn sports", isNav = false), + AutoCompleteServiceRawResult("espn nba", isNav = false), + ), + ) + + whenever(mockSavedSitesRepository.getBookmarks()).thenReturn(flowOf(emptyList())) + + whenever(mockSavedSitesRepository.getFavorites()).thenReturn(flowOf(emptyList())) + + whenever(mockTabRepository.flowTabs).thenReturn( + flowOf( + listOf( + TabEntity(tabId = "1", position = 1, title = "espn", url = "https://espn.com"), + TabEntity(tabId = "2", position = 2, title = "espn nfl", url = "https://espn.com/nfl"), + ), + ), + ) + + val result = testee.autoComplete(searchTerm) + val value = result.first() + + assertEquals(7, value.suggestions.size) + assertEquals( + listOf( + AutoCompleteSwitchToTabSuggestion(phrase = "espn.com", "espn", "https://espn.com", tabId = "1"), + AutoCompleteSwitchToTabSuggestion(phrase = "espn.com/nfl", "espn nfl", "https://espn.com/nfl", tabId = "2"), + AutoCompleteSearchSuggestion(phrase = "espn", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn.com", isUrl = true, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn fantasy football", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn sports", isUrl = false, isAllowedInTopHits = false), + AutoCompleteSearchSuggestion(phrase = "espn nba", isUrl = false, isAllowedInTopHits = false), + ), + value.suggestions, + ) + } + private fun favorite( id: String = UUID.randomUUID().toString(), title: String = "title", diff --git a/app/src/test/java/com/duckduckgo/app/systemsearch/SystemSearchViewModelTest.kt b/app/src/test/java/com/duckduckgo/app/systemsearch/SystemSearchViewModelTest.kt index a96807506251..aceebda892f2 100644 --- a/app/src/test/java/com/duckduckgo/app/systemsearch/SystemSearchViewModelTest.kt +++ b/app/src/test/java/com/duckduckgo/app/systemsearch/SystemSearchViewModelTest.kt @@ -264,7 +264,7 @@ class SystemSearchViewModelTest { @Test fun whenUserSubmitsAutocompleteResultThenBrowserLaunchedAndPixelSent() { - testee.userSubmittedAutocompleteResult(AutoCompleteSearchSuggestion(phrase = AUTOCOMPLETE_RESULT, isUrl = false)) + testee.userSubmittedAutocompleteResult(AutoCompleteSearchSuggestion(phrase = AUTOCOMPLETE_RESULT, isUrl = false, isAllowedInTopHits = false)) verify(commandObserver, atLeastOnce()).onChanged(commandCaptor.capture()) assertEquals(Command.LaunchBrowser(AUTOCOMPLETE_RESULT), commandCaptor.lastValue) verify(mockPixel).fire(INTERSTITIAL_LAUNCH_BROWSER_QUERY) @@ -598,7 +598,10 @@ class SystemSearchViewModelTest { const val BLANK_QUERY = "" const val AUTOCOMPLETE_RESULT = "autocomplete result" val deviceApp = DeviceApp("", "", Intent()) - val autocompleteQueryResult = AutoCompleteResult(QUERY, listOf(AutoCompleteSearchSuggestion(QUERY, false))) + val autocompleteQueryResult = AutoCompleteResult( + QUERY, + listOf(AutoCompleteSearchSuggestion(QUERY, isUrl = false, isAllowedInTopHits = false)), + ) val autocompleteBlankResult = AutoCompleteResult(BLANK_QUERY, emptyList()) val appQueryResult = listOf(deviceApp) val appBlankResult = emptyList() From f32c3baebdd2175041643c0bc09d7e31f8e9ed8e Mon Sep 17 00:00:00 2001 From: Lukasz Macionczyk Date: Fri, 13 Dec 2024 10:33:37 +0100 Subject: [PATCH 03/32] Fix concurrency issue when populating FF inventory UI (#5364) Task/Issue URL: https://app.asana.com/0/488551667048375/1208921958672400/f ### Description ### Steps to test this PR _Feature 1_ - [ ] - [ ] ### No UI changes --- .../ui/FeatureToggleInventoryActivity.kt | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/feature-toggles/feature-toggles-internal/src/main/java/com/duckduckgo/examplefeature/internal/ui/FeatureToggleInventoryActivity.kt b/feature-toggles/feature-toggles-internal/src/main/java/com/duckduckgo/examplefeature/internal/ui/FeatureToggleInventoryActivity.kt index 8436dbaac8f8..bc929f8209a1 100644 --- a/feature-toggles/feature-toggles-internal/src/main/java/com/duckduckgo/examplefeature/internal/ui/FeatureToggleInventoryActivity.kt +++ b/feature-toggles/feature-toggles-internal/src/main/java/com/duckduckgo/examplefeature/internal/ui/FeatureToggleInventoryActivity.kt @@ -21,8 +21,9 @@ import android.os.Bundle import android.text.Editable import android.view.View import androidx.core.view.isVisible -import androidx.lifecycle.AtomicReference +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle import com.duckduckgo.anvil.annotations.ContributeToActivityStarter import com.duckduckgo.anvil.annotations.InjectWith import com.duckduckgo.anvil.annotations.PriorityKey @@ -48,6 +49,7 @@ import javax.inject.Inject import kotlinx.coroutines.CoroutineStart.LAZY import kotlinx.coroutines.Deferred import kotlinx.coroutines.async +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import okio.Buffer @@ -64,21 +66,11 @@ class FeatureToggleInventoryActivity : DuckDuckGoActivity() { @Inject lateinit var moshi: Moshi - private val featureNameFilter: AtomicReference = AtomicReference("") + private val featureNameFilter = MutableStateFlow("") private val searchTextWatcher = object : TextChangedWatcher() { override fun afterTextChanged(editable: Editable) { - when { - editable.toString().isBlank() -> { - featureNameFilter.set("") - } - else -> { - featureNameFilter.set(editable.toString()) - } - } - lifecycleScope.launch { - populateViews() - } + featureNameFilter.value = editable.toString().trim() } } @@ -99,12 +91,14 @@ class FeatureToggleInventoryActivity : DuckDuckGoActivity() { binding.searchName.addTextChangedListener(searchTextWatcher) lifecycleScope.launch { - populateViews() + lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { + featureNameFilter.collect { populateViews(nameFilter = it) } + } } } - private suspend fun populateViews() = withContext(dispatcherProvider.io()) { - val views = getFeatureViews() + private suspend fun populateViews(nameFilter: String) = withContext(dispatcherProvider.io()) { + val views = getFeatureViews(nameFilter) withContext(dispatcherProvider.main()) { binding.featureToggle.removeAllViews() @@ -114,9 +108,9 @@ class FeatureToggleInventoryActivity : DuckDuckGoActivity() { } } - private suspend fun getFeatureViews(): List = withContext(dispatcherProvider.io()) { + private suspend fun getFeatureViews(nameFilter: String): List = withContext(dispatcherProvider.io()) { val toggles = this@FeatureToggleInventoryActivity.toggles.await() - val match = featureNameFilter.get().lowercase() + val match = nameFilter.lowercase() val parentFeatures = toggles .filter { it.featureName().parentName == null } .sortedBy { it.featureName().name.lowercase() } From 93d4adb5a15392918d2b30cec05d311440fce0c5 Mon Sep 17 00:00:00 2001 From: Aitor Viana Date: Fri, 13 Dec 2024 13:33:03 +0000 Subject: [PATCH 04/32] Record malware blocks (#5389) Task/Issue URL: https://app.asana.com/0/1142021229838617/1208368538104397/f ### Description This PR bumps the our netguard (vpn) library to 1.7.0 Also adds the `recordMalwareBlock` callback, called from native when malware is blocked. ### Steps to test this PR _Test_ - [x] Install from this branch and go through onboarding - [x] Enabled VPN - [x] filter logcat by "package:mine tag:GoBackend Malware blocked" - [x] open tab and go to `vpn-malware.goduckgo.com` - [x] verify "Malware blocked in vpn-malware.goduckgo.com" shows - [x] Smoke test browser and VPN --- .../main/java/com/wireguard/android/backend/GoBackend.kt | 6 ++++++ versions.properties | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/network-protection/network-protection-impl/src/main/java/com/wireguard/android/backend/GoBackend.kt b/network-protection/network-protection-impl/src/main/java/com/wireguard/android/backend/GoBackend.kt index 900e144b7916..87f1546d9c4b 100644 --- a/network-protection/network-protection-impl/src/main/java/com/wireguard/android/backend/GoBackend.kt +++ b/network-protection/network-protection-impl/src/main/java/com/wireguard/android/backend/GoBackend.kt @@ -109,6 +109,12 @@ class GoBackend @Inject constructor( return shouldAllowDomain(sni, uid) } + // Called from native code + @Suppress("unused") + fun recordMalwareBlock(domain: String) { + logcat { "Malware blocked in $domain" } + } + private fun shouldAllowDomain( name: String, uid: Int, diff --git a/versions.properties b/versions.properties index 0ea6b052d5c3..12f817a03241 100644 --- a/versions.properties +++ b/versions.properties @@ -77,7 +77,7 @@ version.com.airbnb.android..lottie=5.2.0 version.com.android.installreferrer..installreferrer=2.2 -version.com.duckduckgo.netguard..netguard-android=1.6.12 +version.com.duckduckgo.netguard..netguard-android=1.7.0 version.com.duckduckgo.synccrypto..sync-crypto-android=0.3.0 From 47e27c4846cc2e96e90ae581b092fea4c12cd71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Fri, 13 Dec 2024 15:30:11 +0100 Subject: [PATCH 05/32] add DefaultBrowserBottomSheetDialog (#5388) Task/Issue URL: https://app.asana.com/0/72649045549333/1208944504536341/f --- .../ui/DefaultBrowserBottomSheetDialog.kt | 63 +++++++++++++++ .../drawable/ic_device_mobile_default_128.xml | 77 ++++++++++++++++++ .../layout/bottom_sheet_default_browser.xml | 81 +++++++++++++++++++ app/src/main/res/values/donottranslate.xml | 6 ++ 4 files changed, 227 insertions(+) create mode 100644 app/src/main/java/com/duckduckgo/app/browser/defaultbrowsing/prompts/ui/DefaultBrowserBottomSheetDialog.kt create mode 100644 app/src/main/res/drawable/ic_device_mobile_default_128.xml create mode 100644 app/src/main/res/layout/bottom_sheet_default_browser.xml diff --git a/app/src/main/java/com/duckduckgo/app/browser/defaultbrowsing/prompts/ui/DefaultBrowserBottomSheetDialog.kt b/app/src/main/java/com/duckduckgo/app/browser/defaultbrowsing/prompts/ui/DefaultBrowserBottomSheetDialog.kt new file mode 100644 index 000000000000..08929fcdc2ab --- /dev/null +++ b/app/src/main/java/com/duckduckgo/app/browser/defaultbrowsing/prompts/ui/DefaultBrowserBottomSheetDialog.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.app.browser.defaultbrowsing.prompts.ui + +import android.annotation.SuppressLint +import android.content.Context +import android.view.LayoutInflater +import android.widget.FrameLayout +import com.duckduckgo.app.browser.databinding.BottomSheetDefaultBrowserBinding +import com.duckduckgo.mobile.android.R as CommonR +import com.google.android.material.R +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.google.android.material.shape.CornerFamily +import com.google.android.material.shape.MaterialShapeDrawable + +@SuppressLint("NoBottomSheetDialog") +class DefaultBrowserBottomSheetDialog(private val context: Context) : BottomSheetDialog(context) { + + private val binding: BottomSheetDefaultBrowserBinding = BottomSheetDefaultBrowserBinding.inflate(LayoutInflater.from(context)) + + init { + setContentView(binding.root) + // We need the dialog to always be expanded and not draggable because the content takes up a lot of vertical space and requires a scroll view, + // especially in landscape aspect-ratios. If the dialog started as collapsed, the drag would interfere with internal scroll. + this.behavior.state = BottomSheetBehavior.STATE_EXPANDED + this.behavior.isDraggable = false + roundCornersAlways(this) + } + + /** + * By default, when bottom sheet dialog is expanded, the corners become squared. + * This function ensures that the bottom sheet dialog will have rounded corners even when in an expanded state. + */ + private fun roundCornersAlways(dialog: BottomSheetDialog) { + dialog.setOnShowListener { dialogInterface -> + val bottomSheetDialog = dialogInterface as BottomSheetDialog + val bottomSheet = bottomSheetDialog.findViewById(R.id.design_bottom_sheet) + + val shapeDrawable = MaterialShapeDrawable.createWithElevationOverlay(context) + shapeDrawable.shapeAppearanceModel = shapeDrawable.shapeAppearanceModel + .toBuilder() + .setTopLeftCorner(CornerFamily.ROUNDED, context.resources.getDimension(CommonR.dimen.dialogBorderRadius)) + .setTopRightCorner(CornerFamily.ROUNDED, context.resources.getDimension(CommonR.dimen.dialogBorderRadius)) + .build() + bottomSheet?.background = shapeDrawable + } + } +} diff --git a/app/src/main/res/drawable/ic_device_mobile_default_128.xml b/app/src/main/res/drawable/ic_device_mobile_default_128.xml new file mode 100644 index 000000000000..2c9bbe98f7fc --- /dev/null +++ b/app/src/main/res/drawable/ic_device_mobile_default_128.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/bottom_sheet_default_browser.xml b/app/src/main/res/layout/bottom_sheet_default_browser.xml new file mode 100644 index 000000000000..409d97b3c661 --- /dev/null +++ b/app/src/main/res/layout/bottom_sheet_default_browser.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index a8438ccd8e0d..fae7b2942a90 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -68,4 +68,10 @@ Ready for a deal…? VPN.

Activate it with a paid Privacy Pro subscription.]]>
+ + Protect your personal data every time with DuckDuckGo + If you love protecting your data, make us your default browser. All site links will open in DuckDuckGo. + Set As Your Default Browser + Not Now +
From cc21a12f8f3d4bce0e930e1f2887680e861f70a7 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Fri, 13 Dec 2024 16:16:26 +0100 Subject: [PATCH 06/32] Update Settings: Update Ppro Purchasing and Setting items (#5385) Task/Issue URL: https://app.asana.com/0/1207908166761516/1208966262488270/f ### Description Initial changes to start moving Ppro settings to new Settings world. This PR focuses specifically on the Purchasing state as well as the Subscription Setting item state, as these are part of the same plugin. [Designs](https://www.figma.com/design/CjH849hL53lhsPlf6Ufeo4/%E2%9A%99%EF%B8%8F-Browser-Settings-Documentation-(All-Platforms)?node-id=7605-431390&node-type=instance&t=ZKIMXkdZqzh5gEjU-11) ### Steps to test this PR Prerequisite: Enable `newSettings` feature toggle Prerequisite: Apply the patch in the [Asana task](https://app.asana.com/0/1207908166761516/1208966262488270/f) Also remember VPN, PIR, and ITR are **not** changed in this PR ### _Not purchased_ - [x] Set ln 99 of `ProSettingViewModel` to `_viewState.emit(viewState.value.copy(status = EXPIRED, region = SubscriptionRegion.US))` - [x] Open Settings - [x] Check against [designs](https://www.figma.com/design/CjH849hL53lhsPlf6Ufeo4/%E2%9A%99%EF%B8%8F-Browser-Settings-Documentation-(All-Platforms)?node-id=7605-431390&node-type=instance&t=ZKIMXkdZqzh5gEjU-11) - [x] Click items - [x] Ensure correct screens are open | Before | After | | ------ | ----- | ![not_purchased_original](https://github.com/user-attachments/assets/bfc77f48-77f2-49f6-96fd-c650b082fa15)|![Screenshot_20241212_192120](https://github.com/user-attachments/assets/316945a7-b5ae-4777-aa37-05822f19ec0b)| ### _Purchased_ - [x] Set ln 99 of `ProSettingViewModel` to `_viewState.emit(viewState.value.copy(status = AUTO_RENEWABLE, region = SubscriptionRegion.US))` - [x] Open Settings - [x] Check against [designs](https://www.figma.com/design/CjH849hL53lhsPlf6Ufeo4/%E2%9A%99%EF%B8%8F-Browser-Settings-Documentation-(All-Platforms)?node-id=7605-431390&node-type=instance&t=ZKIMXkdZqzh5gEjU-11) - [x] Click Subscription Settings - [x] Ensure Subscription Settings is opened | Before | After | | ------ | ----- | ![purchased_original](https://github.com/user-attachments/assets/d0c244c0-5535-4adc-944a-a324a8f1eda7)|![subscribed](https://github.com/user-attachments/assets/459f5e63-f161-4809-b25c-d01422ebfcfa)| ### _Activating (Waiting)_ - [x] Set ln 99 of `ProSettingViewModel` to `_viewState.emit(viewState.value.copy(status = WAITING, region = SubscriptionRegion.US))` - [x] Open Settings - [x] Check against [designs](https://www.figma.com/design/CjH849hL53lhsPlf6Ufeo4/%E2%9A%99%EF%B8%8F-Browser-Settings-Documentation-(All-Platforms)?node-id=7605-431390&node-type=instance&t=ZKIMXkdZqzh5gEjU-11) - [x] Click Subscription Settings - [x] Ensure Subscription Settings is opened | Before | After | | ------ | ----- | ![original_waiting](https://github.com/user-attachments/assets/05934c81-c3da-4b40-bfd7-c453f07f919e)|![activating](https://github.com/user-attachments/assets/40ec262f-b764-44f0-9d80-eaabb5ce6f73)| ### _Expired_ - [x] Set ln 99 of `ProSettingViewModel` to `_viewState.emit(viewState.value.copy(status = EXPIRED, region = SubscriptionRegion.US))` - [x] Open Settings - [x] Check against [designs](https://www.figma.com/design/CjH849hL53lhsPlf6Ufeo4/%E2%9A%99%EF%B8%8F-Browser-Settings-Documentation-(All-Platforms)?node-id=7605-431390&node-type=instance&t=ZKIMXkdZqzh5gEjU-11) - [x] Click Subscription Settings - [x] Ensure Subscription Settings is opened | Before | After | | ------ | ----- | ![original_expired](https://github.com/user-attachments/assets/3d26f2b7-382c-4d2a-b5ee-3c16b28e413f)|![expired](https://github.com/user-attachments/assets/3972412e-6daf-4a10-99b1-48f85d104914)| --- .../app/settings/NewSettingsActivity.kt | 2 +- .../main/res/layout/content_settings_new.xml | 13 +- .../ui/view/expand/DaxExpandableMenuItem.kt | 10 +- .../ui/view/listitem/BookmarksListItem.kt | 2 +- .../common/ui/view/listitem/DaxListItem.kt | 21 +- .../ui/view/listitem/OneLineListItem.kt | 8 +- .../ui/view/listitem/SettingsListItem.kt | 19 +- .../ui/view/listitem/TwoLineListItem.kt | 8 +- .../res/layout/component_two_line_item.xml | 26 ++- .../src/main/res/values/attrs-lists.xml | 7 + .../src/main/res/drawable/ic_vpn_color_24.xml | 16 ++ .../drawable/ic_vpn_grayscale_color_24.xml | 16 ++ .../settings/plugins/SubsSettingsPlugins.kt | 10 +- .../settings/views/LegacyProSettingView.kt | 196 ++++++++++++++++++ .../views/LegacyProSettingViewModel.kt | 105 ++++++++++ .../impl/settings/views/ProSettingView.kt | 78 ++++--- .../ic_identity_blocked_pir_color_24.xml | 0 ...dentity_blocked_pir_grayscale_color_24.xml | 0 ...ic_identity_theft_restoration_color_24.xml | 0 ...y_theft_restoration_grayscale_color_24.xml | 0 .../res/drawable/ic_privacy_pro_color_24.xml | 0 .../main/res/layout/legacy_view_settings.xml | 110 ++++++++++ .../src/main/res/layout/view_settings.xml | 37 ++-- .../src/main/res/values/donottranslate.xml | 22 ++ .../LegacyLegacyProSettingViewModelTest.kt | 82 ++++++++ 25 files changed, 695 insertions(+), 93 deletions(-) rename {common/common-ui => network-protection/network-protection-impl}/src/main/res/drawable/ic_vpn_color_24.xml (81%) rename {common/common-ui => network-protection/network-protection-impl}/src/main/res/drawable/ic_vpn_grayscale_color_24.xml (81%) create mode 100644 subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingView.kt create mode 100644 subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt rename {common/common-ui => subscriptions/subscriptions-impl}/src/main/res/drawable/ic_identity_blocked_pir_color_24.xml (100%) rename {common/common-ui => subscriptions/subscriptions-impl}/src/main/res/drawable/ic_identity_blocked_pir_grayscale_color_24.xml (100%) rename {common/common-ui => subscriptions/subscriptions-impl}/src/main/res/drawable/ic_identity_theft_restoration_color_24.xml (100%) rename {common/common-ui => subscriptions/subscriptions-impl}/src/main/res/drawable/ic_identity_theft_restoration_grayscale_color_24.xml (100%) rename {common/common-ui => subscriptions/subscriptions-impl}/src/main/res/drawable/ic_privacy_pro_color_24.xml (100%) create mode 100644 subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_settings.xml create mode 100644 subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml create mode 100644 subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt diff --git a/app/src/main/java/com/duckduckgo/app/settings/NewSettingsActivity.kt b/app/src/main/java/com/duckduckgo/app/settings/NewSettingsActivity.kt index 23c911930f0b..acded73d4e11 100644 --- a/app/src/main/java/com/duckduckgo/app/settings/NewSettingsActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/settings/NewSettingsActivity.kt @@ -153,7 +153,7 @@ class NewSettingsActivity : DuckDuckGoActivity() { get() = binding.includeSettings.contentSettingsInternal private val viewsPro - get() = binding.includeSettings.settingsSectionPro + get() = binding.includeSettings.contentSettingsPrivacyPro override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/res/layout/content_settings_new.xml b/app/src/main/res/layout/content_settings_new.xml index 4b0f1d6b3cd4..d8c6f6803545 100644 --- a/app/src/main/res/layout/content_settings_new.xml +++ b/app/src/main/res/layout/content_settings_new.xml @@ -36,13 +36,14 @@ android:layout_marginTop="@dimen/keyline_4" /> + android:id="@+id/contentSettingsPrivacyPro" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" > + + android:layout_width="match_parent" + android:layout_height="wrap_content" /> Small @@ -306,7 +313,7 @@ abstract class DaxListItem( } } - fun dimension(size: LeadingIconSize): Int { + fun dimension(size: IconSize): Int { return when (size) { Small -> R.dimen.listItemImageSmallSize Medium -> R.dimen.listItemImageMediumSize diff --git a/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/OneLineListItem.kt b/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/OneLineListItem.kt index 9971561f021f..f26fc192ffc3 100644 --- a/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/OneLineListItem.kt +++ b/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/OneLineListItem.kt @@ -21,7 +21,7 @@ import android.util.AttributeSet import android.view.View import android.widget.ImageView import com.duckduckgo.common.ui.view.DaxSwitch -import com.duckduckgo.common.ui.view.listitem.DaxListItem.LeadingIconSize.Medium +import com.duckduckgo.common.ui.view.listitem.DaxListItem.IconSize.Medium import com.duckduckgo.common.ui.view.text.DaxTextView import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.mobile.android.R @@ -93,13 +93,13 @@ class OneLineListItem @JvmOverloads constructor( ImageBackground.None } - val leadingIconSize = if (hasValue(R.styleable.OneLineListItem_leadingIconSize)) { - LeadingIconSize.from(getInt(R.styleable.OneLineListItem_leadingIconSize, 1)) + val iconSize = if (hasValue(R.styleable.OneLineListItem_leadingIconSize)) { + IconSize.from(getInt(R.styleable.OneLineListItem_leadingIconSize, 1)) } else { Medium } - setLeadingIconSize(leadingIconSize, leadingIconBackground) + setLeadingIconSize(iconSize, leadingIconBackground) val showTrailingIcon = hasValue(R.styleable.OneLineListItem_trailingIcon) val showSwitch = getBoolean(R.styleable.OneLineListItem_showSwitch, false) diff --git a/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/SettingsListItem.kt b/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/SettingsListItem.kt index cd354bba2d9f..a9352c8aa72f 100644 --- a/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/SettingsListItem.kt +++ b/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/SettingsListItem.kt @@ -19,6 +19,7 @@ package com.duckduckgo.common.ui.view.listitem import android.content.Context import android.util.AttributeSet import android.widget.ImageView +import androidx.annotation.DrawableRes import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isVisible import com.duckduckgo.common.ui.view.StatusIndicatorView @@ -38,13 +39,13 @@ class SettingsListItem @JvmOverloads constructor( private val binding: ViewSettingsListItemBinding by viewBinding() - val primaryText: DaxTextView + private val primaryText: DaxTextView get() = binding.primaryText - val leadingIcon: ImageView + private val leadingIcon: ImageView get() = binding.leadingIcon - val betaPill: ImageView + private val betaPill: ImageView get() = binding.betaPill - val statusIndicator: StatusIndicatorView + private val statusIndicator: StatusIndicatorView get() = binding.statusIndicator init { @@ -65,9 +66,9 @@ class SettingsListItem @JvmOverloads constructor( leadingIcon.gone() } - setPillVisible(getBoolean(R.styleable.SettingsListItem_showBetaPill, false)) + betaPill.isVisible = getBoolean(R.styleable.SettingsListItem_showBetaPill, false) - val indicatorStatus = Status.from(getInt(R.styleable.SettingsListItem_indicatorStatus, 0)) + val indicatorStatus = Status.from(getInt(R.styleable.SettingsListItem_indicatorStatus, 2)) statusIndicator.setStatus(indicatorStatus) recycle() @@ -79,11 +80,13 @@ class SettingsListItem @JvmOverloads constructor( binding.root.setOnClickListener { onClick() } } + /** Sets whether the status indicator is on or off */ fun setStatus(isOn: Boolean) { statusIndicator.setStatus(if (isOn) Status.ON else Status.OFF) } - private fun setPillVisible(isVisible: Boolean) { - betaPill.isVisible = isVisible + /** Sets the leading icon image resource */ + fun setLeadingIconResource(@DrawableRes idRes: Int) { + leadingIcon.setImageResource(idRes) } } diff --git a/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/TwoLineListItem.kt b/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/TwoLineListItem.kt index da88bf0c09c9..8ca55b8564f6 100644 --- a/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/TwoLineListItem.kt +++ b/common/common-ui/src/main/java/com/duckduckgo/common/ui/view/listitem/TwoLineListItem.kt @@ -23,7 +23,7 @@ import android.util.AttributeSet import android.view.View import android.widget.ImageView import com.duckduckgo.common.ui.view.DaxSwitch -import com.duckduckgo.common.ui.view.listitem.DaxListItem.LeadingIconSize.Medium +import com.duckduckgo.common.ui.view.listitem.DaxListItem.IconSize.Medium import com.duckduckgo.common.ui.view.text.DaxTextView import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.mobile.android.R @@ -100,7 +100,7 @@ class TwoLineListItem @JvmOverloads constructor( } val leadingIconSize = if (hasValue(R.styleable.TwoLineListItem_leadingIconSize)) { - LeadingIconSize.from(getInt(R.styleable.TwoLineListItem_leadingIconSize, 1)) + IconSize.from(getInt(R.styleable.TwoLineListItem_leadingIconSize, 1)) } else { Medium } @@ -114,6 +114,10 @@ class TwoLineListItem @JvmOverloads constructor( setPillVisible(getBoolean(R.styleable.TwoLineListItem_showBetaPill, false)) val showTrailingIcon = hasValue(R.styleable.TwoLineListItem_trailingIcon) + + val trailingIconSize = IconSize.from(getInt(R.styleable.TwoLineListItem_trailingIconSize, Medium.ordinal)) + setTrailingIconSize(trailingIconSize) + val showSwitch = getBoolean(R.styleable.TwoLineListItem_showSwitch, false) when { showSwitch -> showSwitch() diff --git a/common/common-ui/src/main/res/layout/component_two_line_item.xml b/common/common-ui/src/main/res/layout/component_two_line_item.xml index ef9c4dff9d80..6884d1f403fb 100644 --- a/common/common-ui/src/main/res/layout/component_two_line_item.xml +++ b/common/common-ui/src/main/res/layout/component_two_line_item.xml @@ -171,13 +171,37 @@ app:trailingIcon="@drawable/ic_menu_vertical_24" /> + + + + diff --git a/common/common-ui/src/main/res/values/attrs-lists.xml b/common/common-ui/src/main/res/values/attrs-lists.xml index d61b6e549644..d5520e29d512 100644 --- a/common/common-ui/src/main/res/values/attrs-lists.xml +++ b/common/common-ui/src/main/res/values/attrs-lists.xml @@ -54,6 +54,12 @@ + + + + + + @@ -87,6 +93,7 @@ + diff --git a/common/common-ui/src/main/res/drawable/ic_vpn_color_24.xml b/network-protection/network-protection-impl/src/main/res/drawable/ic_vpn_color_24.xml similarity index 81% rename from common/common-ui/src/main/res/drawable/ic_vpn_color_24.xml rename to network-protection/network-protection-impl/src/main/res/drawable/ic_vpn_color_24.xml index 5cc01cc7fc4b..78af318a96f4 100644 --- a/common/common-ui/src/main/res/drawable/ic_vpn_color_24.xml +++ b/network-protection/network-protection-impl/src/main/res/drawable/ic_vpn_color_24.xml @@ -1,3 +1,19 @@ + + + { + binding.subscriptionBuyContainer.gone() + binding.subscriptionRestoreContainer.gone() + binding.subscriptionWaitingContainer.gone() + binding.subscriptionSettingContainer.show() + } + WAITING -> { + binding.subscriptionBuyContainer.gone() + binding.subscriptionWaitingContainer.show() + binding.subscriptionSettingContainer.gone() + binding.subscriptionRestoreContainer.show() + } + EXPIRED, INACTIVE -> { + binding.subscriptionBuy.setPrimaryText(context.getString(R.string.subscriptionSettingExpired)) + binding.subscriptionBuy.setSecondaryText(context.getString(R.string.subscriptionSettingExpiredSubtitle)) + binding.subscriptionBuy.setItemStatus(ALERT) + binding.subscriptionGet.setText(R.string.subscriptionSettingExpiredViewPlans) + binding.subscriptionBuyContainer.show() + binding.subscriptionSettingContainer.show() + binding.subscriptionWaitingContainer.gone() + binding.subscriptionRestoreContainer.gone() + } + else -> { + binding.subscriptionBuy.setPrimaryText(context.getString(R.string.subscriptionSettingSubscribe)) + binding.subscriptionBuy.setSecondaryText( + when (viewState.region) { + ROW -> context.getString(R.string.subscriptionSettingSubscribeSubtitleRow) + US -> context.getString(R.string.subscriptionSettingSubscribeSubtitle) + else -> "" + }, + ) + binding.subscriptionBuy.setItemStatus(DISABLED) + binding.subscriptionGet.setText(R.string.subscriptionSettingGet) + binding.subscriptionBuyContainer.show() + binding.subscriptionSettingContainer.gone() + binding.subscriptionWaitingContainer.gone() + binding.subscriptionRestoreContainer.show() + } + } + } + + private fun processCommands(command: Command) { + when (command) { + is OpenSettings -> { + globalActivityStarter.start(context, SubscriptionsSettingsScreenWithEmptyParams) + } + is OpenBuyScreen -> { + globalActivityStarter.start( + context, + SubscriptionsWebViewActivityWithParams( + url = SubscriptionsConstants.BUY_URL, + ), + ) + } + is OpenRestoreScreen -> { + globalActivityStarter.start(context, RestoreSubscriptionScreenWithParams(isOriginWeb = false)) + } + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt new file mode 100644 index 000000000000..a824f85d7e50 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.duckduckgo.anvil.annotations.ContributesViewModel +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import com.duckduckgo.subscriptions.api.SubscriptionStatus.UNKNOWN +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_ROW +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US +import com.duckduckgo.subscriptions.impl.SubscriptionsManager +import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender +import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.Command.OpenBuyScreen +import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.Command.OpenRestoreScreen +import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.Command.OpenSettings +import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.ViewState.SubscriptionRegion +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch + +@SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle +@ContributesViewModel(ViewScope::class) +class LegacyProSettingViewModel @Inject constructor( + private val subscriptionsManager: SubscriptionsManager, + private val pixelSender: SubscriptionPixelSender, +) : ViewModel(), DefaultLifecycleObserver { + + sealed class Command { + data object OpenSettings : Command() + data object OpenBuyScreen : Command() + data object OpenRestoreScreen : Command() + } + + private val command = Channel(1, BufferOverflow.DROP_OLDEST) + internal fun commands(): Flow = command.receiveAsFlow() + data class ViewState( + val status: SubscriptionStatus = UNKNOWN, + val region: SubscriptionRegion? = null, + ) { + enum class SubscriptionRegion { US, ROW } + } + + private val _viewState = MutableStateFlow(ViewState()) + val viewState = _viewState.asStateFlow() + + fun onSettings() { + sendCommand(OpenSettings) + } + + fun onBuy() { + sendCommand(OpenBuyScreen) + } + + fun onRestore() { + pixelSender.reportAppSettingsRestorePurchaseClick() + sendCommand(OpenRestoreScreen) + } + + override fun onCreate(owner: LifecycleOwner) { + super.onCreate(owner) + subscriptionsManager.subscriptionStatus + .distinctUntilChanged() + .onEach { subscriptionStatus -> + val region = when (subscriptionsManager.getSubscriptionOffer()?.monthlyPlanId) { + MONTHLY_PLAN_ROW -> SubscriptionRegion.ROW + MONTHLY_PLAN_US -> SubscriptionRegion.US + else -> null + } + _viewState.emit(viewState.value.copy(status = subscriptionStatus, region = region)) + }.launchIn(viewModelScope) + } + + private fun sendCommand(newCommand: Command) { + viewModelScope.launch { + command.send(newCommand) + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt index 75c91092e91f..4ce3f911ae70 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingView.kt @@ -20,18 +20,17 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.widget.FrameLayout +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.common.ui.view.gone -import com.duckduckgo.common.ui.view.listitem.CheckListItem.CheckItemStatus.ALERT -import com.duckduckgo.common.ui.view.listitem.CheckListItem.CheckItemStatus.DISABLED -import com.duckduckgo.common.ui.view.show import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.common.utils.ConflatedJob import com.duckduckgo.common.utils.ViewViewModelFactory import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter import com.duckduckgo.subscriptions.api.SubscriptionStatus.AUTO_RENEWABLE import com.duckduckgo.subscriptions.api.SubscriptionStatus.EXPIRED @@ -135,42 +134,53 @@ class ProSettingView @JvmOverloads constructor( private fun renderView(viewState: ViewState) { when (viewState.status) { AUTO_RENEWABLE, NOT_AUTO_RENEWABLE, GRACE_PERIOD -> { - binding.subscriptionBuyContainer.gone() - binding.subscriptionRestoreContainer.gone() - binding.subscriptionWaitingContainer.gone() - binding.subscriptionSettingContainer.show() + with(binding) { + subscriptionBuyContainer.isGone = true + subscriptionRestoreContainer.isGone = true + subscriptionSetting.isGone = true + + subscribedSubscriptionSetting.isVisible = true + subscriptionSettingContainer.isVisible = true + } } WAITING -> { - binding.subscriptionBuyContainer.gone() - binding.subscriptionWaitingContainer.show() - binding.subscriptionSettingContainer.gone() - binding.subscriptionRestoreContainer.show() + with(binding) { + subscriptionBuyContainer.isGone = true + subscriptionRestoreContainer.isGone = true + subscribedSubscriptionSetting.isGone = true + + subscriptionSettingContainer.isVisible = true + subscriptionSetting.setSecondaryText(context.getString(R.string.subscriptionSettingActivating)) + } } EXPIRED, INACTIVE -> { - binding.subscriptionBuy.setPrimaryText(context.getString(R.string.subscriptionSettingExpired)) - binding.subscriptionBuy.setSecondaryText(context.getString(R.string.subscriptionSettingExpiredSubtitle)) - binding.subscriptionBuy.setItemStatus(ALERT) - binding.subscriptionGet.setText(R.string.subscriptionSettingExpiredViewPlans) - binding.subscriptionBuyContainer.show() - binding.subscriptionSettingContainer.show() - binding.subscriptionWaitingContainer.gone() - binding.subscriptionRestoreContainer.gone() + with(binding) { + subscriptionBuyContainer.isGone = true + subscriptionRestoreContainer.isGone = true + subscribedSubscriptionSetting.isGone = true + + subscriptionSettingContainer.isVisible = true + subscriptionSetting.setSecondaryText(context.getString(R.string.subscriptionSettingExpired)) + subscriptionSetting.setTrailingIconResource(CommonR.drawable.ic_exclamation_red_16) + } } else -> { - binding.subscriptionBuy.setPrimaryText(context.getString(R.string.subscriptionSettingSubscribe)) - binding.subscriptionBuy.setSecondaryText( - when (viewState.region) { - ROW -> context.getString(R.string.subscriptionSettingSubscribeSubtitleRow) - US -> context.getString(R.string.subscriptionSettingSubscribeSubtitle) - else -> "" - }, - ) - binding.subscriptionBuy.setItemStatus(DISABLED) - binding.subscriptionGet.setText(R.string.subscriptionSettingGet) - binding.subscriptionBuyContainer.show() - binding.subscriptionSettingContainer.gone() - binding.subscriptionWaitingContainer.gone() - binding.subscriptionRestoreContainer.show() + with(binding) { + subscriptionBuy.setPrimaryText(context.getString(R.string.subscriptionSettingSubscribe)) + subscriptionBuy.setSecondaryText( + when (viewState.region) { + ROW -> context.getString(R.string.subscriptionSettingSubscribeSubtitleRow) + US -> context.getString(R.string.subscriptionSettingSubscribeSubtitle) + else -> "" + }, + ) + subscriptionGet.setText(R.string.subscriptionSettingGet) + + subscriptionBuyContainer.isVisible = true + subscriptionRestoreContainer.isVisible = true + + subscriptionSettingContainer.isGone = true + } } } } diff --git a/common/common-ui/src/main/res/drawable/ic_identity_blocked_pir_color_24.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_blocked_pir_color_24.xml similarity index 100% rename from common/common-ui/src/main/res/drawable/ic_identity_blocked_pir_color_24.xml rename to subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_blocked_pir_color_24.xml diff --git a/common/common-ui/src/main/res/drawable/ic_identity_blocked_pir_grayscale_color_24.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_blocked_pir_grayscale_color_24.xml similarity index 100% rename from common/common-ui/src/main/res/drawable/ic_identity_blocked_pir_grayscale_color_24.xml rename to subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_blocked_pir_grayscale_color_24.xml diff --git a/common/common-ui/src/main/res/drawable/ic_identity_theft_restoration_color_24.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_theft_restoration_color_24.xml similarity index 100% rename from common/common-ui/src/main/res/drawable/ic_identity_theft_restoration_color_24.xml rename to subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_theft_restoration_color_24.xml diff --git a/common/common-ui/src/main/res/drawable/ic_identity_theft_restoration_grayscale_color_24.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_theft_restoration_grayscale_color_24.xml similarity index 100% rename from common/common-ui/src/main/res/drawable/ic_identity_theft_restoration_grayscale_color_24.xml rename to subscriptions/subscriptions-impl/src/main/res/drawable/ic_identity_theft_restoration_grayscale_color_24.xml diff --git a/common/common-ui/src/main/res/drawable/ic_privacy_pro_color_24.xml b/subscriptions/subscriptions-impl/src/main/res/drawable/ic_privacy_pro_color_24.xml similarity index 100% rename from common/common-ui/src/main/res/drawable/ic_privacy_pro_color_24.xml rename to subscriptions/subscriptions-impl/src/main/res/drawable/ic_privacy_pro_color_24.xml diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_settings.xml new file mode 100644 index 000000000000..24b69b96fa8b --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_settings.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml index 24b69b96fa8b..e77bd974cb82 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/view_settings.xml @@ -31,10 +31,11 @@ android:visibility="gone" tools:visibility="visible"> - @@ -42,7 +43,7 @@ android:id="@+id/subscriptionGet" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="48dp" + android:layout_marginStart="56dp" android:layout_marginTop="@dimen/keyline_3" android:layout_marginBottom="@dimen/keyline_3" app:textType="primary" @@ -60,33 +61,25 @@ tools:visibility="visible"> - - - - + tools:visibility="visible" + tools:ignore="RtlSymmetry" /> - + diff --git a/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml b/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml new file mode 100644 index 000000000000..f002ba80c3d9 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml @@ -0,0 +1,22 @@ + + + + + + Activating + + diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt new file mode 100644 index 000000000000..f1587dca900b --- /dev/null +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt @@ -0,0 +1,82 @@ +package com.duckduckgo.subscriptions.impl.settings.views + +import app.cash.turbine.test +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import com.duckduckgo.subscriptions.impl.SubscriptionsManager +import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender +import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.Command.OpenBuyScreen +import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.Command.OpenRestoreScreen +import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.Command.OpenSettings +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.* +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoMoreInteractions +import org.mockito.kotlin.whenever + +class LegacyLegacyProSettingViewModelTest { + @get:Rule + val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() + + private val subscriptionsManager: SubscriptionsManager = mock() + private val pixelSender: SubscriptionPixelSender = mock() + private lateinit var viewModel: LegacyProSettingViewModel + + @Before + fun before() { + viewModel = LegacyProSettingViewModel(subscriptionsManager, pixelSender) + } + + @Test + fun whenOnSettingsThenCommandSent() = runTest { + viewModel.commands().test { + viewModel.onSettings() + assertTrue(awaitItem() is OpenSettings) + cancelAndConsumeRemainingEvents() + } + } + + @Test + fun whenOnBuyThenCommandSent() = runTest { + viewModel.commands().test { + viewModel.onBuy() + assertTrue(awaitItem() is OpenBuyScreen) + cancelAndConsumeRemainingEvents() + } + } + + @Test + fun whenOnRestoreThenCommandSent() = runTest { + viewModel.commands().test { + viewModel.onRestore() + assertTrue(awaitItem() is OpenRestoreScreen) + cancelAndConsumeRemainingEvents() + } + } + + @Test + fun whenOnResumeEmitViewState() = runTest { + whenever(subscriptionsManager.subscriptionStatus).thenReturn(flowOf(SubscriptionStatus.EXPIRED)) + + viewModel.onCreate(mock()) + viewModel.viewState.test { + assertEquals(SubscriptionStatus.EXPIRED, awaitItem().status) + cancelAndConsumeRemainingEvents() + } + } + + @Test + fun whenOnRestoreThenPixelSent() = runTest { + viewModel.commands().test { + viewModel.onRestore() + verify(pixelSender).reportAppSettingsRestorePurchaseClick() + verifyNoMoreInteractions(pixelSender) + cancelAndConsumeRemainingEvents() + } + } +} From aa6cf2cbad280e2a4fab8ff77a75fff7bcb6bf2d Mon Sep 17 00:00:00 2001 From: Craig Russell Date: Mon, 16 Dec 2024 15:40:13 +0000 Subject: [PATCH 07/32] Allow scrolling all of the password management list mode screen (#5377) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task/Issue URL: https://app.asana.com/0/488551667048375/1208758825735780/f ### Description This PR tweaks the layout params for the password recycler view so that the whole view content, already encapsulated in a `NestedScrollView`, is scrollable. - Before, you had to scroll on the list view directly, and then only the passwords list would scroll while the rest of the views above were fixed. - Now, the entire view (including the toggle) is scrollable ### Steps to test this PR - [ ] Visit password management view when you have 0 passwords; verify it looks fine and unchanged from before - [ ] Add a single password; verify the password appears immediately below the horizontal divider - [ ] Add enough passwords that they appear down below the screen. - [ ] Verify that scrolling scrolls the whole content, and not just the password list itself - [ ] Verify you can scroll on the list, or scroll on the sync panel, or the text etc… and the whole page scrolls the same way ## Screenshots ### Current behavior ![current](https://github.com/user-attachments/assets/633dbba3-548f-47f7-b1e7-0065ecacb5a5) ### New behavior ![after](https://github.com/user-attachments/assets/c5456d1a-8256-49fc-9632-3313ec6de25a) Co-authored-by: Craig Russell <1336281+CDRussell@users.noreply.github.com> --- .../main/res/layout/fragment_autofill_management_list_mode.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/autofill/autofill-impl/src/main/res/layout/fragment_autofill_management_list_mode.xml b/autofill/autofill-impl/src/main/res/layout/fragment_autofill_management_list_mode.xml index 970e25b5f97f..5342ee25e29c 100644 --- a/autofill/autofill-impl/src/main/res/layout/fragment_autofill_management_list_mode.xml +++ b/autofill/autofill-impl/src/main/res/layout/fragment_autofill_management_list_mode.xml @@ -78,9 +78,8 @@ From d69001dc7d4e71f978684f04c04ea51c5f6394bb Mon Sep 17 00:00:00 2001 From: Dax Mobile <44842493+daxmobile@users.noreply.github.com> Date: Tue, 17 Dec 2024 04:53:12 +1100 Subject: [PATCH 08/32] Update autoconsent to v12.3.0 (#5393) Task/Issue URL: https://app.asana.com/0/1208976603817267/1208976603817267 Autoconsent Release: https://github.com/duckduckgo/autoconsent/releases/tag/v12.3.0 ## Description Updates Autoconsent to version [v12.3.0](https://github.com/duckduckgo/autoconsent/releases/tag/v12.3.0). ### Autoconsent v12.3.0 release notes See release notes [here](https://github.com/duckduckgo/autoconsent/blob/v12.3.0/CHANGELOG.md) ## Steps to test This release has been tested during Autoconsent development. You can check the release notes for more information. 1. Make sure that there's no unexpected failures in CI checks 2. (optional) smoke test some of the sites mentioned in the release notes 3. If there are problems, reach out to a CPM DRI Co-authored-by: muodov <2726132+muodov@users.noreply.github.com> --- autoconsent/autoconsent-impl/libs/autoconsent-bundle.js | 4 ++-- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js b/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js index a82b1bbffd29..696b1e255825 100644 --- a/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js +++ b/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js @@ -1,4 +1,4 @@ -!function(){"use strict";var e=class e{static setBase(t){e.base=t}static findElement(t,o=null,i=!1){let n=null;return n=null!=o?Array.from(o.querySelectorAll(t.selector)):null!=e.base?Array.from(e.base.querySelectorAll(t.selector)):Array.from(document.querySelectorAll(t.selector)),null!=t.textFilter&&(n=n.filter((e=>{const o=e.textContent.toLowerCase();if(Array.isArray(t.textFilter)){let e=!1;for(const i of t.textFilter)if(-1!==o.indexOf(i.toLowerCase())){e=!0;break}return e}return null!=t.textFilter&&-1!==o.indexOf(t.textFilter.toLowerCase())}))),null!=t.styleFilters&&(n=n.filter((e=>{const o=window.getComputedStyle(e);let i=!0;for(const e of t.styleFilters){const t=o[e.option];i=e.negated?i&&t!==e.value:i&&t===e.value}return i}))),null!=t.displayFilter&&(n=n.filter((e=>t.displayFilter?0!==e.offsetHeight:0===e.offsetHeight))),null!=t.iframeFilter&&(n=n.filter((()=>t.iframeFilter?window.location!==window.parent.location:window.location===window.parent.location))),null!=t.childFilter&&(n=n.filter((o=>{const i=e.base;e.setBase(o);const n=e.find(t.childFilter);return e.setBase(i),null!=n.target}))),i?n:(n.length>1&&console.warn("Multiple possible targets: ",n,t,o),n[0])}static find(t,o=!1){const i=[];if(null!=t.parent){const n=e.findElement(t.parent,null,o);if(null!=n){if(n instanceof Array)return n.forEach((n=>{const s=e.findElement(t.target,n,o);s instanceof Array?s.forEach((e=>{i.push({parent:n,target:e})})):i.push({parent:n,target:s})})),i;{const s=e.findElement(t.target,n,o);s instanceof Array?s.forEach((e=>{i.push({parent:n,target:e})})):i.push({parent:n,target:s})}}}else{const n=e.findElement(t.target,null,o);n instanceof Array?n.forEach((e=>{i.push({parent:null,target:e})})):i.push({parent:null,target:n})}return 0===i.length&&i.push({parent:null,target:null}),o?i:(1!==i.length&&console.warn("Multiple results found, even though multiple false",i),i[0])}};e.base=null;var t=e;function o(e){const o=t.find(e);return"css"===e.type?!!o.target:"checkbox"===e.type?!!o.target&&o.target.checked:void 0}async function i(e,c){switch(e.type){case"click":return async function(e){const o=t.find(e);null!=o.target&&o.target.click();return s(n)}(e);case"list":return async function(e,t){for(const o of e.actions)await i(o,t)}(e,c);case"consent":return async function(e,t){for(const n of e.consents){const e=-1!==t.indexOf(n.type);if(n.matcher&&n.toggleAction){o(n.matcher)!==e&&await i(n.toggleAction)}else e?await i(n.trueAction):await i(n.falseAction)}}(e,c);case"ifcss":return async function(e,o){const n=t.find(e);n.target?e.falseAction&&await i(e.falseAction,o):e.trueAction&&await i(e.trueAction,o)}(e,c);case"waitcss":return async function(e){await new Promise((o=>{let i=e.retries||10;const n=e.waitTime||250,s=()=>{const c=t.find(e);(e.negated&&c.target||!e.negated&&!c.target)&&i>0?(i-=1,setTimeout(s,n)):o()};s()}))}(e);case"foreach":return async function(e,o){const n=t.find(e,!0),s=t.base;for(const s of n)s.target&&(t.setBase(s.target),await i(e.action,o));t.setBase(s)}(e,c);case"hide":return async function(e){const o=t.find(e);o.target&&o.target.classList.add("Autoconsent-Hidden")}(e);case"slide":return async function(e){const o=t.find(e),i=t.find(e.dragTarget);if(o.target){const e=o.target.getBoundingClientRect(),t=i.target.getBoundingClientRect();let n=t.top-e.top,s=t.left-e.left;"y"===this.config.axis.toLowerCase()&&(s=0),"x"===this.config.axis.toLowerCase()&&(n=0);const c=window.screenX+e.left+e.width/2,r=window.screenY+e.top+e.height/2,a=e.left+e.width/2,l=e.top+e.height/2,p=document.createEvent("MouseEvents");p.initMouseEvent("mousedown",!0,!0,window,0,c,r,a,l,!1,!1,!1,!1,0,o.target);const d=document.createEvent("MouseEvents");d.initMouseEvent("mousemove",!0,!0,window,0,c+s,r+n,a+s,l+n,!1,!1,!1,!1,0,o.target);const u=document.createEvent("MouseEvents");u.initMouseEvent("mouseup",!0,!0,window,0,c+s,r+n,a+s,l+n,!1,!1,!1,!1,0,o.target),o.target.dispatchEvent(p),await this.waitTimeout(10),o.target.dispatchEvent(d),await this.waitTimeout(10),o.target.dispatchEvent(u)}}(e);case"close":return async function(){window.close()}();case"wait":return async function(e){await s(e.waitTime)}(e);case"eval":return async function(e){return console.log("eval!",e.code),new Promise((t=>{try{e.async?(window.eval(e.code),setTimeout((()=>{t(window.eval("window.__consentCheckResult"))}),e.timeout||250)):t(window.eval(e.code))}catch(o){console.warn("eval error",o,e.code),t(!1)}}))}(e);default:throw new Error("Unknown action type: "+e.type)}}var n=0;function s(e){return new Promise((t=>{setTimeout((()=>{t()}),e)}))}function c(){return crypto&&void 0!==crypto.randomUUID?crypto.randomUUID():Math.random().toString()}var r=class{constructor(e,t=1e3){this.id=e,this.promise=new Promise(((e,t)=>{this.resolve=e,this.reject=t})),this.timer=window.setTimeout((()=>{this.reject(new Error("timeout"))}),t)}},a={pending:new Map,sendContentMessage:null};var l={EVAL_0:()=>console.log(1),EVAL_CONSENTMANAGER_1:()=>window.__cmp&&"object"==typeof __cmp("getCMPData"),EVAL_CONSENTMANAGER_2:()=>!__cmp("consentStatus").userChoiceExists,EVAL_CONSENTMANAGER_3:()=>__cmp("setConsent",0),EVAL_CONSENTMANAGER_4:()=>__cmp("setConsent",1),EVAL_CONSENTMANAGER_5:()=>__cmp("consentStatus").userChoiceExists,EVAL_COOKIEBOT_1:()=>!!window.Cookiebot,EVAL_COOKIEBOT_2:()=>!window.Cookiebot.hasResponse&&!0===window.Cookiebot.dialog?.visible,EVAL_COOKIEBOT_3:()=>window.Cookiebot.withdraw()||!0,EVAL_COOKIEBOT_4:()=>window.Cookiebot.hide()||!0,EVAL_COOKIEBOT_5:()=>!0===window.Cookiebot.declined,EVAL_KLARO_1:()=>{const e=globalThis.klaroConfig||globalThis.klaro?.getManager&&globalThis.klaro.getManager().config;if(!e)return!0;const t=(e.services||e.apps).filter((e=>!e.required)).map((e=>e.name));if(klaro&&klaro.getManager){const e=klaro.getManager();return t.every((t=>!e.consents[t]))}if(klaroConfig&&"cookie"===klaroConfig.storageMethod){const e=klaroConfig.cookieName||klaroConfig.storageName,o=JSON.parse(decodeURIComponent(document.cookie.split(";").find((t=>t.trim().startsWith(e))).split("=")[1]));return Object.keys(o).filter((e=>t.includes(e))).every((e=>!1===o[e]))}},EVAL_KLARO_OPEN_POPUP:()=>{klaro.show(void 0,!0)},EVAL_KLARO_TRY_API_OPT_OUT:()=>{if(window.klaro&&"function"==typeof klaro.show&&"function"==typeof klaro.getManager)try{return klaro.getManager().changeAll(!1),klaro.getManager().saveAndApplyConsents(),!0}catch(e){return console.warn(e),!1}return!1},EVAL_ONETRUST_1:()=>window.OnetrustActiveGroups.split(",").filter((e=>e.length>0)).length<=1,EVAL_TRUSTARC_TOP:()=>window&&window.truste&&"0"===window.truste.eu.bindMap.prefCookie,EVAL_TRUSTARC_FRAME_TEST:()=>window&&window.QueryString&&"0"===window.QueryString.preferences,EVAL_TRUSTARC_FRAME_GTM:()=>window&&window.QueryString&&"1"===window.QueryString.gtm,EVAL_ABC_TEST:()=>document.cookie.includes("trackingconsent"),EVAL_ADROLL_0:()=>!document.cookie.includes("__adroll_fpc"),EVAL_ALMACMP_0:()=>document.cookie.includes('"name":"Google","consent":false'),EVAL_AFFINITY_SERIF_COM_0:()=>document.cookie.includes("serif_manage_cookies_viewed")&&!document.cookie.includes("serif_allow_analytics"),EVAL_ARBEITSAGENTUR_TEST:()=>document.cookie.includes("cookie_consent=denied"),EVAL_AXEPTIO_0:()=>document.cookie.includes("axeptio_authorized_vendors=%2C%2C"),EVAL_BAHN_TEST:()=>1===utag.gdpr.getSelectedCategories().length,EVAL_BING_0:()=>document.cookie.includes("AD=0"),EVAL_BLOCKSY_0:()=>document.cookie.includes("blocksy_cookies_consent_accepted=no"),EVAL_BORLABS_0:()=>!JSON.parse(decodeURIComponent(document.cookie.split(";").find((e=>-1!==e.indexOf("borlabs-cookie"))).split("=",2)[1])).consents.statistics,EVAL_BUNDESREGIERUNG_DE_0:()=>document.cookie.match("cookie-allow-tracking=0"),EVAL_CANVA_0:()=>!document.cookie.includes("gtm_fpc_engagement_event"),EVAL_CC_BANNER2_0:()=>!!document.cookie.match(/sncc=[^;]+D%3Dtrue/),EVAL_CLICKIO_0:()=>document.cookie.includes("__lxG__consent__v2_daisybit="),EVAL_CLINCH_0:()=>document.cookie.includes("ctc_rejected=1"),EVAL_COOKIECONSENT2_TEST:()=>document.cookie.includes("cc_cookie="),EVAL_COOKIECONSENT3_TEST:()=>document.cookie.includes("cc_cookie="),EVAL_COINBASE_0:()=>JSON.parse(decodeURIComponent(document.cookie.match(/cm_(eu|default)_preferences=([0-9a-zA-Z\\{\\}\\[\\]%:]*);?/)[2])).consent.length<=1,EVAL_COMPLIANZ_BANNER_0:()=>document.cookie.includes("cmplz_banner-status=dismissed"),EVAL_COOKIE_LAW_INFO_0:()=>CLI.disableAllCookies()||CLI.reject_close()||!0,EVAL_COOKIE_LAW_INFO_1:()=>-1===document.cookie.indexOf("cookielawinfo-checkbox-non-necessary=yes"),EVAL_COOKIE_LAW_INFO_DETECT:()=>!!window.CLI,EVAL_COOKIE_MANAGER_POPUP_0:()=>!1===JSON.parse(document.cookie.split(";").find((e=>e.trim().startsWith("CookieLevel"))).split("=")[1]).social,EVAL_COOKIEALERT_0:()=>document.querySelector("body").removeAttribute("style")||!0,EVAL_COOKIEALERT_1:()=>document.querySelector("body").removeAttribute("style")||!0,EVAL_COOKIEALERT_2:()=>!0===window.CookieConsent.declined,EVAL_COOKIEFIRST_0:()=>{return!1===(e=JSON.parse(decodeURIComponent(document.cookie.split(";").find((e=>-1!==e.indexOf("cookiefirst"))).trim()).split("=")[1])).performance&&!1===e.functional&&!1===e.advertising;var e},EVAL_COOKIEFIRST_1:()=>document.querySelectorAll("button[data-cookiefirst-accent-color=true][role=checkbox]:not([disabled])").forEach((e=>"true"===e.getAttribute("aria-checked")&&e.click()))||!0,EVAL_COOKIEINFORMATION_0:()=>CookieInformation.declineAllCategories()||!0,EVAL_COOKIEINFORMATION_1:()=>CookieInformation.submitAllCategories()||!0,EVAL_COOKIEINFORMATION_2:()=>document.cookie.includes("CookieInformationConsent="),EVAL_COOKIEYES_0:()=>document.cookie.includes("advertisement:no"),EVAL_DAILYMOTION_0:()=>!!document.cookie.match("dm-euconsent-v2"),EVAL_DNDBEYOND_TEST:()=>document.cookie.includes("cookie-consent=denied"),EVAL_DSGVO_0:()=>!document.cookie.includes("sp_dsgvo_cookie_settings"),EVAL_DUNELM_0:()=>document.cookie.includes("cc_functional=0")&&document.cookie.includes("cc_targeting=0"),EVAL_ETSY_0:()=>document.querySelectorAll(".gdpr-overlay-body input").forEach((e=>{e.checked=!1}))||!0,EVAL_ETSY_1:()=>document.querySelector(".gdpr-overlay-view button[data-wt-overlay-close]").click()||!0,EVAL_EU_COOKIE_COMPLIANCE_0:()=>-1===document.cookie.indexOf("cookie-agreed=2"),EVAL_EU_COOKIE_LAW_0:()=>!document.cookie.includes("euCookie"),EVAL_EZOIC_0:()=>ezCMP.handleAcceptAllClick(),EVAL_EZOIC_1:()=>!!document.cookie.match(/ez-consent-tcf/),EVAL_FIDES_DETECT_POPUP:()=>window.Fides?.initialized,EVAL_GOOGLE_0:()=>!!document.cookie.match(/SOCS=CAE/),EVAL_HEMA_TEST_0:()=>document.cookie.includes("cookies_rejected=1"),EVAL_IUBENDA_0:()=>document.querySelectorAll(".purposes-item input[type=checkbox]:not([disabled])").forEach((e=>{e.checked&&e.click()}))||!0,EVAL_IUBENDA_1:()=>!!document.cookie.match(/_iub_cs-\d+=/),EVAL_IWINK_TEST:()=>document.cookie.includes("cookie_permission_granted=no"),EVAL_JQUERY_COOKIEBAR_0:()=>!document.cookie.includes("cookies-state=accepted"),EVAL_KETCH_TEST:()=>document.cookie.includes("_ketch_consent_v1_"),EVAL_MEDIAVINE_0:()=>document.querySelectorAll('[data-name="mediavine-gdpr-cmp"] input[type=checkbox]').forEach((e=>e.checked&&e.click()))||!0,EVAL_MICROSOFT_0:()=>Array.from(document.querySelectorAll("div > button")).filter((e=>e.innerText.match("Reject|Ablehnen")))[0].click()||!0,EVAL_MICROSOFT_1:()=>Array.from(document.querySelectorAll("div > button")).filter((e=>e.innerText.match("Accept|Annehmen")))[0].click()||!0,EVAL_MICROSOFT_2:()=>!!document.cookie.match("MSCC|GHCC"),EVAL_MOOVE_0:()=>document.querySelectorAll("#moove_gdpr_cookie_modal input").forEach((e=>{e.disabled||(e.checked="moove_gdpr_strict_cookies"===e.name||"moove_gdpr_strict_cookies"===e.id)}))||!0,EVAL_ONENINETWO_0:()=>document.cookie.includes("CC_ADVERTISING=NO")&&document.cookie.includes("CC_ANALYTICS=NO"),EVAL_OPENAI_TEST:()=>document.cookie.includes("oai-allow-ne=false"),EVAL_OPERA_0:()=>document.cookie.includes("cookie_consent_essential=true")&&!document.cookie.includes("cookie_consent_marketing=true"),EVAL_PAYPAL_0:()=>!0===document.cookie.includes("cookie_prefs"),EVAL_PRIMEBOX_0:()=>!document.cookie.includes("cb-enabled=accepted"),EVAL_PUBTECH_0:()=>document.cookie.includes("euconsent-v2")&&(document.cookie.match(/.YAAAAAAAAAAA/)||document.cookie.match(/.aAAAAAAAAAAA/)||document.cookie.match(/.YAAACFgAAAAA/)),EVAL_REDDIT_0:()=>document.cookie.includes("eu_cookie={%22opted%22:true%2C%22nonessential%22:false}"),EVAL_ROBLOX_TEST:()=>document.cookie.includes("RBXcb"),EVAL_SKYSCANNER_TEST:()=>document.cookie.match(/gdpr=[^;]*adverts:::false/)&&!document.cookie.match(/gdpr=[^;]*init:::true/),EVAL_SIRDATA_UNBLOCK_SCROLL:()=>(document.documentElement.classList.forEach((e=>{e.startsWith("sd-cmp-")&&document.documentElement.classList.remove(e)})),!0),EVAL_SNIGEL_0:()=>!!document.cookie.match("snconsent"),EVAL_STEAMPOWERED_0:()=>2===JSON.parse(decodeURIComponent(document.cookie.split(";").find((e=>e.trim().startsWith("cookieSettings"))).split("=")[1])).preference_state,EVAL_SVT_TEST:()=>document.cookie.includes('cookie-consent-1={"optedIn":true,"functionality":false,"statistics":false}'),EVAL_TAKEALOT_0:()=>document.body.classList.remove("freeze")||(document.body.style="")||!0,EVAL_TARTEAUCITRON_0:()=>tarteaucitron.userInterface.respondAll(!1)||!0,EVAL_TARTEAUCITRON_1:()=>tarteaucitron.userInterface.respondAll(!0)||!0,EVAL_TARTEAUCITRON_2:()=>document.cookie.match(/tarteaucitron=[^;]*/)?.[0].includes("false"),EVAL_TAUNTON_TEST:()=>document.cookie.includes("taunton_user_consent_submitted=true"),EVAL_TEALIUM_0:()=>void 0!==window.utag&&"object"==typeof utag.gdpr,EVAL_TEALIUM_1:()=>utag.gdpr.setConsentValue(!1)||!0,EVAL_TEALIUM_DONOTSELL:()=>utag.gdpr.dns?.setDnsState(!1)||!0,EVAL_TEALIUM_2:()=>utag.gdpr.setConsentValue(!0)||!0,EVAL_TEALIUM_3:()=>1!==utag.gdpr.getConsentState(),EVAL_TEALIUM_DONOTSELL_CHECK:()=>1!==utag.gdpr.dns?.getDnsState(),EVAL_TESLA_TEST:()=>document.cookie.includes("tsla-cookie-consent=rejected"),EVAL_TESTCMP_STEP:()=>!!document.querySelector("#reject-all"),EVAL_TESTCMP_0:()=>"button_clicked"===window.results.results[0],EVAL_TESTCMP_COSMETIC_0:()=>"banner_hidden"===window.results.results[0],EVAL_THEFREEDICTIONARY_0:()=>cmpUi.showPurposes()||cmpUi.rejectAll()||!0,EVAL_THEFREEDICTIONARY_1:()=>cmpUi.allowAll()||!0,EVAL_THEVERGE_0:()=>document.cookie.includes("_duet_gdpr_acknowledged=1"),EVAL_TWCC_TEST:()=>document.cookie.includes("twCookieConsent="),EVAL_UBUNTU_COM_0:()=>document.cookie.includes("_cookies_accepted=essential"),EVAL_UK_COOKIE_CONSENT_0:()=>!document.cookie.includes("catAccCookies"),EVAL_USERCENTRICS_API_0:()=>"object"==typeof UC_UI,EVAL_USERCENTRICS_API_1:()=>!!UC_UI.closeCMP(),EVAL_USERCENTRICS_API_2:()=>!!UC_UI.denyAllConsents(),EVAL_USERCENTRICS_API_3:()=>!!UC_UI.acceptAllConsents(),EVAL_USERCENTRICS_API_4:()=>!!UC_UI.closeCMP(),EVAL_USERCENTRICS_API_5:()=>!0===UC_UI.areAllConsentsAccepted(),EVAL_USERCENTRICS_API_6:()=>!1===UC_UI.areAllConsentsAccepted(),EVAL_USERCENTRICS_BUTTON_0:()=>JSON.parse(localStorage.getItem("usercentrics")).consents.every((e=>e.isEssential||!e.consentStatus)),EVAL_WAITROSE_0:()=>Array.from(document.querySelectorAll("label[id$=cookies-deny-label]")).forEach((e=>e.click()))||!0,EVAL_WAITROSE_1:()=>document.cookie.includes("wtr_cookies_advertising=0")&&document.cookie.includes("wtr_cookies_analytics=0"),EVAL_WP_COOKIE_NOTICE_0:()=>document.cookie.includes("wpl_viewed_cookie=no"),EVAL_XE_TEST:()=>document.cookie.includes("xeConsentState={%22performance%22:false%2C%22marketing%22:false%2C%22compliance%22:false}"),EVAL_XING_0:()=>document.cookie.includes("userConsent=%7B%22marketing%22%3Afalse"),EVAL_YOUTUBE_DESKTOP_0:()=>!!document.cookie.match(/SOCS=CAE/),EVAL_YOUTUBE_MOBILE_0:()=>!!document.cookie.match(/SOCS=CAE/)};var p={main:!0,frame:!1,urlPattern:""},d=class{constructor(e){this.runContext=p,this.autoconsent=e}get hasSelfTest(){throw new Error("Not Implemented")}get isIntermediate(){throw new Error("Not Implemented")}get isCosmetic(){throw new Error("Not Implemented")}mainWorldEval(e){const t=l[e];if(!t)return console.warn("Snippet not found",e),Promise.resolve(!1);const o=this.autoconsent.config.logs;if(this.autoconsent.config.isMainWorld){o.evals&&console.log("inline eval:",e,t);let i=!1;try{i=!!t.call(globalThis)}catch(t){o.evals&&console.error("error evaluating rule",e,t)}return Promise.resolve(i)}const i=`(${t.toString()})()`;return o.evals&&console.log("async eval:",e,i),function(e,t){const o=c();a.sendContentMessage({type:"eval",id:o,code:e,snippetId:t});const i=new r(o);return a.pending.set(i.id,i),i.promise}(i,e).catch((t=>(o.evals&&console.error("error evaluating rule",e,t),!1)))}checkRunContext(){const e={...p,...this.runContext},t=window.top===window;return!(t&&!e.main)&&(!(!t&&!e.frame)&&!(e.urlPattern&&!window.location.href.match(e.urlPattern)))}detectCmp(){throw new Error("Not Implemented")}async detectPopup(){return!1}optOut(){throw new Error("Not Implemented")}optIn(){throw new Error("Not Implemented")}openCmp(){throw new Error("Not Implemented")}async test(){return Promise.resolve(!0)}click(e,t=!1){return this.autoconsent.domActions.click(e,t)}elementExists(e){return this.autoconsent.domActions.elementExists(e)}elementVisible(e,t){return this.autoconsent.domActions.elementVisible(e,t)}waitForElement(e,t){return this.autoconsent.domActions.waitForElement(e,t)}waitForVisible(e,t,o){return this.autoconsent.domActions.waitForVisible(e,t,o)}waitForThenClick(e,t,o){return this.autoconsent.domActions.waitForThenClick(e,t,o)}wait(e){return this.autoconsent.domActions.wait(e)}hide(e,t){return this.autoconsent.domActions.hide(e,t)}prehide(e){return this.autoconsent.domActions.prehide(e)}undoPrehide(){return this.autoconsent.domActions.undoPrehide()}querySingleReplySelector(e,t){return this.autoconsent.domActions.querySingleReplySelector(e,t)}querySelectorChain(e){return this.autoconsent.domActions.querySelectorChain(e)}elementSelector(e){return this.autoconsent.domActions.elementSelector(e)}},u=class extends d{constructor(e,t){super(t),this.rule=e,this.name=e.name,this.runContext=e.runContext||p}get hasSelfTest(){return!!this.rule.test}get isIntermediate(){return!!this.rule.intermediate}get isCosmetic(){return!!this.rule.cosmetic}get prehideSelectors(){return this.rule.prehideSelectors}async detectCmp(){return!!this.rule.detectCmp&&this._runRulesParallel(this.rule.detectCmp)}async detectPopup(){return!!this.rule.detectPopup&&this._runRulesSequentially(this.rule.detectPopup)}async optOut(){const e=this.autoconsent.config.logs;return!!this.rule.optOut&&(e.lifecycle&&console.log("Initiated optOut()",this.rule.optOut),this._runRulesSequentially(this.rule.optOut))}async optIn(){const e=this.autoconsent.config.logs;return!!this.rule.optIn&&(e.lifecycle&&console.log("Initiated optIn()",this.rule.optIn),this._runRulesSequentially(this.rule.optIn))}async openCmp(){return!!this.rule.openCmp&&this._runRulesSequentially(this.rule.openCmp)}async test(){return this.hasSelfTest?this._runRulesSequentially(this.rule.test):super.test()}async evaluateRuleStep(e){const t=[],o=this.autoconsent.config.logs;if(e.exists&&t.push(this.elementExists(e.exists)),e.visible&&t.push(this.elementVisible(e.visible,e.check)),e.eval){const o=this.mainWorldEval(e.eval);t.push(o)}if(e.waitFor&&t.push(this.waitForElement(e.waitFor,e.timeout)),e.waitForVisible&&t.push(this.waitForVisible(e.waitForVisible,e.timeout,e.check)),e.click&&t.push(this.click(e.click,e.all)),e.waitForThenClick&&t.push(this.waitForThenClick(e.waitForThenClick,e.timeout,e.all)),e.wait&&t.push(this.wait(e.wait)),e.hide&&t.push(this.hide(e.hide,e.method)),e.if){if(!e.if.exists&&!e.if.visible)return console.error("invalid conditional rule",e.if),!1;const i=await this.evaluateRuleStep(e.if);o.rulesteps&&console.log("Condition is",i),i?t.push(this._runRulesSequentially(e.then)):e.else?t.push(this._runRulesSequentially(e.else)):t.push(!0)}if(e.any){for(const t of e.any)if(await this.evaluateRuleStep(t))return!0;return!1}if(0===t.length)return o.errors&&console.warn("Unrecognized rule",e),!1;return(await Promise.all(t)).reduce(((e,t)=>e&&t),!0)}async _runRulesParallel(e){const t=e.map((e=>this.evaluateRuleStep(e)));return(await Promise.all(t)).every((e=>!!e))}async _runRulesSequentially(e){const t=this.autoconsent.config.logs;for(const o of e){t.rulesteps&&console.log("Running rule...",o);const e=await this.evaluateRuleStep(o);if(t.rulesteps&&console.log("...rule result",e),!e&&!o.optional)return!1}return!0}},h=class{constructor(e,t){this.name=e,this.config=t,this.methods=new Map,this.runContext=p,this.isCosmetic=!1,t.methods.forEach((e=>{e.action&&this.methods.set(e.name,e.action)})),this.hasSelfTest=!1}get isIntermediate(){return!1}checkRunContext(){return!0}async detectCmp(){return this.config.detectors.map((e=>o(e.presentMatcher))).some((e=>!!e))}async detectPopup(){return this.config.detectors.map((e=>o(e.showingMatcher))).some((e=>!!e))}async executeAction(e,t){return!this.methods.has(e)||i(this.methods.get(e),t)}async optOut(){return await this.executeAction("HIDE_CMP"),await this.executeAction("OPEN_OPTIONS"),await this.executeAction("HIDE_CMP"),await this.executeAction("DO_CONSENT",[]),await this.executeAction("SAVE_CONSENT"),!0}async optIn(){return await this.executeAction("HIDE_CMP"),await this.executeAction("OPEN_OPTIONS"),await this.executeAction("HIDE_CMP"),await this.executeAction("DO_CONSENT",["D","A","B","E","F","X"]),await this.executeAction("SAVE_CONSENT"),!0}async openCmp(){return await this.executeAction("HIDE_CMP"),await this.executeAction("OPEN_OPTIONS"),!0}async test(){return!0}};function m(e="autoconsent-css-rules"){const t=`style#${e}`,o=document.querySelector(t);if(o&&o instanceof HTMLStyleElement)return o;{const t=document.head||document.getElementsByTagName("head")[0]||document.documentElement,o=document.createElement("style");return o.id=e,t.appendChild(o),o}}function A(e){return`${"opacity"===e?"opacity: 0":"display: none"} !important; z-index: -1 !important; pointer-events: none !important;`}function g(e,t,o="display"){const i=`${t} { ${A(o)} } `;return e instanceof HTMLStyleElement&&(e.innerText+=i,t.length>0)}async function f(e,t,o){const i=await e();return!i&&t>0?new Promise((i=>{setTimeout((async()=>{i(f(e,t-1,o))}),o)})):Promise.resolve(i)}function k(e){if(!e)return!1;if(null!==e.offsetParent)return!0;{const t=window.getComputedStyle(e);if("fixed"===t.position&&"none"!==t.display)return!0}return!1}function b(e){const t={enabled:!0,autoAction:"optOut",disabledCmps:[],enablePrehide:!0,enableCosmeticRules:!0,detectRetries:20,isMainWorld:!1,prehideTimeout:2e3,enableFilterList:!1,logs:{lifecycle:!1,rulesteps:!1,evals:!1,errors:!0,messages:!1}},o=(i=t,globalThis.structuredClone?structuredClone(i):JSON.parse(JSON.stringify(i)));var i;for(const i of Object.keys(t))void 0!==e[i]&&(o[i]=e[i]);return o}var y="#truste-show-consent",w="#truste-consent-track",v=[class extends d{constructor(e){super(e),this.name="TrustArc-top",this.prehideSelectors=[".trustarc-banner-container",`.truste_popframe,.truste_overlay,.truste_box_overlay,${w}`],this.runContext={main:!0,frame:!1},this._shortcutButton=null,this._optInDone=!1}get hasSelfTest(){return!0}get isIntermediate(){return!this._optInDone&&!this._shortcutButton}get isCosmetic(){return!1}async detectCmp(){const e=this.elementExists(`${y},${w}`);return e&&(this._shortcutButton=document.querySelector("#truste-consent-required")),e}async detectPopup(){return this.elementVisible(`#truste-consent-content,#trustarc-banner-overlay,${w}`,"any")}openFrame(){this.click(y)}async optOut(){return this._shortcutButton?(this._shortcutButton.click(),!0):(g(m(),`.truste_popframe, .truste_overlay, .truste_box_overlay, ${w}`),this.click(y),setTimeout((()=>{m().remove()}),1e4),!0)}async optIn(){return this._optInDone=!0,this.click("#truste-consent-button")}async openCmp(){return!0}async test(){return await this.wait(500),await this.mainWorldEval("EVAL_TRUSTARC_TOP")}},class extends d{constructor(){super(...arguments),this.name="TrustArc-frame",this.runContext={main:!1,frame:!0,urlPattern:"^https://consent-pref\\.trustarc\\.com/\\?"}}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return!0}async detectPopup(){return this.elementVisible("#defaultpreferencemanager","any")&&this.elementVisible(".mainContent","any")}async navigateToSettings(){return await f((async()=>this.elementExists(".shp")||this.elementVisible(".advance","any")||this.elementExists(".switch span:first-child")),10,500),this.elementExists(".shp")&&this.click(".shp"),await this.waitForElement(".prefPanel",5e3),this.elementVisible(".advance","any")&&this.click(".advance"),await f((()=>this.elementVisible(".switch span:first-child","any")),5,1e3)}async optOut(){if(await this.mainWorldEval("EVAL_TRUSTARC_FRAME_TEST"))return!0;let e=3e3;return await this.mainWorldEval("EVAL_TRUSTARC_FRAME_GTM")&&(e=1500),await f((()=>"complete"===document.readyState),20,100),await this.waitForElement(".mainContent[aria-hidden=false]",e),!!this.click(".rejectAll")||(this.elementExists(".prefPanel")&&await this.waitForElement('.prefPanel[style="visibility: visible;"]',e),this.click("#catDetails0")?(this.click(".submit"),this.waitForThenClick("#gwt-debug-close_id",e),!0):this.click(".required")?(this.waitForThenClick("#gwt-debug-close_id",e),!0):(await this.navigateToSettings(),this.click(".switch span:nth-child(1):not(.active)",!0),this.click(".submit"),this.waitForThenClick("#gwt-debug-close_id",10*e),!0))}async optIn(){return this.click(".call")||(await this.navigateToSettings(),this.click(".switch span:nth-child(2)",!0),this.click(".submit"),this.waitForElement("#gwt-debug-close_id",3e5).then((()=>{this.click("#gwt-debug-close_id")}))),!0}async test(){return await this.wait(500),await this.mainWorldEval("EVAL_TRUSTARC_FRAME_TEST")}},class extends d{constructor(){super(...arguments),this.name="Cybotcookiebot",this.prehideSelectors=["#CybotCookiebotDialog,#CybotCookiebotDialogBodyUnderlay,#dtcookie-container,#cookiebanner,#cb-cookieoverlay,.modal--cookie-banner,#cookiebanner_outer,#CookieBanner"]}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return await this.mainWorldEval("EVAL_COOKIEBOT_1")}async detectPopup(){return this.mainWorldEval("EVAL_COOKIEBOT_2")}async optOut(){await this.wait(500);let e=await this.mainWorldEval("EVAL_COOKIEBOT_3");return await this.wait(500),e=e&&await this.mainWorldEval("EVAL_COOKIEBOT_4"),e}async optIn(){return this.elementExists("#dtcookie-container")?this.click(".h-dtcookie-accept"):(this.click(".CybotCookiebotDialogBodyLevelButton:not(:checked):enabled",!0),this.click("#CybotCookiebotDialogBodyLevelButtonAccept"),this.click("#CybotCookiebotDialogBodyButtonAccept"),!0)}async test(){return await this.wait(500),await this.mainWorldEval("EVAL_COOKIEBOT_5")}},class extends d{constructor(){super(...arguments),this.name="Sourcepoint-frame",this.prehideSelectors=["div[id^='sp_message_container_'],.message-overlay","#sp_privacy_manager_container"],this.ccpaNotice=!1,this.ccpaPopup=!1,this.runContext={main:!0,frame:!0}}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){const e=new URL(location.href);return e.searchParams.has("message_id")&&"ccpa-notice.sp-prod.net"===e.hostname?(this.ccpaNotice=!0,!0):"ccpa-pm.sp-prod.net"===e.hostname?(this.ccpaPopup=!0,!0):("/index.html"===e.pathname||"/privacy-manager/index.html"===e.pathname||"/ccpa_pm/index.html"===e.pathname)&&(e.searchParams.has("message_id")||e.searchParams.has("requestUUID")||e.searchParams.has("consentUUID"))}async detectPopup(){return!!this.ccpaNotice||(this.ccpaPopup?await this.waitForElement(".priv-save-btn",2e3):(await this.waitForElement(".sp_choice_type_11,.sp_choice_type_12,.sp_choice_type_13,.sp_choice_type_ACCEPT_ALL,.sp_choice_type_SAVE_AND_EXIT",2e3),!this.elementExists(".sp_choice_type_9")))}async optIn(){return await this.waitForElement(".sp_choice_type_11,.sp_choice_type_ACCEPT_ALL",2e3),!!this.click(".sp_choice_type_11")||!!this.click(".sp_choice_type_ACCEPT_ALL")}isManagerOpen(){return"/privacy-manager/index.html"===location.pathname||"/ccpa_pm/index.html"===location.pathname}async optOut(){const e=this.autoconsent.config.logs;if(this.ccpaPopup){const e=document.querySelectorAll(".priv-purpose-container .sp-switch-arrow-block a.neutral.on .right");for(const t of e)t.click();const t=document.querySelectorAll(".priv-purpose-container .sp-switch-arrow-block a.switch-bg.on");for(const e of t)e.click();return this.click(".priv-save-btn")}if(!this.isManagerOpen()){if(!await this.waitForElement(".sp_choice_type_12,.sp_choice_type_13"))return!1;if(!this.elementExists(".sp_choice_type_12"))return this.click(".sp_choice_type_13");this.click(".sp_choice_type_12"),await f((()=>this.isManagerOpen()),200,100)}await this.waitForElement(".type-modal",2e4),this.waitForThenClick(".ccpa-stack .pm-switch[aria-checked=true] .slider",500,!0);try{const e=".sp_choice_type_REJECT_ALL",t=".reject-toggle",o=await Promise.race([this.waitForElement(e,2e3).then((e=>e?0:-1)),this.waitForElement(t,2e3).then((e=>e?1:-1)),this.waitForElement(".pm-features",2e3).then((e=>e?2:-1))]);if(0===o)return await this.waitForVisible(e),this.click(e);1===o?this.click(t):2===o&&(await this.waitForElement(".pm-features",1e4),this.click(".checked > span",!0),this.click(".chevron"))}catch(t){e.errors&&console.warn(t)}return this.click(".sp_choice_type_SAVE_AND_EXIT")}},class extends d{constructor(){super(...arguments),this.name="consentmanager.net",this.prehideSelectors=["#cmpbox,#cmpbox2"],this.apiAvailable=!1}get hasSelfTest(){return this.apiAvailable}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.apiAvailable=await this.mainWorldEval("EVAL_CONSENTMANAGER_1"),!!this.apiAvailable||this.elementExists("#cmpbox")}async detectPopup(){return this.apiAvailable?(await this.wait(500),await this.mainWorldEval("EVAL_CONSENTMANAGER_2")):this.elementVisible("#cmpbox .cmpmore","any")}async optOut(){return await this.wait(500),this.apiAvailable?await this.mainWorldEval("EVAL_CONSENTMANAGER_3"):!!this.click(".cmpboxbtnno")||(this.elementExists(".cmpwelcomeprpsbtn")?(this.click(".cmpwelcomeprpsbtn > a[aria-checked=true]",!0),this.click(".cmpboxbtnsave"),!0):(this.click(".cmpboxbtncustom"),await this.waitForElement(".cmptblbox",2e3),this.click(".cmptdchoice > a[aria-checked=true]",!0),this.click(".cmpboxbtnyescustomchoices"),this.hide("#cmpwrapper,#cmpbox","display"),!0))}async optIn(){return this.apiAvailable?await this.mainWorldEval("EVAL_CONSENTMANAGER_4"):this.click(".cmpboxbtnyes")}async test(){if(this.apiAvailable)return await this.mainWorldEval("EVAL_CONSENTMANAGER_5")}},class extends d{constructor(){super(...arguments),this.name="Evidon"}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("#_evidon_banner")}async detectPopup(){return this.elementVisible("#_evidon_banner","any")}async optOut(){return this.click("#_evidon-decline-button")||(g(m(),"#evidon-prefdiag-overlay,#evidon-prefdiag-background,#_evidon-background"),await this.waitForThenClick("#_evidon-option-button"),await this.waitForElement("#evidon-prefdiag-overlay",5e3),await this.wait(500),await this.waitForThenClick("#evidon-prefdiag-decline")),!0}async optIn(){return this.click("#_evidon-accept-button")}},class extends d{constructor(){super(...arguments),this.name="Onetrust",this.prehideSelectors=["#onetrust-banner-sdk,#onetrust-consent-sdk,.onetrust-pc-dark-filter,.js-consent-banner"],this.runContext={urlPattern:"^(?!.*https://www\\.nba\\.com/)"}}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("#onetrust-banner-sdk,#onetrust-pc-sdk")}async detectPopup(){return this.elementVisible("#onetrust-banner-sdk,#onetrust-pc-sdk","any")}async optOut(){return this.elementVisible("#onetrust-reject-all-handler,.ot-pc-refuse-all-handler,.js-reject-cookies","any")?this.click("#onetrust-reject-all-handler,.ot-pc-refuse-all-handler,.js-reject-cookies"):(this.elementExists("#onetrust-pc-btn-handler")?this.click("#onetrust-pc-btn-handler"):this.click(".ot-sdk-show-settings,button.js-cookie-settings"),await this.waitForElement("#onetrust-consent-sdk",2e3),await this.wait(1e3),this.click("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked",!0),await this.wait(1e3),await this.waitForElement(".save-preference-btn-handler,.js-consent-save",2e3),this.click(".save-preference-btn-handler,.js-consent-save"),await this.waitForVisible("#onetrust-banner-sdk",5e3,"none"),!0)}async optIn(){return this.click("#onetrust-accept-btn-handler,#accept-recommended-btn-handler,.js-accept-cookies")}async test(){return await f((()=>this.mainWorldEval("EVAL_ONETRUST_1")),10,500)}},class extends d{constructor(){super(...arguments),this.name="Klaro",this.prehideSelectors=[".klaro"],this.settingsOpen=!1}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists(".klaro > .cookie-modal")?(this.settingsOpen=!0,!0):this.elementExists(".klaro > .cookie-notice")}async detectPopup(){return this.elementVisible(".klaro > .cookie-notice,.klaro > .cookie-modal","any")}async optOut(){return!!await this.mainWorldEval("EVAL_KLARO_TRY_API_OPT_OUT")||(!!this.click(".klaro .cn-decline")||(await this.mainWorldEval("EVAL_KLARO_OPEN_POPUP"),!!this.click(".klaro .cn-decline")||(this.click(".cm-purpose:not(.cm-toggle-all) > input:not(.half-checked,.required,.only-required),.cm-purpose:not(.cm-toggle-all) > div > input:not(.half-checked,.required,.only-required)",!0),this.click(".cm-btn-accept,.cm-button"))))}async optIn(){return!!this.click(".klaro .cm-btn-accept-all")||(this.settingsOpen?(this.click(".cm-purpose:not(.cm-toggle-all) > input.half-checked",!0),this.click(".cm-btn-accept")):this.click(".klaro .cookie-notice .cm-btn-success"))}async test(){return await this.mainWorldEval("EVAL_KLARO_1")}},class extends d{constructor(){super(...arguments),this.name="Uniconsent"}get prehideSelectors(){return[".unic",".modal:has(.unic)"]}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists(".unic .unic-box,.unic .unic-bar,.unic .unic-modal")}async detectPopup(){return this.elementVisible(".unic .unic-box,.unic .unic-bar,.unic .unic-modal","any")}async optOut(){if(await this.waitForElement(".unic button",1e3),document.querySelectorAll(".unic button").forEach((e=>{const t=e.textContent;(t.includes("Manage Options")||t.includes("Optionen verwalten"))&&e.click()})),await this.waitForElement(".unic input[type=checkbox]",1e3)){await this.waitForElement(".unic button",1e3),document.querySelectorAll(".unic input[type=checkbox]").forEach((e=>{e.checked&&e.click()}));for(const e of document.querySelectorAll(".unic button")){const t=e.textContent;for(const o of["Confirm Choices","Save Choices","Auswahl speichern"])if(t.includes(o))return e.click(),await this.wait(500),!0}}return!1}async optIn(){return this.waitForThenClick(".unic #unic-agree")}async test(){await this.wait(1e3);return!this.elementExists(".unic .unic-box,.unic .unic-bar")}},class extends d{constructor(){super(...arguments),this.prehideSelectors=[".cmp-root"],this.name="Conversant"}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists(".cmp-root .cmp-receptacle")}async detectPopup(){return this.elementVisible(".cmp-root .cmp-receptacle","any")}async optOut(){if(!await this.waitForThenClick(".cmp-main-button:not(.cmp-main-button--primary)"))return!1;if(!await this.waitForElement(".cmp-view-tab-tabs"))return!1;await this.waitForThenClick(".cmp-view-tab-tabs > :first-child"),await this.waitForThenClick(".cmp-view-tab-tabs > .cmp-view-tab--active:first-child");for(const e of Array.from(document.querySelectorAll(".cmp-accordion-item"))){e.querySelector(".cmp-accordion-item-title").click(),await f((()=>!!e.querySelector(".cmp-accordion-item-content.cmp-active")),10,50);const t=e.querySelector(".cmp-accordion-item-content.cmp-active");t.querySelectorAll(".cmp-toggle-actions .cmp-toggle-deny:not(.cmp-toggle-deny--active)").forEach((e=>e.click())),t.querySelectorAll(".cmp-toggle-actions .cmp-toggle-checkbox:not(.cmp-toggle-checkbox--active)").forEach((e=>e.click()))}return await this.click(".cmp-main-button:not(.cmp-main-button--primary)"),!0}async optIn(){return this.waitForThenClick(".cmp-main-button.cmp-main-button--primary")}async test(){return document.cookie.includes("cmp-data=0")}},class extends d{constructor(){super(...arguments),this.name="tiktok.com",this.runContext={urlPattern:"tiktok"}}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}getShadowRoot(){const e=document.querySelector("tiktok-cookie-banner");return e?e.shadowRoot:null}async detectCmp(){return this.elementExists("tiktok-cookie-banner")}async detectPopup(){return k(this.getShadowRoot().querySelector(".tiktok-cookie-banner"))}async optOut(){const e=this.autoconsent.config.logs,t=this.getShadowRoot().querySelector(".button-wrapper button:first-child");return t?(e.rulesteps&&console.log("[clicking]",t),t.click(),!0):(e.errors&&console.log("no decline button found"),!1)}async optIn(){const e=this.autoconsent.config.logs,t=this.getShadowRoot().querySelector(".button-wrapper button:last-child");return t?(e.rulesteps&&console.log("[clicking]",t),t.click(),!0):(e.errors&&console.log("no accept button found"),!1)}async test(){const e=document.cookie.match(/cookie-consent=([^;]+)/);if(!e)return!1;const t=JSON.parse(decodeURIComponent(e[1]));return Object.values(t).every((e=>"boolean"!=typeof e||!1===e))}},class extends d{constructor(){super(...arguments),this.name="airbnb",this.runContext={urlPattern:"^https://(www\\.)?airbnb\\.[^/]+/"},this.prehideSelectors=["div[data-testid=main-cookies-banner-container]",'div:has(> div:first-child):has(> div:last-child):has(> section [data-testid="strictly-necessary-cookies"])']}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("div[data-testid=main-cookies-banner-container]")}async detectPopup(){return this.elementVisible("div[data-testid=main-cookies-banner-container","any")}async optOut(){let e;for(await this.waitForThenClick("div[data-testid=main-cookies-banner-container] button._snbhip0");e=document.querySelector("[data-testid=modal-container] button[aria-checked=true]:not([disabled])");)e.click();return this.waitForThenClick("button[data-testid=save-btn]")}async optIn(){return this.waitForThenClick("div[data-testid=main-cookies-banner-container] button._148dgdpk")}async test(){return await f((()=>!!document.cookie.match("OptanonAlertBoxClosed")),20,200)}},class extends d{constructor(){super(...arguments),this.name="tumblr-com",this.runContext={urlPattern:"^https://(www\\.)?tumblr\\.com/"}}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}get prehideSelectors(){return["#cmp-app-container"]}async detectCmp(){return this.elementExists("#cmp-app-container")}async detectPopup(){return this.elementVisible("#cmp-app-container","any")}async optOut(){let e=document.querySelector("#cmp-app-container iframe"),t=e.contentDocument?.querySelector(".cmp-components-button.is-secondary");return!!t&&(t.click(),await f((()=>{const e=document.querySelector("#cmp-app-container iframe");return!!e.contentDocument?.querySelector(".cmp__dialog input")}),5,500),e=document.querySelector("#cmp-app-container iframe"),t=e.contentDocument?.querySelector(".cmp-components-button.is-secondary"),!!t&&(t.click(),!0))}async optIn(){const e=document.querySelector("#cmp-app-container iframe").contentDocument.querySelector(".cmp-components-button.is-primary");return!!e&&(e.click(),!0)}},class extends d{constructor(){super(...arguments),this.name="Admiral"}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("div > div[class*=Card] > div[class*=Frame] > div[class*=Pills] > button[class*=Pills__StyledPill]")}async detectPopup(){return this.elementVisible("div > div[class*=Card] > div[class*=Frame] > div[class*=Pills] > button[class*=Pills__StyledPill]","any")}async optOut(){const e="xpath///button[contains(., 'Afvis alle') or contains(., 'Reject all') or contains(., 'Odbaci sve') or contains(., 'Rechazar todo') or contains(., 'Atmesti visus') or contains(., 'Odmítnout vše') or contains(., 'Απόρριψη όλων') or contains(., 'Rejeitar tudo') or contains(., 'Tümünü reddet') or contains(., 'Отклонить все') or contains(., 'Noraidīt visu') or contains(., 'Avvisa alla') or contains(., 'Odrzuć wszystkie') or contains(., 'Alles afwijzen') or contains(., 'Отхвърляне на всички') or contains(., 'Rifiuta tutto') or contains(., 'Zavrni vse') or contains(., 'Az összes elutasítása') or contains(., 'Respingeți tot') or contains(., 'Alles ablehnen') or contains(., 'Tout rejeter') or contains(., 'Odmietnuť všetko') or contains(., 'Lükka kõik tagasi') or contains(., 'Hylkää kaikki')]";if(await this.waitForElement(e,500))return this.click(e);const t="xpath///button[contains(., 'Spara & avsluta') or contains(., 'Save & exit') or contains(., 'Uložit a ukončit') or contains(., 'Enregistrer et quitter') or contains(., 'Speichern & Verlassen') or contains(., 'Tallenna ja poistu') or contains(., 'Išsaugoti ir išeiti') or contains(., 'Opslaan & afsluiten') or contains(., 'Guardar y salir') or contains(., 'Shrani in zapri') or contains(., 'Uložiť a ukončiť') or contains(., 'Kaydet ve çıkış yap') or contains(., 'Сохранить и выйти') or contains(., 'Salvesta ja välju') or contains(., 'Salva ed esci') or contains(., 'Gem & afslut') or contains(., 'Αποθήκευση και έξοδος') or contains(., 'Saglabāt un iziet') or contains(., 'Mentés és kilépés') or contains(., 'Guardar e sair') or contains(., 'Zapisz & zakończ') or contains(., 'Salvare și ieșire') or contains(., 'Spremi i izađi') or contains(., 'Запазване и изход')]";if(await this.waitForThenClick("xpath///button[contains(., 'Zwecke') or contains(., 'Σκοποί') or contains(., 'Purposes') or contains(., 'Цели') or contains(., 'Eesmärgid') or contains(., 'Tikslai') or contains(., 'Svrhe') or contains(., 'Cele') or contains(., 'Účely') or contains(., 'Finalidades') or contains(., 'Mērķi') or contains(., 'Scopuri') or contains(., 'Fines') or contains(., 'Ändamål') or contains(., 'Finalités') or contains(., 'Doeleinden') or contains(., 'Tarkoitukset') or contains(., 'Scopi') or contains(., 'Amaçlar') or contains(., 'Nameni') or contains(., 'Célok') or contains(., 'Formål')]")&&await this.waitForVisible(t)){return this.elementSelector(t)[0].parentElement.parentElement.querySelectorAll("input[type=checkbox]:checked").forEach((e=>e.click())),this.click(t)}return!1}async optIn(){return this.click("xpath///button[contains(., 'Sprejmi vse') or contains(., 'Prihvati sve') or contains(., 'Godkänn alla') or contains(., 'Prijať všetko') or contains(., 'Принять все') or contains(., 'Aceptar todo') or contains(., 'Αποδοχή όλων') or contains(., 'Zaakceptuj wszystkie') or contains(., 'Accetta tutto') or contains(., 'Priimti visus') or contains(., 'Pieņemt visu') or contains(., 'Tümünü kabul et') or contains(., 'Az összes elfogadása') or contains(., 'Accept all') or contains(., 'Приемане на всички') or contains(., 'Accepter alle') or contains(., 'Hyväksy kaikki') or contains(., 'Tout accepter') or contains(., 'Alles accepteren') or contains(., 'Aktsepteeri kõik') or contains(., 'Přijmout vše') or contains(., 'Alles akzeptieren') or contains(., 'Aceitar tudo') or contains(., 'Acceptați tot')]")}}],_=class{constructor(e){this.autoconsentInstance=e}click(e,t=!1){const o=this.elementSelector(e);return this.autoconsentInstance.config.logs.rulesteps&&console.log("[click]",e,t,o),o.length>0&&(t?o.forEach((e=>e.click())):o[0].click()),o.length>0}elementExists(e){return this.elementSelector(e).length>0}elementVisible(e,t){const o=this.elementSelector(e),i=new Array(o.length);return o.forEach(((e,t)=>{i[t]=k(e)})),"none"===t?i.every((e=>!e)):0!==i.length&&("any"===t?i.some((e=>e)):i.every((e=>e)))}waitForElement(e,t=1e4){const o=Math.ceil(t/200);return this.autoconsentInstance.config.logs.rulesteps&&console.log("[waitForElement]",e),f((()=>this.elementSelector(e).length>0),o,200)}waitForVisible(e,t=1e4,o="any"){const i=Math.ceil(t/200);return this.autoconsentInstance.config.logs.rulesteps&&console.log("[waitForVisible]",e),f((()=>this.elementVisible(e,o)),i,200)}async waitForThenClick(e,t=1e4,o=!1){return await this.waitForElement(e,t),this.click(e,o)}wait(e){return this.autoconsentInstance.config.logs.rulesteps&&this.autoconsentInstance.config.logs.waits&&console.log("[wait]",e),new Promise((t=>{setTimeout((()=>{t(!0)}),e)}))}hide(e,t){this.autoconsentInstance.config.logs.rulesteps&&console.log("[hide]",e);return g(m(),e,t)}prehide(e){const t=m("autoconsent-prehide");return this.autoconsentInstance.config.logs.lifecycle&&console.log("[prehide]",t,location.href),g(t,e,"opacity")}undoPrehide(){const e=m("autoconsent-prehide");return this.autoconsentInstance.config.logs.lifecycle&&console.log("[undoprehide]",e,location.href),e&&e.remove(),!!e}async createOrUpdateStyleSheet(e,t){return t||(t=new CSSStyleSheet),t=await t.replace(e)}removeStyleSheet(e){return!!e&&(e.replace(""),!0)}querySingleReplySelector(e,t=document){if(e.startsWith("aria/"))return[];if(e.startsWith("xpath/")){const o=e.slice(6),i=document.evaluate(o,t,null,XPathResult.ANY_TYPE,null);let n=null;const s=[];for(;n=i.iterateNext();)s.push(n);return s}return e.startsWith("text/")||e.startsWith("pierce/")?[]:t.shadowRoot?Array.from(t.shadowRoot.querySelectorAll(e)):Array.from(t.querySelectorAll(e))}querySelectorChain(e){let t,o=document;for(const i of e){if(t=this.querySingleReplySelector(i,o),0===t.length)return[];o=t[0]}return t}elementSelector(e){return"string"==typeof e?this.querySingleReplySelector(e):this.querySelectorChain(e)}};function C(){return{chars:new Map,code:void 0}}var x=new Uint8Array(0),S=class{constructor(e,t=3e4){this.trie=function(e){const t=C();for(let o=0;o figure.wp-block-image:has(> img[class^="wp-image-"][src^="https://www.sinhasannews.com/"][width="','"]:not([style^="width: 1px; height: 1px; position: absolute; left: -10000px; top: -"])',"acs, document.createElement, %2Fl%5C.parentNode%5C.insertBefore%5C(s%2F","%2Fvisit%2F%22%5D%5Btitle%5E%3D%22https%3A%2F%2F%22%5D, %5Btitle%5D",", OptanonConsent, groups%3DC0001%253A1%252CC0002%253A0%252CC000","rmnt, script, %2Fh%3DdecodeURIComponent%7CpopundersPerIP%2F",'.project-description [href^="/linkout?remoteUrl="][href*="',':not([style^="position: absolute; left: -5000px"])',"href-sanitizer, a%5Bhref%5E%3D%22https%3A%2F%2F","ra, oncontextmenu%7Condragstart%7Conselectstart",", OptanonAlertBoxClosed, %24currentDate%24","acs, document.querySelectorAll, popMagic","acs, addEventListener, google_ad_client","aost, String.prototype.charCodeAt, ai_","aopr, app_vars.force_disable_adblock","acs, document.addEventListener, ","taboola-below-article-thumbnails","acs, document.getElementById, ","no-fetch-if, googlesyndication","aopr, document.dispatchEvent","no-xhr-if, googlesyndication",", document.createElement, ","acs, String.fromCharCode, ","%2522%253Afalse%252C%2522",", document.oncontextmenu","%2522%253Atrue%252C%2522","aeld, DOMContentLoaded, ","nosiif, visibility, 1000","set-local-storage-item, ","%2522%3Afalse%252C%2522","trusted-click-element, ","set, blurred, false","acs, eval, replace","decodeURIComponent",'[target="_blank"]',"%22%3Afalse%2C%22","^script:has-text(",'[href^="https://','[href^="http://','[href="https://','[src^="https://','[data-testid="',"modal-backdrop","rmnt, script, ","BlockDetected","trusted-set-",".prototype.","contextmenu","no-fetch-if","otification",":has-text(","background",'[class*="','[class^="',"body,html","container","Container","decodeURI","div[class",'div[id^="',"div[style","document.","no-xhr-if","placehold",'[href*="',"#wpsafe-","AAAAAAAA","Detector","disclaim","nano-sib","nextFunc","noopFunc","nostif, ","nowebrtc",'.com/"]',"300x250","article","consent","Consent","content","display","keydown","message","Message","overlay","privacy","sidebar","sponsor","wrapper","-child","[data-","accept","Accept","aopr, ","banner","bottom","cookie","Cookie","google","nosiif","notice","nowoif","policy","Policy","script","widget",":has(",":not(","block","Block","click","deskt","disab","fixed","frame","modal","popup","video",".com","2%3A","aeld","body","butt","foot","gdpr","html","icky","ight","show","tion","true"," > ","%3D","%7C","age","box","div","ent","out","rap","set","__",", ",'"]',"%2","%5",'="',"00","ac","ad","Ad","al","an","ar","at","e-","ed","en","er","he","id","in","la","le","lo","od","ol","om","on","op","or","re","s_","s-","se","st","t-","te","ti","un","_","-",";",":",".","(",")","[","]","*","/","#","^","0","1","2","3","4","5","6","7","8","9","b","B","c","C","d","D","e","E","f","F","g","G","h","H","I","j","J","k","l","L","m","M","n","N","O","p","P","q","Q","R","s","S","t","T","u","U","v","V","w","W","x","y","Y","z"],T=["sandbox allow-forms allow-same-origin allow-scripts allow-modals allow-orientation-lock allow-pointer-lock allow-presentation allow-top-navigation","script-src 'self' 'unsafe-inline' 'unsafe-eval' "," *.google.com *.gstatic.com *.googleapis.com",".com *.google.com *.googletagmanager.com *.","script-src 'self' '*' 'unsafe-inline'","default-src 'unsafe-inline' 'self'","script-src 'self' 'unsafe-eval' "," *.google.com *.gstatic.com *.","t-src 'self' 'unsafe-inline' ","script-src * 'unsafe-inline'",".com *.googleapis.com *."," *.googletagmanager.com",".com *.bootstrapcdn.com","default-src 'self' *.","frame-src 'self' *"," *.cloudflare.com","child-src 'none';","worker-src 'none'","'unsafe-inline'"," data: blob:","*.googleapis","connect-src ","unsafe-eval'","child-src *"," *.gstatic","script-src","style-src ","frame-src","facebook","https://"," 'self'"," allow-",".com *.",".net *.","addthis","captcha","gstatic","youtube","defaul","disqus","google","https:","jquery","data:","http:","media","scrip","-src",".com",".net","n.cc"," *.","age","box","str","vic","yti"," '"," *","*.","al","am","an","as","cd","el","es","il","im","in","or","pi","st","ur","wi","wp"," ","-",";",":",".","'","*","/","3","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y"],O=["/homad-global-configs.schneevonmorgen.com/global_config","/videojs-vast-vpaid@2.0.2/bin/videojs_5.vast.vpaid.min","/etc.clientlibs/logitech-common/clientlibs/onetrust.","/pagead/managed/js/adsense/*/show_ads_impl","/pagead/managed/js/gpt/*/pubads_impl","/wrappermessagingwithoutdetection","/pagead/js/adsbygoogle.js","a-z]{8,15}\\.(?:com|net)\\/","/js/sdkloader/ima3.js","/js/sdkloader/ima3_d","/videojs-contrib-ads","/wp-content/plugins/","/wp-content/uploads/","/wp-content/themes/","/detroitchicago/","*/satellitelib-","/appmeasurement","/413gkwmt/init","/cdn-cgi/trace","/^https?:\\/\\/","[a-zA-Z0-9]{","/^https:\\/\\/","notification","\\/[a-z0-9]{","fingerprint","impression","[0-9a-z]{","/plugins/","affiliate","analytics","telemetry","(.+?\\.)?","/assets/","/images/","/pagead/","pageview","template","tracking","/public","300x250","ampaign","captcha","collect","consent","content","counter","default","metrics","privacy","[a-z]{","/embed","728x90","banner","bundle","client","cookie","detect","dn-cgi","google","iframe","module","prebid","script","source","widget",".aspx",".cgi?",".com/",".html","/api/","/beac","/img/","/java","/stat","0x600","block","click","count","event","manag","media","pixel","popup","tegra","theme","track","type=","video","visit",".css",".gif",".jpg",".min",".php",".png","/jqu","/js/","/lib","/log","/web","/wp-","468x","data","gdpr","gi-b","http","ight","mail","play","plug","publ","show","stat","uild","view",".js","/ad","=*&","age","com","ext","jax","key","log","new","sdk","tag","web","ync",":/","*/","*^","/_","/?","/*","/d","/f","/g","/h","/l","/n","/r","/u","/w","ac","ad","al","am","an","ap","ar","as","at","bo","ce","ch","co","de","e/","ec","ed","el","en","er","et","fi","g/","ic","id","im","in","is","it","js","la","le","li","lo","ma","mo","mp","ol","om","on","op","or","ot","re","ro","s_","s-","s?","s/","sp","ss","st","t/","ti","tm","tr","ub","un","ur","us","ut","ve","_","-",",","?",".","}","*","/","\\","&","^","=","0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],P=["securepubads.g.doubleclick",".actonservice.com","googlesyndication","imasdk.googleapis",".cloudfront.net","googletagmanag","-1.xx.fbcdn","analytics.","marketing.","tracking.","metrics.","images.",".co.uk","a8clk.","stats.","a8cv.","click","media","track",".com",".net",".xyz","www.",".io",".jp","a8.","app","cdn","new","web",".b",".c",".d",".f",".h",".k",".m",".n",".p",".s",".t","10","24","a-","a1","a2","a4","ab","ac","ad","af","ag","ah","ai","ak","al","am","an","ap","ar","as","at","au","av","aw","ax","ay","az","be","bi","bl","bo","br","bu","ca","ce","ch","ci","ck","cl","cr","ct","cu","de","di","dn","do","dr","ds","du","dy","e-","eb","ec","ed","ef","eg","el","em","en","ep","er","es","et","eu","ev","ew","ex","ey","fe","ff","fi","fo","fr","ft","ge","gh","gi","gn","go","gr","gu","he","ho","ib","ic","id","ie","if","ig","ik","il","im","in","ip","ir","is","it","iv","ix","iz","jo","ks","la","le","li","ll","lo","lu","ly","ma","me","mo","mp","my","no","ok","ol","om","on","oo","op","or","ot","ou","ph","pl","po","pr","pu","qu","re","ri","ro","ru","s-","sc","se","sh","si","sk","sn","so","sp","ss","st","su","sw","sy","t-","ta","te","th","ti","tn","to","tr","ts","tu","ty","ub","ud","ul","um","un","up","ur","us","ut","ve","vi","vo","wa","we","wh","wn","-",".","0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],R=["google-analytics.com/analytics.js","googlesyndication_adsbygoogle.js","googletagmanager.com/gtm.js","googletagservices_gpt.js","googletagmanager_gtm.js","fuckadblock.js-3.2.0","amazon_apstag.js","google-analytics","fingerprint2.js","noop-1s.mp4:10","google-ima.js","noop-0.1s.mp3","prebid-ads.js","nobab2.js:10","noopmp3-0.1s","noop-1s.mp4","hd-main.js","noopmp4-1s","32x32.png","noop.html","noopframe","noop.txt","nooptext","1x1.gif","2x2.png","noop.js","noopjs",".com/",".js:5","noop",":10",".js","ads","bea","_a",":5",".0","ar","ch","ic","in","le","ma","on","re","st","_","-",":",".","/","0","1","2","3","4","5","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","r","s","t","u","v","w","x","y","z"],z=[",redirect=google-ima","/js/sdkloader/ima3.j","/wp-content/plugins/",",redirect-rule=noop",".actonservice.com^",".com^$third-party","googlesyndication","imasdk.googleapis",".cloudfront.net^",",redirect-rule=","$script,domain=",",3p,denyallow=",",redirect=noop","xmlhttprequest","^$third-party","||smetrics.","third-party","marketing.","$document","analytics",",domain=","/assets/","metrics.","subdocum","tracking","$script",".co.uk","$ghide","a8clk.","cookie","google","script",".com^",".xyz^","$doma","a8cv.","click","image","media","track",".com",".fr^",".gif",".jp^",".net","/js/","$doc","$xhr","stat","www.",",1p",",3p",".io",".jp",".js","app","cdn","ent","new","web",".b",".c",".d",".f",".h",".m",".n",".p",".s",".t","@@","/*","/p","||","ab","ac","ad","af","ag","ai","ak","al","am","an","ap","ar","as","at","au","av","aw","ax","ay","az","be","bi","bo","br","ca","ce","ch","ck","cl","ct","cu","de","di","do","e-","e^","ec","ed","el","em","en","ep","er","es","et","ev","ew","ex","fe","ff","fi","fo","fr","g^","ge","gi","go","gr","he","hi","ho","hp","ht","ic","id","ig","il","im","in","ip","ir","is","it","ix","js","ke","le","li","lo","lu","ly","me","mo","mp","ne","no","od","ok","ol","om","on","op","or","ot","ow","pl","po","pr","qu","re","ri","ro","ru","s-","s/","sc","se","sh","si","so","sp","ss","st","su","te","th","ti","to","tr","ts","ty","ub","ud","ul","um","un","up","ur","us","ut","ve","vi","_","-",",","?",".","*","/","^","=","|","~","$","0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"],L=["-webkit-touch-callo",", 1year, , domain, ",", googlesyndication",", SOCS, CAISNQgQEit",":style(overflow: au","##^script:has-text(","9udGVuZHVpc2VydmVyX","GgJmaSADGgYIgOu0sgY","ib3FfaWRlbnRpdHlmcm","position: initial !","set-local-storage-i","set, blurred, false","user-select: text !","zIwMjQwNTE0LjA2X3Aw",'[href^="https://',"rmnt, script, ","ut: default !"," !important)","trusted-set-",", document.",", noopFunc)","##body,html","contextmenu","no-fetch-if","otification",".com##+js(",'="https://',"background","important;"," -webkit-",".*,xhamst","container","AAAAAAAA","nostif, ",",google",":style(","consent","message","nowoif)","privacy","-wrapp",",kayak",".co.uk","[class","##+js(","accept","aopr, ","banner","bottom","cookie","Cookie","google","notice","policy","widget",":has(","##div","block","cript","true)",".co.",".com",".de,",".fr,",".net",".nl,",".pl,",".xyz","#@#.","2%3A","gdpr","html","ight","news","text","to !","wrap","www."," > ",",xh","##.","###","%3D","%7C","ent","lay","web","__","-s",", ",",b",",c",",f",",g",",h",",m",",p",",s",",t",": ",".*",".b",".c",".m",".p",".s",'"]',"##","%2","%5",'="',"00","a-","ab","ac","ad","Ad","af","ag","ak","al","am","an","ap","ar","as","at","au","av","ay","az","bo","ch","ck","cl","ct","de","di","do","e-","ed","el","em","en","er","es","et","ex","fi","fo","he","ic","id","if","ig","il","im","in","is","it","iv","le","lo","mo","ol","om","on","op","or","ot","ov","pl","po","re","ro","s_","s-","se","sh","si","sp","st","t-","th","ti","tr","tv","ub","ul","um","un","up","ur","us","ut","vi"," ","_","-",",",":",".","(",")","[","*","/","^","0","1","2","3","4","5","6","7","8","9","a","b","B","c","C","d","D","e","E","f","F","g","h","i","j","k","l","L","m","M","n","o","p","P","q","r","s","S","t","T","u","v","w","x","y","z"],B=class{constructor(){this.cosmeticSelector=new I(F),this.networkCSP=new I(T),this.networkRedirect=new I(R),this.networkHostname=new I(P),this.networkFilter=new I(O),this.networkRaw=new I(z),this.cosmeticRaw=new I(L)}},U=(()=>{let e=0;const t=new Int32Array(256);for(let o=0;256!==o;o+=1)e=o,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,t[o]=e;return t})();var N=2147483647,V=36,j=/[^\0-\x7E]/,M=/[\x2E\u3002\uFF0E\uFF61]/g,D={"invalid-input":"Invalid input","not-basic":"Illegal input >= 0x80 (not a basic code point)",overflow:"Overflow: input needs wider integers to process"};function H(e){throw new RangeError(D[e])}function W(e,t){return e+22+75*(e<26?1:0)-((0!==t?1:0)<<5)}function q(e,t,o){let i=0;for(e=o?Math.floor(e/700):e>>1,e+=Math.floor(e/t);e>455;i+=V)e=Math.floor(e/35);return Math.floor(i+36*e/(e+38))}function G(e){const t=[],o=e.length;let i=0,n=128,s=72,c=e.lastIndexOf("-");c<0&&(c=0);for(let o=0;o=128&&H("not-basic"),t.push(e.charCodeAt(o));for(let a=c>0?c+1:0;a=o&&H("invalid-input");const c=(r=e.charCodeAt(a++))-48<10?r-22:r-65<26?r-65:r-97<26?r-97:V;(c>=V||c>Math.floor((N-i)/t))&&H("overflow"),i+=c*t;const l=n<=s?1:n>=s+26?26:n-s;if(cMath.floor(N/p)&&H("overflow"),t*=p}const l=t.length+1;s=q(i-c,l,0===c),Math.floor(i/l)>N-n&&H("overflow"),n+=Math.floor(i/l),i%=l,t.splice(i++,0,n)}var r;return String.fromCodePoint.apply(null,t)}function $(e){const t=[],o=function(e){const t=[];let o=0;const i=e.length;for(;o=55296&&n<=56319&&o=n&&iMath.floor((N-s)/i)&&H("overflow"),s+=(e-n)*i,n=e;for(let e=0;eN&&H("overflow"),l===n){let e=s;for(let o=V;;o+=V){const i=o<=c?1:o>=c+26?26:o-c;if(e{const e=new B;return Z=()=>e,e};function J(e){return e<=127?1:5}function ee(e,t){return te(e.length,t)}function te(e,t){return(t?3:0)+e+J(e)}function oe(e){return e.length+J(e.length)}function ie(e){const t=$(e).length;return t+J(t)}function ne(e){return e.byteLength+J(e.length)}var se,ce=class e{static empty(t){return e.fromUint8Array(Q,t)}static fromUint8Array(t,o){return new e(t,o)}static allocate(t,o){return new e(new Uint8Array(t),o)}constructor(e,{enableCompression:t}){if(!1===X)throw new Error("Adblocker currently does not support Big-endian systems");!0===t&&this.enableCompression(),this.buffer=e,this.pos=0}enableCompression(){this.compression=Z()}checksum(){return function(e,t,o){let i=-1;const n=o-7;let s=t;for(;s>>8^U[255&(i^e[s++])],i=i>>>8^U[255&(i^e[s++])],i=i>>>8^U[255&(i^e[s++])],i=i>>>8^U[255&(i^e[s++])],i=i>>>8^U[255&(i^e[s++])],i=i>>>8^U[255&(i^e[s++])],i=i>>>8^U[255&(i^e[s++])],i=i>>>8^U[255&(i^e[s++])];for(;s>>8^U[255&(i^e[s++])];return~i>>>0}(this.buffer,0,this.pos)}dataAvailable(){return this.pos>>8,this.buffer[this.pos++]=e}getUint16(){return(this.buffer[this.pos++]<<8|this.buffer[this.pos++])>>>0}pushUint32(e){this.buffer[this.pos++]=e>>>24,this.buffer[this.pos++]=e>>>16,this.buffer[this.pos++]=e>>>8,this.buffer[this.pos++]=e}getUint32(){return(this.buffer[this.pos++]<<24>>>0)+(this.buffer[this.pos++]<<16|this.buffer[this.pos++]<<8|this.buffer[this.pos++])>>>0}pushUint32Array(e){this.pushLength(e.length);for(const t of e)this.pushUint32(t)}getUint32Array(){const e=this.getLength(),t=new Uint32Array(e);for(let o=0;othis.buffer.byteLength)throw new Error(`StaticDataView too small: ${this.buffer.byteLength}, but required ${this.pos} bytes`)}pushLength(e){e<=127?this.pushUint8(e):(this.pushUint8(128),this.pushUint32(e))}getLength(){const e=this.getUint8();return 128===e?this.getUint32():e}},re=class e{static deserialize(t){return new e({debug:t.getBool(),enableCompression:t.getBool(),enableHtmlFiltering:t.getBool(),enableInMemoryCache:t.getBool(),enableMutationObserver:t.getBool(),enableOptimizations:t.getBool(),enablePushInjectionsOnNavigationEvents:t.getBool(),guessRequestTypeFromUrl:t.getBool(),integrityCheck:t.getBool(),loadCSPFilters:t.getBool(),loadCosmeticFilters:t.getBool(),loadExceptionFilters:t.getBool(),loadExtendedSelectors:t.getBool(),loadGenericCosmeticsFilters:t.getBool(),loadNetworkFilters:t.getBool(),loadPreprocessors:t.getBool()})}constructor({debug:e=!1,enableCompression:t=!1,enableHtmlFiltering:o=!1,enableInMemoryCache:i=!0,enableMutationObserver:n=!0,enableOptimizations:s=!0,enablePushInjectionsOnNavigationEvents:c=!0,guessRequestTypeFromUrl:r=!1,integrityCheck:a=!0,loadCSPFilters:l=!0,loadCosmeticFilters:p=!0,loadExceptionFilters:d=!0,loadExtendedSelectors:u=!1,loadGenericCosmeticsFilters:h=!0,loadNetworkFilters:m=!0,loadPreprocessors:A=!1}={}){this.debug=e,this.enableCompression=t,this.enableHtmlFiltering=o,this.enableInMemoryCache=i,this.enableMutationObserver=n,this.enableOptimizations=s,this.enablePushInjectionsOnNavigationEvents=c,this.guessRequestTypeFromUrl=r,this.integrityCheck=a,this.loadCSPFilters=l,this.loadCosmeticFilters=p,this.loadExceptionFilters=d,this.loadExtendedSelectors=u,this.loadGenericCosmeticsFilters=h,this.loadNetworkFilters=m,this.loadPreprocessors=A}getSerializedSize(){return 16}serialize(e){e.pushBool(this.debug),e.pushBool(this.enableCompression),e.pushBool(this.enableHtmlFiltering),e.pushBool(this.enableInMemoryCache),e.pushBool(this.enableMutationObserver),e.pushBool(this.enableOptimizations),e.pushBool(this.enablePushInjectionsOnNavigationEvents),e.pushBool(this.guessRequestTypeFromUrl),e.pushBool(this.integrityCheck),e.pushBool(this.loadCSPFilters),e.pushBool(this.loadCosmeticFilters),e.pushBool(this.loadExceptionFilters),e.pushBool(this.loadExtendedSelectors),e.pushBool(this.loadGenericCosmeticsFilters),e.pushBool(this.loadNetworkFilters),e.pushBool(this.loadPreprocessors)}},ae="undefined"!=typeof window&&"function"==typeof window.queueMicrotask?e=>window.queueMicrotask(e):e=>(se||(se=Promise.resolve())).then(e).catch((e=>setTimeout((()=>{throw e}),0)));function le(e,t,o){let i=o.get(e);void 0===i&&(i=[],o.set(e,i)),i.push(t)}function pe(e,t,o){const i=o.get(e);if(void 0!==i){const e=i.indexOf(t);-1!==e&&i.splice(e,1)}}function de(e,t,o){if(0===o.size)return!1;const i=o.get(e);return void 0!==i&&(ae((()=>{for(const e of i)e(...t)})),!0)}var ue=class{constructor(){this.onceListeners=new Map,this.onListeners=new Map}on(e,t){le(e,t,this.onListeners)}once(e,t){le(e,t,this.onceListeners)}unsubscribe(e,t){pe(e,t,this.onListeners),pe(e,t,this.onceListeners)}emit(e,...t){de(e,t,this.onListeners),!0===de(e,t,this.onceListeners)&&this.onceListeners.delete(e)}};function he(e,t){return function(e,t){let o=3;const i=()=>e(t).catch((e=>{if(o>0)return o-=1,new Promise(((e,t)=>{setTimeout((()=>{i().then(e).catch(t)}),500)}));throw e}));return i()}(e,t).then((e=>e.text()))}var me="https://raw.githubusercontent.com/ghostery/adblocker/master/packages/adblocker/assets",Ae=[`${me}/easylist/easylist.txt`,`${me}/peter-lowe/serverlist.txt`,`${me}/ublock-origin/badware.txt`,`${me}/ublock-origin/filters-2020.txt`,`${me}/ublock-origin/filters-2021.txt`,`${me}/ublock-origin/filters-2022.txt`,`${me}/ublock-origin/filters-2023.txt`,`${me}/ublock-origin/filters-2024.txt`,`${me}/ublock-origin/filters.txt`,`${me}/ublock-origin/quick-fixes.txt`,`${me}/ublock-origin/resource-abuse.txt`,`${me}/ublock-origin/unbreak.txt`],ge=[...Ae,`${me}/easylist/easyprivacy.txt`,`${me}/ublock-origin/privacy.txt`],fe=[...ge,`${me}/easylist/easylist-cookie.txt`,`${me}/ublock-origin/annoyances-others.txt`,`${me}/ublock-origin/annoyances-cookies.txt`];var ke=new Set(["any","dir","has","host-context","if","if-not","is","matches","not","where"]),be={attribute:/\[\s*(?:(?\*|[-\w]*)\|)?(?[-\w\u{0080}-\u{FFFF}]+)\s*(?:(?\W?=)\s*(?.+?)\s*(?[iIsS])?\s*)?\]/gu,id:/#(?(?:[-\w\u{0080}-\u{FFFF}]|\\.)+)/gu,class:/\.(?(?:[-\w\u{0080}-\u{FFFF}]|\\.)+)/gu,comma:/\s*,\s*/g,combinator:/\s*[\s>+~]\s*/g,"pseudo-element":/::(?[-\w\u{0080}-\u{FFFF}]+)(?:\((?:¶*)\))?/gu,"pseudo-class":/:(?[-\w\u{0080}-\u{FFFF}]+)(?:\((?¶*)\))?/gu,type:/(?:(?\*|[-\w]*)\|)?(?[-\w\u{0080}-\u{FFFF}]+)|\*/gu},ye=new Set(["pseudo-class","pseudo-element"]),we=new Set([...ye,"attribute"]),ve=new Set(["combinator","comma"]),_e=Object.assign({},be);function Ce(e,t){e.lastIndex=0;const o=e.exec(t);if(null===o)return;const i=o.index-1,n=o[0],s=t.slice(0,i+1),c=t.slice(i+n.length+1);return[s,[n,o.groups||{}],c]}_e["pseudo-element"]=RegExp(be["pseudo-element"].source.replace("(?¶*)","(?.*?)"),"gu"),_e["pseudo-class"]=RegExp(be["pseudo-class"].source.replace("(?¶*)","(?.*)"),"gu");var xe=[e=>{const t=Ce(be.attribute,e);if(void 0===t)return;const[o,[i,{name:n,operator:s,value:c,namespace:r,caseSensitive:a}],l]=t;return void 0!==n?[o,{type:"attribute",content:i,length:i.length,namespace:r,caseSensitive:a,pos:[],name:n,operator:s,value:c},l]:void 0},e=>{const t=Ce(be.id,e);if(void 0===t)return;const[o,[i,{name:n}],s]=t;return void 0!==n?[o,{type:"id",content:i,length:i.length,pos:[],name:n},s]:void 0},e=>{const t=Ce(be.class,e);if(void 0===t)return;const[o,[i,{name:n}],s]=t;return void 0!==n?[o,{type:"class",content:i,length:i.length,pos:[],name:n},s]:void 0},e=>{const t=Ce(be.comma,e);if(void 0===t)return;const[o,[i],n]=t;return[o,{type:"comma",content:i,length:i.length,pos:[]},n]},e=>{const t=Ce(be.combinator,e);if(void 0===t)return;const[o,[i],n]=t;return[o,{type:"combinator",content:i,length:i.length,pos:[]},n]},e=>{const t=Ce(be["pseudo-element"],e);if(void 0===t)return;const[o,[i,{name:n}],s]=t;return void 0!==n?[o,{type:"pseudo-element",content:i,length:i.length,pos:[],name:n},s]:void 0},e=>{const t=Ce(be["pseudo-class"],e);if(void 0===t)return;const[o,[i,{name:n,argument:s}],c]=t;return void 0!==n?[o,{type:"pseudo-class",content:i,length:i.length,pos:[],name:n,argument:s,subtree:void 0},c]:void 0},e=>{const t=Ce(be.type,e);if(void 0===t)return;const[o,[i,{name:n,namespace:s}],c]=t;return[o,{type:"type",content:i,length:i.length,namespace:s,pos:[],name:n},c]}];function Se(e,t,o,i){for(const n of t)for(const t of e)if(i.has(t.type)&&t.pos[0]=0&&"\\"===e[t];)o+=1,t-=1;return o%2!=0}function Ie(e,t,o){let i=o+1;for(;-1!==(i=e.indexOf(t,i))&&!0===Ee(e,i);)i+=1;if(-1!==i)return e.slice(o,i+1)}function Fe(e,t){let o=0;for(let i=t;i0))return;o-=1}if(0===o)return e.slice(t,i+1)}}function Te(e,t,o,i){const n=[];let s=0;for(;-1!==(s=e.indexOf(o,s));){const o=i(e,s);if(void 0===o)break;n.push({str:o,start:s}),e=`${e.slice(0,s+1)}${t.repeat(o.length-2)}${e.slice(s+o.length-1)}`,s+=o.length}return[n,e]}function Oe(e){if("string"!=typeof e)return[];if(0===(e=e.trim()).length)return[];const[t,o]=Te(e,"§",'"',((e,t)=>Ie(e,'"',t))),[i,n]=Te(o,"§","'",((e,t)=>Ie(e,"'",t))),[s,c]=Te(n,"¶","(",Fe),r=function(e){if(!e)return[];const t=[e];for(const e of xe)for(let o=0;o0!==e.length)))}}let o=0;for(const e of t)"string"!=typeof e&&(e.pos=[o,o+e.length],ve.has(e.type)&&(e.content=e.content.trim()||" ")),o+=e.length;return t.every((e=>"string"!=typeof e))?t:[]}(c);return Se(r,s,/\(¶*\)/,ye),Se(r,t,/"§*"/,we),Se(r,i,/'§*'/,we),r}function Pe(e,{list:t=!0}={}){if(!0===t&&e.some((e=>"comma"===e.type))){const t=[],o=[];for(let i=0;i=0;t--){const o=e[t];if("combinator"===o.type){const i=Pe(e.slice(0,t)),n=Pe(e.slice(t+1));if(void 0===n)return;if(" "!==o.content&&"~"!==o.content&&"+"!==o.content&&">"!==o.content)return;return{type:"complex",combinator:o.content,left:i,right:n}}}if(0!==e.length)return function(e){return e.every((e=>"comma"!==e.type&&"combinator"!==e.type))}(e)?1===e.length?e[0]:{type:"compound",compound:[...e]}:void 0}function Re(e,t,o,i){if(void 0!==e){if("complex"===e.type)Re(e.left,t,o,e),Re(e.right,t,o,e);else if("compound"===e.type)for(const i of e.compound)Re(i,t,o,e);else"pseudo-class"===e.type&&void 0!==e.subtree&&void 0!==o&&"pseudo-class"===o.type&&void 0!==o.subtree&&Re(e.subtree,t,o,e);t(e,i)}}function ze(e,{recursive:t=!0,list:o=!0}={}){const i=Oe(e);if(0===i.length)return;const n=Pe(i,{list:o});return!0===t&&Re(n,(e=>{"pseudo-class"===e.type&&e.argument&&void 0!==e.name&&ke.has(e.name)&&(e.subtree=ze(e.argument,{recursive:!0,list:!0}))})),n}var Le,Be,Ue=new Set(["has","has-text","if"]),Ne=new Set(["active","any","any-link","blank","checked","default","defined","dir","disabled","empty","enabled","first","first-child","first-of-type","focus","focus-visible","focus-within","fullscreen","host","host-context","hover","in-range","indeterminate","invalid","is","lang","last-child","last-of-type","left","link","matches","not","nth-child","nth-last-child","nth-last-of-type","nth-of-type","only-child","only-of-type","optional","out-of-range","placeholder-shown","read-only","read-write","required","right","root","scope","target","valid","visited","where"]),Ve=new Set(["after","before","first-letter","first-line"]);function je(e){if(-1===e.indexOf(":"))return Le.Normal;const t=Oe(e);let o=!1;for(const e of t)if("pseudo-class"===e.type){const{name:t}=e;if(!0===Ue.has(t))o=!0;else if(!1===Ne.has(t)&&!1===Ve.has(t))return Le.Invalid;if(!1===o&&void 0!==e.argument&&!0===ke.has(t)){const t=je(e.argument);if(t===Le.Invalid)return t;t===Le.Extended&&(o=!0)}}return!0===o?Le.Extended:Le.Normal}(Be=Le||(Le={}))[Be.Normal=0]="Normal",Be[Be.Extended=1]="Extended",Be[Be.Invalid=2]="Invalid";var Me=new Set(["htm","html","xhtml"]),De=new Set(["eot","otf","sfnt","ttf","woff","woff2"]),He=new Set(["apng","bmp","cur","dib","eps","gif","heic","heif","ico","j2k","jfi","jfif","jif","jp2","jpe","jpeg","jpf","jpg","jpm","jpx","mj2","pjp","pjpeg","png","svg","svgz","tif","tiff","webp"]),We=new Set(["avi","flv","mp3","mp4","ogg","wav","weba","webm","wmv"]),qe=new Set(["js","ts","jsx","esm"]),Ge=new Set(["css","scss"]);function $e(e,t){let o=0,i=e.length,n=!1;if(!t){if(e.startsWith("data:"))return null;for(;oo+1&&e.charCodeAt(i-1)<=32;)i-=1;if(47===e.charCodeAt(o)&&47===e.charCodeAt(o+1))o+=2;else{const t=e.indexOf(":/",o);if(-1!==t){const i=t-o,n=e.charCodeAt(o),s=e.charCodeAt(o+1),c=e.charCodeAt(o+2),r=e.charCodeAt(o+3),a=e.charCodeAt(o+4);if(5===i&&104===n&&116===s&&116===c&&112===r&&115===a);else if(4===i&&104===n&&116===s&&116===c&&112===r);else if(3===i&&119===n&&115===s&&115===c);else if(2===i&&119===n&&115===s);else for(let i=o;i=97&&t<=122||t>=48&&t<=57||46===t||45===t||43===t))return null}for(o=t+2;47===e.charCodeAt(o);)o+=1}}let t=-1,s=-1,c=-1;for(let r=o;r=65&&o<=90&&(n=!0)}if(-1!==t&&t>o&&to&&co+1&&46===e.charCodeAt(i-1);)i-=1;const s=0!==o||i!==e.length?e.slice(o,i):e;return n?s.toLowerCase():s}function Ke(e){return e>=97&&e<=122||e>=48&&e<=57||e>127}function Qe(e){if(e.length>255)return!1;if(0===e.length)return!1;if(!Ke(e.charCodeAt(0))&&46!==e.charCodeAt(0)&&95!==e.charCodeAt(0))return!1;let t=-1,o=-1;const i=e.length;for(let n=0;n64||46===o||45===o||95===o)return!1;t=n}else if(!Ke(i)&&45!==i&&95!==i)return!1;o=i}return i-t-1<=63&&45!==o}var Ye=function({allowIcannDomains:e=!0,allowPrivateDomains:t=!1,detectIp:o=!0,extractHostname:i=!0,mixedInputs:n=!0,validHosts:s=null,validateHostname:c=!0}){return{allowIcannDomains:e,allowPrivateDomains:t,detectIp:o,extractHostname:i,mixedInputs:n,validHosts:s,validateHostname:c}}({});function Xe(e,t,o,i,n){const s=function(e){return void 0===e?Ye:function({allowIcannDomains:e=!0,allowPrivateDomains:t=!1,detectIp:o=!0,extractHostname:i=!0,mixedInputs:n=!0,validHosts:s=null,validateHostname:c=!0}){return{allowIcannDomains:e,allowPrivateDomains:t,detectIp:o,extractHostname:i,mixedInputs:n,validHosts:s,validateHostname:c}}(e)}(i);return"string"!=typeof e?n:(s.extractHostname?s.mixedInputs?n.hostname=$e(e,Qe(e)):n.hostname=$e(e,!1):n.hostname=e,0===t||null===n.hostname||s.detectIp&&(n.isIp=function(e){if(e.length<3)return!1;let t=e.startsWith("[")?1:0,o=e.length;if("]"===e[o-1]&&(o-=1),o-t>39)return!1;let i=!1;for(;t=48&&o<=57||o>=97&&o<=102||o>=65&&o<=90))return!1}return i}(c=n.hostname)||function(e){if(e.length<7)return!1;if(e.length>15)return!1;let t=0;for(let o=0;o57)return!1}return 3===t&&46!==e.charCodeAt(0)&&46!==e.charCodeAt(e.length-1)}(c),n.isIp)?n:s.validateHostname&&s.extractHostname&&!Qe(n.hostname)?(n.hostname=null,n):(o(n.hostname,s,n),2===t||null===n.publicSuffix?n:(n.domain=function(e,t,o){if(null!==o.validHosts){const e=o.validHosts;for(const o of e)if(function(e,t){return!!e.endsWith(t)&&(e.length===t.length||"."===e[e.length-t.length-1])}(t,o))return o}let i=0;if(t.startsWith("."))for(;i=i)return!1;let n=o,s=i-1;for(;n<=s;){const o=n+s>>>1,i=e[o];if(it))return!0;s=o-1}}return!1}var et=new Uint32Array(20);function tt(e,t,o){if(function(e,t,o){if(!t.allowPrivateDomains&&e.length>3){const t=e.length-1,i=e.charCodeAt(t),n=e.charCodeAt(t-1),s=e.charCodeAt(t-2),c=e.charCodeAt(t-3);if(109===i&&111===n&&99===s&&46===c)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="com",!0;if(103===i&&114===n&&111===s&&46===c)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="org",!0;if(117===i&&100===n&&101===s&&46===c)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="edu",!0;if(118===i&&111===n&&103===s&&46===c)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="gov",!0;if(116===i&&101===n&&110===s&&46===c)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="net",!0;if(101===i&&100===n&&46===s)return o.isIcann=!0,o.isPrivate=!1,o.publicSuffix="de",!0}return!1}(e,t,o))return;const{allowIcannDomains:i,allowPrivateDomains:n}=t;let s=-1,c=0,r=0,a=1;const l=function(e,t){let o=5381,i=0;for(let n=e.length-1;n>=0;n-=1){const s=e.charCodeAt(n);if(46===s&&(et[i<<1]=o>>>0,et[1+(i<<1)]=n+1,i+=1,i===t))return i;o=33*o^s}return et[i<<1]=o>>>0,et[1+(i<<1)]=0,i+=1,i}(e,Ze[0]);for(let e=0;er;)t.shift();o.publicSuffix=t.join(".")}else o.publicSuffix=e.slice(s);else o.publicSuffix=1===l?e:e.slice(et[1])}function ot(e,t={}){return Xe(e,5,tt,t,{domain:null,domainWithoutSuffix:null,hostname:null,isIcann:null,isIp:null,isPrivate:null,publicSuffix:null,subdomain:null})}var it=new class{constructor(e){this.pos=0,this.buffer=new Uint32Array(e)}reset(){this.pos=0}slice(){return this.buffer.slice(0,this.pos)}push(e){this.buffer[this.pos++]=e}empty(){return 0===this.pos}full(){return this.pos===this.buffer.length}remaining(){return this.buffer.length-this.pos}}(1024),nt=37,st=5011;function ct(e){return 16843009*((e=(858993459&(e-=e>>1&1431655765))+(e>>2&858993459))+(e>>4)&252645135)>>24}function rt(e,t){return!!(e&t)}function at(e,t){return e|t}function lt(e,t){return e&~t}function pt(e,t,o){let i=st;for(let n=t;n>>0}function dt(e){return"string"!=typeof e||0===e.length?st:pt(e,0,e.length)}function ut(e){const t=new Uint32Array(e.length);let o=0;for(const i of e)t[o++]=dt(i);return t}function ht(e,t){if(e.length=48&&e<=57}function gt(e){return e>=97&&e<=122||e>=65&&e<=90}function ft(e){return gt(e)||At(e)||37===e||function(e){return e>=192&&e<=450}(e)||function(e){return e>=1024&&e<=1279}(e)}function kt(e,t,o,i){const n=Math.min(e.length,2*i.remaining());let s=!1,c=0,r=st;for(let o=0;o1&&(!1===t||0!==c)&&i.push(r>>>0))}!0===s&&!1===o&&e.length-c>1&&!1===i.full()&&i.push(r>>>0)}function bt(e,t){const o=Math.min(e.length,2*t.remaining());let i=!1,n=0,s=st;for(let c=0;c1&&t.push(s>>>0))}!0===i&&e.length-n>1&&!1===t.full()&&t.push(s>>>0)}function yt(e,t){return-1!==function(e,t){if(0===e.length)return-1;let o=0,i=e.length-1;for(;o<=i;){const n=o+i>>>1,s=e[n];if(st))return n;i=n-1}}return-1}(e,t)}var wt=/[^\u0000-\u00ff]/;function vt(e){return wt.test(e)}var _t={extractHostname:!0,mixedInputs:!1,validateHostname:!1},Ct={beacon:dt("type:beacon"),cspReport:dt("type:csp"),csp_report:dt("type:csp"),cspviolationreport:dt("type:cspviolationreport"),document:dt("type:document"),eventsource:dt("type:other"),fetch:dt("type:xhr"),font:dt("type:font"),image:dt("type:image"),imageset:dt("type:image"),mainFrame:dt("type:document"),main_frame:dt("type:document"),manifest:dt("type:other"),media:dt("type:media"),object:dt("type:object"),object_subrequest:dt("type:object"),other:dt("type:other"),ping:dt("type:ping"),prefetch:dt("type:other"),preflight:dt("type:preflight"),script:dt("type:script"),signedexchange:dt("type:signedexchange"),speculative:dt("type:other"),stylesheet:dt("type:stylesheet"),subFrame:dt("type:subdocument"),sub_frame:dt("type:subdocument"),texttrack:dt("type:other"),webSocket:dt("type:websocket"),web_manifest:dt("type:other"),websocket:dt("type:websocket"),xhr:dt("type:xhr"),xml_dtd:dt("type:other"),xmlhttprequest:dt("type:xhr"),xslt:dt("type:other")};function xt(e){let t=st;for(let o=e.length-1;o>=0;o-=1)t=t*nt^e.charCodeAt(o);return t>>>0}function St(e,t,o){it.reset();let i=st;for(let n=t-1;n>=0;n-=1){const t=e.charCodeAt(n);46===t&&n>>0),i=i*nt^t}return it.push(i>>>0),it.slice()}function Et(e,t){const o=function(e,t){let o=null;const i=t.indexOf(".");if(-1!==i){const n=t.slice(i+1);o=e.slice(0,-n.length-1)}return o}(e,t);return null!==o?St(o,o.length,o.length):Y}function It(e,t){return St(e,e.length,e.length-t.length)}var Ft=class e{static fromRawDetails({requestId:t="0",tabId:o=0,url:i="",hostname:n,domain:s,sourceUrl:c="",sourceHostname:r,sourceDomain:a,type:l="main_frame",_originalRequestDetails:p}){if(i=i.toLowerCase(),void 0===n||void 0===s){const e=ot(i,_t);n=n||e.hostname||"",s=s||e.domain||""}if(void 0===r||void 0===a){const e=ot(r||a||c,_t);r=r||e.hostname||"",a=a||e.domain||r||""}return new e({requestId:t,tabId:o,domain:s,hostname:n,url:i,sourceDomain:a,sourceHostname:r,sourceUrl:c,type:l,_originalRequestDetails:p})}constructor({requestId:e,tabId:t,type:o,domain:i,hostname:n,url:s,sourceDomain:c,sourceHostname:r,_originalRequestDetails:a}){if(this.tokens=void 0,this.hostnameHashes=void 0,this.entityHashes=void 0,this._originalRequestDetails=a,this.id=e,this.tabId=t,this.type=o,this.url=s,this.hostname=n,this.domain=i,this.sourceHostnameHashes=0===r.length?Y:It(r,c),this.sourceEntityHashes=0===r.length?Y:Et(r,c),this.isThirdParty=function(e,t,o,i,n){return"main_frame"!==n&&"mainFrame"!==n&&(0!==t.length&&0!==i.length?t!==i:0!==t.length&&0!==o.length?t!==o:0!==i.length&&0!==e.length&&e!==i)}(n,i,r,c,o),this.isFirstParty=!this.isThirdParty,this.isSupported=!0,"websocket"===this.type||this.url.startsWith("ws:")||this.url.startsWith("wss:"))this.isHttp=!1,this.isHttps=!1,this.type="websocket",this.isSupported=!0;else if(this.url.startsWith("http:"))this.isHttp=!0,this.isHttps=!1;else if(this.url.startsWith("https:"))this.isHttps=!0,this.isHttp=!1;else if(this.url.startsWith("data:")){this.isHttp=!1,this.isHttps=!1;const e=this.url.indexOf(",");-1!==e&&(this.url=this.url.slice(0,e))}else this.isHttp=!1,this.isHttps=!1,this.isSupported=!1}getHostnameHashes(){return void 0===this.hostnameHashes&&(this.hostnameHashes=0===this.hostname.length?Y:It(this.hostname,this.domain)),this.hostnameHashes}getEntityHashes(){return void 0===this.entityHashes&&(this.entityHashes=0===this.hostname.length?Y:Et(this.hostname,this.domain)),this.entityHashes}getTokens(){if(void 0===this.tokens){it.reset();for(const e of this.sourceHostnameHashes)it.push(e);it.push(Ct[this.type]),bt(this.url,it),this.tokens=it.slice()}return this.tokens}isMainFrame(){return"main_frame"===this.type||"mainFrame"===this.type}isSubFrame(){return"sub_frame"===this.type||"subFrame"===this.type}guessTypeOfRequest(){const e=this.type;return this.type=function(e){const t=function(e){let t=e.length;const o=e.indexOf("#");-1!==o&&(t=o);const i=e.indexOf("?");-1!==i&&i=0&&(s=e.charCodeAt(n),0!=(s>=65&&s<=90||s>=97&&s<=122||s>=48&&s<=57));n-=1);return 46!==s||n<0||t-n>=10?"":e.slice(n+1,t)}(e);return He.has(t)||e.startsWith("data:image/")||e.startsWith("https://frog.wix.com/bt")?"image":We.has(t)||e.startsWith("data:audio/")||e.startsWith("data:video/")?"media":Ge.has(t)||e.startsWith("data:text/css")?"stylesheet":qe.has(t)||e.startsWith("data:")&&(e.startsWith("data:application/ecmascript")||e.startsWith("data:application/javascript")||e.startsWith("data:application/x-ecmascript")||e.startsWith("data:application/x-javascript")||e.startsWith("data:text/ecmascript")||e.startsWith("data:text/javascript")||e.startsWith("data:text/javascript1.0")||e.startsWith("data:text/javascript1.1")||e.startsWith("data:text/javascript1.2")||e.startsWith("data:text/javascript1.3")||e.startsWith("data:text/javascript1.4")||e.startsWith("data:text/javascript1.5")||e.startsWith("data:text/jscript")||e.startsWith("data:text/livescript")||e.startsWith("data:text/x-ecmascript")||e.startsWith("data:text/x-javascript"))||e.startsWith("https://maps.googleapis.com/maps/api/js")||e.startsWith("https://www.googletagmanager.com/gtag/js")?"script":Me.has(t)||e.startsWith("data:text/html")||e.startsWith("data:application/xhtml")||e.startsWith("https://www.youtube.com/embed/")||e.startsWith("https://www.google.com/gen_204")?"document":De.has(t)||e.startsWith("data:font/")?"font":"other"}(this.url),e!==this.type&&(this.tokens=void 0),this.type}},Tt=class e{static parse(t,o=!1){if(0===t.length)return;const i=[],n=[],s=[],c=[];for(let e of t){vt(e)&&(e=K(e));const t=126===e.charCodeAt(0),o=42===e.charCodeAt(e.length-1)&&46===e.charCodeAt(e.length-2),r=t?1:0,a=o?e.length-2:e.length,l=xt(!0===t||!0===o?e.slice(r,a):e);t?o?n.push(l):c.push(l):o?i.push(l):s.push(l)}return new e({entities:0!==i.length?new Uint32Array(i).sort():void 0,hostnames:0!==s.length?new Uint32Array(s).sort():void 0,notEntities:0!==n.length?new Uint32Array(n).sort():void 0,notHostnames:0!==c.length?new Uint32Array(c).sort():void 0,parts:!0===o?t.join(","):void 0})}static deserialize(t){const o=t.getUint8();return new e({entities:1&~o?void 0:t.getUint32Array(),hostnames:2&~o?void 0:t.getUint32Array(),notEntities:4&~o?void 0:t.getUint32Array(),notHostnames:8&~o?void 0:t.getUint32Array(),parts:16&~o?void 0:t.getUTF8()})}constructor({entities:e,hostnames:t,notEntities:o,notHostnames:i,parts:n}){this.entities=e,this.hostnames=t,this.notEntities=o,this.notHostnames=i,this.parts=n}updateId(e){const{hostnames:t,entities:o,notHostnames:i,notEntities:n}=this;if(void 0!==t)for(const o of t)e=e*nt^o;if(void 0!==o)for(const t of o)e=e*nt^t;if(void 0!==i)for(const t of i)e=e*nt^t;if(void 0!==n)for(const t of n)e=e*nt^t;return e}serialize(e){const t=e.getPos();e.pushUint8(0);let o=0;void 0!==this.entities&&(o|=1,e.pushUint32Array(this.entities)),void 0!==this.hostnames&&(o|=2,e.pushUint32Array(this.hostnames)),void 0!==this.notEntities&&(o|=4,e.pushUint32Array(this.notEntities)),void 0!==this.notHostnames&&(o|=8,e.pushUint32Array(this.notHostnames)),void 0!==this.parts&&(o|=16,e.pushUTF8(this.parts)),e.setByte(t,o)}getSerializedSize(){let e=1;return void 0!==this.entities&&(e+=ne(this.entities)),void 0!==this.hostnames&&(e+=ne(this.hostnames)),void 0!==this.notHostnames&&(e+=ne(this.notHostnames)),void 0!==this.notEntities&&(e+=ne(this.notEntities)),void 0!==this.parts&&(e+=ie(this.parts)),e}match(e,t){if(void 0!==this.notHostnames)for(const t of e)if(yt(this.notHostnames,t))return!1;if(void 0!==this.notEntities)for(const e of t)if(yt(this.notEntities,e))return!1;if(void 0!==this.hostnames||void 0!==this.entities){if(void 0!==this.hostnames)for(const t of e)if(yt(this.hostnames,t))return!0;if(void 0!==this.entities)for(const e of t)if(yt(this.entities,e))return!0;return!1}return!0}};function Ot(e){if(!1===e.startsWith("^script"))return;const t=":has-text(",o=[];let i=7;for(;e.startsWith(t,i);){i+=10;let t=1;const n=i;let s=-1;for(;i=48&&o<=57||o>=65&&o<=90||o>=97&&o<=122)){if(t{}},t=/^[#.]?[\w-.]+$/;return function(o){if(t.test(o))return!0;try{(t=>{e.matches(t)})(o)}catch(e){return!1}return!0}})();function Dt(e,t){const o=e.getSelector();if(!1===e.isScriptInject())return o;const i=e.parseScript();if(void 0===i)return o;const n=t(i.name);return void 0===n?o:o.replace(i.name,n)}(jt=Vt||(Vt={}))[jt.unhide=1]="unhide",jt[jt.scriptInject=2]="scriptInject",jt[jt.isUnicode=4]="isUnicode",jt[jt.isClassSelector=8]="isClassSelector",jt[jt.isIdSelector=16]="isIdSelector",jt[jt.isHrefSelector=32]="isHrefSelector",jt[jt.remove=64]="remove",jt[jt.extended=128]="extended";var Ht=class e{static parse(t,o=!1){const i=t;let n,s,c,r=0;const a=t.indexOf("#"),l=a+1;let p=l+1;if(t.length>l&&("@"===t[l]?(r=at(r,Vt.unhide),p+=1):"?"===t[l]&&(p+=1)),p>=t.length)return null;if(a>0&&(s=Tt.parse(t.slice(0,a).split(","),o)),t.endsWith(":remove()"))r=at(r,Vt.remove),r=at(r,Vt.extended),t=t.slice(0,-9);else if(t.length-p>=8&&t.endsWith(")")&&-1!==t.indexOf(":style(",p)){const e=t.indexOf(":style(",p);c=t.slice(e+7,-1),t=t.slice(0,e)}if(94===t.charCodeAt(p)){if(!1===mt(t,"script:has-text(",p+1)||41!==t.charCodeAt(t.length-1))return null;if(n=t.slice(p,t.length),void 0===Ot(n))return null}else if(t.length-p>4&&43===t.charCodeAt(p)&&mt(t,"+js(",p)){if((void 0===s||void 0===s.hostnames&&void 0===s.entities)&&!1===rt(r,Vt.unhide))return null;if(r=at(r,Vt.scriptInject),n=t.slice(p+4,t.length-1),!1===rt(r,Vt.unhide)&&0===n.length)return null}else{n=t.slice(p);const e=je(n);if(e===Le.Extended)r=at(r,Vt.extended);else if(e===Le.Invalid||!Mt(n))return null}if(void 0===s&&!0===rt(r,Vt.extended))return null;if(void 0!==n&&(vt(n)&&(r=at(r,Vt.isUnicode)),!1===rt(r,Vt.scriptInject)&&!1===rt(r,Vt.remove)&&!1===rt(r,Vt.extended)&&!1===n.startsWith("^"))){const e=n.charCodeAt(0),t=n.charCodeAt(1),o=n.charCodeAt(2);!1===rt(r,Vt.scriptInject)&&(46===e&&Ut(n)?r=at(r,Vt.isClassSelector):35===e&&Ut(n)?r=at(r,Vt.isIdSelector):(97===e&&91===t&&104===o&&Nt(n,2)||91===e&&104===t&&Nt(n,1))&&(r=at(r,Vt.isHrefSelector)))}return new e({mask:r,rawLine:!0===o?i:void 0,selector:n,style:c,domains:s})}static deserialize(t){const o=t.getUint8(),i=rt(o,Vt.isUnicode),n=t.getUint8(),s=i?t.getUTF8():t.getCosmeticSelector();return new e({mask:o,selector:s,domains:1&~n?void 0:Tt.deserialize(t),rawLine:2&~n?void 0:t.getRawCosmetic(),style:4&~n?void 0:t.getASCII()})}constructor({mask:e,selector:t,domains:o,rawLine:i,style:n}){this.mask=e,this.selector=t,this.domains=o,this.style=n,this.id=void 0,this.rawLine=i,this.scriptletDetails=void 0}isCosmeticFilter(){return!0}isNetworkFilter(){return!1}serialize(e){e.pushUint8(this.mask);const t=e.getPos();e.pushUint8(0),this.isUnicode()?e.pushUTF8(this.selector):e.pushCosmeticSelector(this.selector);let o=0;void 0!==this.domains&&(o|=1,this.domains.serialize(e)),void 0!==this.rawLine&&(o|=2,e.pushRawCosmetic(this.rawLine)),void 0!==this.style&&(o|=4,e.pushASCII(this.style)),e.setByte(t,o)}getSerializedSize(e){let t=2;return this.isUnicode()?t+=ie(this.selector):t+=function(e,t){return!0===t?te(Z().cosmeticSelector.getCompressedSize(e),!1):oe(e)}(this.selector,e),void 0!==this.domains&&(t+=this.domains.getSerializedSize()),void 0!==this.rawLine&&(t+=function(e,t){return!0===t?te(Z().cosmeticRaw.getCompressedSize($(e)),!1):ie(e)}(this.rawLine,e)),void 0!==this.style&&(t+=oe(this.style)),t}toString(){if(void 0!==this.rawLine)return this.rawLine;let e="";return void 0!==this.domains&&(void 0!==this.domains.parts?e+=this.domains.parts:e+=""),this.isUnhide()?e+="#@#":e+="##",this.isScriptInject()?(e+="+js(",e+=this.selector,e+=")"):e+=this.selector,e}match(e,t){return!1===this.hasHostnameConstraint()||!(!e&&this.hasHostnameConstraint())&&(void 0===this.domains||this.domains.match(0===e.length?Y:It(e,t),0===e.length?Y:Et(e,t)))}getTokens(){const e=[];if(void 0!==this.domains){const{hostnames:t,entities:o}=this.domains;if(void 0!==t)for(const o of t)e.push(new Uint32Array([o]));if(void 0!==o)for(const t of o)e.push(new Uint32Array([t]))}if(0===e.length&&!1===this.isUnhide())if(this.isIdSelector()||this.isClassSelector()){let t=1;const o=this.selector;for(;t0?n=!0:"'"===p&&e.indexOf("'",o+1)>0?s=!0:"{"===p&&e.indexOf("}",o+1)>0?r+=1:"/"===p&&e.indexOf("/",o+1)>0?c=!0:l=!0)),","===p&&(t.push(e.slice(i+1,o).trim()),i=o,l=!1))),a="\\"===p}if(t.push(e.slice(i+1).trim()),0===t.length)return;const p=t.slice(1).map((e=>e.startsWith("'")&&e.endsWith("'")||e.startsWith('"')&&e.endsWith('"')?e.substring(1,e.length-1):e)).map((e=>e.replace(zt,",").replace(Lt,"\\").replace(Bt,",")));return this.scriptletDetails={name:t[0],args:p},this.scriptletDetails}getScript(e){const t=this.parseScript();if(void 0===t)return;const{name:o,args:i}=t;let n=e(o);if(void 0!==n){for(let e=0;e>>0}(this.mask,this.selector,this.domains,this.style)),this.id}hasCustomStyle(){return void 0!==this.style}getStyle(e=Rt){return this.style||e}getStyleAttributeHash(){return`s${dt(this.getStyle())}`}getSelector(){return this.selector}getSelectorAST(){return ze(this.getSelector())}getExtendedSelector(){return Ot(this.selector)}isExtended(){return rt(this.mask,Vt.extended)}isRemove(){return rt(this.mask,Vt.remove)}isUnhide(){return rt(this.mask,Vt.unhide)}isScriptInject(){return rt(this.mask,Vt.scriptInject)}isCSS(){return!1===this.isScriptInject()}isIdSelector(){return rt(this.mask,Vt.isIdSelector)}isClassSelector(){return rt(this.mask,Vt.isClassSelector)}isHrefSelector(){return rt(this.mask,Vt.isHrefSelector)}isUnicode(){return rt(this.mask,Vt.isUnicode)}isHtmlFiltering(){return this.getSelector().startsWith("^")}isGenericHide(){var e,t;return void 0===(null===(e=null==this?void 0:this.domains)||void 0===e?void 0:e.hostnames)&&void 0===(null===(t=null==this?void 0:this.domains)||void 0===t?void 0:t.entities)}},Wt=class{constructor(){this.options=new Set,this.prefix=void 0,this.infix=void 0,this.suffix=void 0,this.redirect=void 0}blockRequestsWithType(e){if(this.options.has(e))throw new Error(`Already blocking type ${e}`);return this.options.add(e),this}images(){return this.blockRequestsWithType("image")}scripts(){return this.blockRequestsWithType("script")}frames(){return this.blockRequestsWithType("frame")}fonts(){return this.blockRequestsWithType("font")}medias(){return this.blockRequestsWithType("media")}styles(){return this.blockRequestsWithType("css")}redirectTo(e){if(void 0!==this.redirect)throw new Error(`Already redirecting: ${this.redirect}`);return this.redirect=`redirect=${e}`,this}urlContains(e){if(void 0!==this.infix)throw new Error(`Already matching pattern: ${this.infix}`);return this.infix=e,this}urlStartsWith(e){if(void 0!==this.prefix)throw new Error(`Already matching prefix: ${this.prefix}`);return this.prefix=`|${e}`,this}urlEndsWith(e){if(void 0!==this.suffix)throw new Error(`Already matching suffix: ${this.suffix}`);return this.suffix=`${e}|`,this}withHostname(e){if(void 0!==this.prefix)throw new Error(`Cannot match hostname if filter already has prefix: ${this.prefix}`);return this.prefix=`||${e}^`,this}toString(){const e=[];void 0!==this.prefix&&e.push(this.prefix),void 0!==this.infix&&e.push(this.infix),void 0!==this.suffix&&e.push(this.suffix);const t=["important"];if(0!==this.options.size)for(const e of this.options)t.push(e);return void 0!==this.redirect&&t.push(this.redirect),`${0===e.length?"*":e.join("*")}$${t.join(",")}`}};function qt(){return new Wt}var Gt,$t,Kt=dt("http"),Qt=dt("https");($t=Gt||(Gt={}))[$t.fromDocument=1]="fromDocument",$t[$t.fromFont=2]="fromFont",$t[$t.fromHttp=4]="fromHttp",$t[$t.fromHttps=8]="fromHttps",$t[$t.fromImage=16]="fromImage",$t[$t.fromMedia=32]="fromMedia",$t[$t.fromObject=64]="fromObject",$t[$t.fromOther=128]="fromOther",$t[$t.fromPing=256]="fromPing",$t[$t.fromScript=512]="fromScript",$t[$t.fromStylesheet=1024]="fromStylesheet",$t[$t.fromSubdocument=2048]="fromSubdocument",$t[$t.fromWebsocket=4096]="fromWebsocket",$t[$t.fromXmlHttpRequest=8192]="fromXmlHttpRequest",$t[$t.firstParty=16384]="firstParty",$t[$t.thirdParty=32768]="thirdParty",$t[$t.isReplace=65536]="isReplace",$t[$t.isBadFilter=131072]="isBadFilter",$t[$t.isCSP=262144]="isCSP",$t[$t.isGenericHide=524288]="isGenericHide",$t[$t.isImportant=1048576]="isImportant",$t[$t.isSpecificHide=2097152]="isSpecificHide",$t[$t.isFullRegex=4194304]="isFullRegex",$t[$t.isRegex=8388608]="isRegex",$t[$t.isUnicode=16777216]="isUnicode",$t[$t.isLeftAnchor=33554432]="isLeftAnchor",$t[$t.isRightAnchor=67108864]="isRightAnchor",$t[$t.isException=134217728]="isException",$t[$t.isHostnameAnchor=268435456]="isHostnameAnchor",$t[$t.isRedirectRule=536870912]="isRedirectRule",$t[$t.isRedirect=1073741824]="isRedirect";var Yt=Gt.fromDocument|Gt.fromFont|Gt.fromImage|Gt.fromMedia|Gt.fromObject|Gt.fromOther|Gt.fromPing|Gt.fromScript|Gt.fromStylesheet|Gt.fromSubdocument|Gt.fromWebsocket|Gt.fromXmlHttpRequest,Xt={beacon:Gt.fromPing,document:Gt.fromDocument,cspviolationreport:Gt.fromOther,fetch:Gt.fromXmlHttpRequest,font:Gt.fromFont,image:Gt.fromImage,imageset:Gt.fromImage,mainFrame:Gt.fromDocument,main_frame:Gt.fromDocument,media:Gt.fromMedia,object:Gt.fromObject,object_subrequest:Gt.fromObject,ping:Gt.fromPing,script:Gt.fromScript,stylesheet:Gt.fromStylesheet,subFrame:Gt.fromSubdocument,sub_frame:Gt.fromSubdocument,webSocket:Gt.fromWebsocket,websocket:Gt.fromWebsocket,xhr:Gt.fromXmlHttpRequest,xmlhttprequest:Gt.fromXmlHttpRequest,cspReport:Gt.fromOther,csp_report:Gt.fromOther,eventsource:Gt.fromOther,manifest:Gt.fromOther,other:Gt.fromOther,prefetch:Gt.fromOther,preflight:Gt.fromOther,signedexchange:Gt.fromOther,speculative:Gt.fromOther,texttrack:Gt.fromOther,web_manifest:Gt.fromOther,xml_dtd:Gt.fromOther,xslt:Gt.fromOther};function Zt(e){const t=[];return e.fromDocument()&&t.push("document"),e.fromImage()&&t.push("image"),e.fromMedia()&&t.push("media"),e.fromObject()&&t.push("object"),e.fromOther()&&t.push("other"),e.fromPing()&&t.push("ping"),e.fromScript()&&t.push("script"),e.fromStylesheet()&&t.push("stylesheet"),e.fromSubdocument()&&t.push("sub_frame"),e.fromWebsocket()&&t.push("websocket"),e.fromXmlHttpRequest()&&t.push("xhr"),e.fromFont()&&t.push("font"),t}function Jt(e,t,o,i,n,s){let c=185407^e;if(void 0!==i&&(c=i.updateId(c)),void 0!==n&&(c=n.updateId(c)),void 0!==t)for(let e=0;e>>0}function eo(e,t,o,i){return!0===i?new RegExp(e.slice(1,e.length-1),"i"):(e=(e=(e=e.replace(/([|.$+?{}()[\]\\])/g,"\\$1")).replace(/\*/g,".*")).replace(/\^/g,"(?:[^\\w\\d_.%-]|$)"),o&&(e=`${e}$`),t&&(e=`^${e}`),new RegExp(e))}function to(e,t,o){const i=t;for(;t=48&&e<=57||e<=65&&e<=70||e>=97&&e<=102}function so(e,t,o){const i=e.charCodeAt(t+1);return 44===i||47===i?[t+1,!1]:function(e,t){const o=e.charCodeAt(t+1);if(44===o||io.has(o))return[t+1,!0];if(99===o){const o=e.charCodeAt(t+2);if(o>=65&&o<=90||o>=97&&o<=122)return[t+2,!0]}if(120===o&&no(e.charCodeAt(t+2))&&no(e.charCodeAt(t+3)))return[t+3,!0];if(117===o)if(123===e.charCodeAt(t+2)){const o=e.indexOf("}",t+3),i=o-t+3;if(i>=1&&i<=6)return[o,!0]}else if(no(e.charCodeAt(t+2))&&no(e.charCodeAt(t+3))&&no(e.charCodeAt(t+4))&&no(e.charCodeAt(t+5)))return[t+5,!0];return[t+1,!1]}(e,t)}function co(e,t,o){if(47!==e.charCodeAt(t++))return[o,void 0];const i=["","",""];let n=t,s=0;for(;t0&&92===e.charCodeAt(o-1);)o=e.lastIndexOf(t,o-1);return o}(t,"$");if(-1!==u&&47!==t.charCodeAt(u+1)){d=u;for(const e of function(e,t,o){const i=[];let n,s;for(;t0&&(c=p);break;case"ehide":case"elemhide":if(t)return null;r=at(r,Gt.isGenericHide),r=at(r,Gt.isSpecificHide);break;case"shide":case"specifichide":if(t)return null;r=at(r,Gt.isSpecificHide);break;case"ghide":case"generichide":if(t)return null;r=at(r,Gt.isGenericHide);break;case"inline-script":if(t)return null;r=at(r,Gt.isCSP),c="script-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:";break;case"inline-font":if(t)return null;r=at(r,Gt.isCSP),c="font-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:";break;case"replace":case"content":if(t||(0===p.length?!1===rt(r,Gt.isException):null===ro(p)))return null;r=at(r,Gt.isReplace),c=p;break;default:{let e=0;switch(i){case"all":if(t)return null;break;case"image":e=Gt.fromImage;break;case"media":e=Gt.fromMedia;break;case"object":case"object-subrequest":e=Gt.fromObject;break;case"other":e=Gt.fromOther;break;case"ping":case"beacon":e=Gt.fromPing;break;case"script":e=Gt.fromScript;break;case"css":case"stylesheet":e=Gt.fromStylesheet;break;case"frame":case"subdocument":e=Gt.fromSubdocument;break;case"xhr":case"xmlhttprequest":e=Gt.fromXmlHttpRequest;break;case"websocket":e=Gt.fromWebsocket;break;case"font":e=Gt.fromFont;break;case"doc":case"document":e=Gt.fromDocument;break;default:return null}t?l=lt(l,e):a=at(a,e);break}}}}let h;if(r|=0===a?l:l===Yt?a:a&l,d-p>=2&&47===t.charCodeAt(p)&&47===t.charCodeAt(d-1)){h=t.slice(p,d);try{eo(h,!1,!1,!0)}catch(e){return null}r=at(r,Gt.isFullRegex)}else{if(d>0&&124===t.charCodeAt(d-1)&&(r=at(r,Gt.isRightAnchor),d-=1),p0&&42===t.charCodeAt(d-1)&&(d-=1),!1===rt(r,Gt.isHostnameAnchor)&&d-p>0&&42===t.charCodeAt(p)&&(r=lt(r,Gt.isLeftAnchor),p+=1),rt(r,Gt.isLeftAnchor)&&(d-p==5&&mt(t,"ws://",p)?(r=at(r,Gt.fromWebsocket),r=lt(r,Gt.isLeftAnchor),r=lt(r,Gt.fromHttp),r=lt(r,Gt.fromHttps),p=d):d-p==7&&mt(t,"http://",p)?(r=at(r,Gt.fromHttp),r=lt(r,Gt.fromHttps),r=lt(r,Gt.isLeftAnchor),p=d):d-p==8&&mt(t,"https://",p)?(r=at(r,Gt.fromHttps),r=lt(r,Gt.fromHttp),r=lt(r,Gt.isLeftAnchor),p=d):d-p==8&&mt(t,"http*://",p)&&(r=at(r,Gt.fromHttps),r=at(r,Gt.fromHttp),r=lt(r,Gt.isLeftAnchor),p=d)),d-p>0&&(h=t.slice(p,d).toLowerCase(),r=po(r,Gt.isUnicode,vt(h)),!1===rt(r,Gt.isRegex)&&(r=po(r,Gt.isRegex,function(e,t,o){const i=e.indexOf("^",t);if(-1!==i&&it.length)return!1;if(e.length===t.length)return e===t;const i=t.indexOf(e);if(-1===i)return!1;if(0===i)return!0===o||46===t.charCodeAt(e.length)||46===e.charCodeAt(e.length-1);if(t.length===i+e.length)return 46===t.charCodeAt(i-1)||46===e.charCodeAt(0);return!(!0!==o&&46!==t.charCodeAt(e.length)&&46!==e.charCodeAt(e.length-1)||46!==t.charCodeAt(i-1)&&46!==e.charCodeAt(0))}(i,t.hostname,void 0!==e.filter&&42===e.filter.charCodeAt(0)))return!1;if(e.isRegex())return e.getRegex().test(t.url.slice(t.url.indexOf(i)+i.length));if(e.isRightAnchor()&&e.isLeftAnchor()){return o===t.url.slice(t.url.indexOf(i)+i.length)}if(e.isRightAnchor()){const n=t.hostname;return!1===e.hasFilter()?i.length===n.length||n.endsWith(i):t.url.endsWith(o)}return e.isLeftAnchor()?mt(t.url,o,t.url.indexOf(i)+i.length):!1===e.hasFilter()||-1!==t.url.indexOf(o,t.url.indexOf(i)+i.length)}if(e.isRegex())return e.getRegex().test(t.url);if(e.isLeftAnchor()&&e.isRightAnchor())return t.url===o;if(e.isLeftAnchor())return ht(t.url,o);if(e.isRightAnchor())return t.url.endsWith(o);if(!1===e.hasFilter())return!0;return-1!==t.url.indexOf(o)}(this,e)}serialize(e){e.pushUint32(this.mask);const t=e.getPos();e.pushUint8(0);let o=0;void 0!==this.filter&&(o|=1,this.isUnicode()?e.pushUTF8(this.filter):e.pushNetworkFilter(this.filter)),void 0!==this.hostname&&(o|=2,e.pushNetworkHostname(this.hostname)),void 0!==this.domains&&(o|=4,this.domains.serialize(e)),void 0!==this.rawLine&&(o|=8,e.pushRawNetwork(this.rawLine)),void 0!==this.denyallow&&(o|=16,this.denyallow.serialize(e)),void 0!==this.optionValue&&(o|=32,this.isCSP()?e.pushNetworkCSP(this.optionValue):this.isRedirect()?e.pushNetworkRedirect(this.optionValue):e.pushUTF8(this.optionValue)),e.setByte(t,o)}getSerializedSize(e){let t=5;return void 0!==this.filter&&(!0===this.isUnicode()?t+=ie(this.filter):t+=function(e,t){return!0===t?te(Z().networkFilter.getCompressedSize(e),!1):oe(e)}(this.filter,e)),void 0!==this.hostname&&(t+=function(e,t){return!0===t?te(Z().networkHostname.getCompressedSize(e),!1):oe(e)}(this.hostname,e)),void 0!==this.domains&&(t+=this.domains.getSerializedSize()),void 0!==this.rawLine&&(t+=function(e,t){return!0===t?te(Z().networkRaw.getCompressedSize($(e)),!1):ie(e)}(this.rawLine,e)),void 0!==this.denyallow&&(t+=this.denyallow.getSerializedSize()),void 0!==this.optionValue&&(this.isCSP()?t+=function(e,t){return!0===t?te(Z().networkCSP.getCompressedSize(e),!1):oe(e)}(this.optionValue,e):this.isRedirect()?t+=function(e,t){return!0===t?te(Z().networkRedirect.getCompressedSize(e),!1):oe(e)}(this.optionValue,e):t+=ie(this.optionValue)),t}toString(e){if(void 0!==this.rawLine)return this.rawLine;let t="";this.isException()&&(t+="@@"),this.isHostnameAnchor()?t+="||":this.fromHttp()!==this.fromHttps()?this.fromHttp()?t+="|http://":t+="|https://":this.isLeftAnchor()&&(t+="|"),this.hasHostname()&&(t+=this.getHostname(),t+="^"),this.isFullRegex()?t+=`/${this.getRegex().source}/`:this.isRegex()?t+=this.getRegex().source:t+=this.getFilter(),this.isRightAnchor()&&"^"!==t[t.length-1]&&(t+="|");const o=[];if(!1===this.fromAny()){const e=ct(this.getCptMask());if(ct(Yt)-e")),void 0!==this.denyallow&&(void 0!==this.denyallow.parts?o.push(`denyallow=${this.denyallow.parts}`):o.push("denyallow=")),this.isBadFilter()&&o.push("badfilter"),o.length>0&&(t+="function"==typeof e?`$${o.map(e).join(",")}`:`$${o.join(",")}`),t}getIdWithoutBadFilter(){return Jt(this.mask&~Gt.isBadFilter,this.filter,this.hostname,this.domains,this.denyallow,this.optionValue)}getId(){return void 0===this.id&&(this.id=Jt(this.mask,this.filter,this.hostname,this.domains,this.denyallow,this.optionValue)),this.id}hasFilter(){return void 0!==this.filter}hasDomains(){return void 0!==this.domains}getMask(){return this.mask}getCptMask(){return this.getMask()&Yt}isRedirect(){return rt(this.getMask(),Gt.isRedirect)}isRedirectRule(){return rt(this.mask,Gt.isRedirectRule)}getRedirect(){var e;return null!==(e=this.optionValue)&&void 0!==e?e:""}isReplace(){return rt(this.getMask(),Gt.isReplace)}getHtmlModifier(){var e;return 0===(null===(e=this.optionValue)||void 0===e?void 0:e.length)?null:ro(this.optionValue)}isHtmlFilteringRule(){return this.isReplace()}getRedirectResource(){const e=this.getRedirect(),t=e.lastIndexOf(":");return-1===t?e:e.slice(0,t)}getRedirectPriority(){const e=this.getRedirect(),t=e.lastIndexOf(":");return-1===t?0:Number(e.slice(t+1))}hasHostname(){return void 0!==this.hostname}getHostname(){return this.hostname||""}getFilter(){return this.filter||""}getRegex(){return void 0===this.regex&&(this.regex=void 0!==this.filter&&this.isRegex()?eo(this.filter,this.isLeftAnchor(),this.isRightAnchor(),this.isFullRegex()):ao),this.regex}getTokens(){if(it.reset(),void 0!==this.domains&&void 0!==this.domains.hostnames&&void 0===this.domains.entities&&void 0===this.domains.notHostnames&&void 0===this.domains.notEntities&&1===this.domains.hostnames.length&&it.push(this.domains.hostnames[0]),!1===this.isFullRegex()){if(void 0!==this.filter){const e=!this.isRightAnchor(),t=!this.isLeftAnchor();!function(e,t,o,i){const n=Math.min(e.length,2*i.remaining());let s=!1,c=0,r=0,a=st;for(let o=0;o1&&42!==n&&42!==c&&(!1===t||0!==r)&&i.push(a>>>0)),c=n)}!1===o&&!0===s&&42!==c&&e.length-r>1&&!1===i.full()&&i.push(a>>>0)}(this.filter,t,e,it)}void 0!==this.hostname&&kt(this.hostname,!1,void 0!==this.filter&&42===this.filter.charCodeAt(0),it)}else void 0!==this.filter&&function(e,t){let o=e.length-1,i=1,n=0;for(;i=i;o-=1){const t=e.charCodeAt(o);if(124===t)return;if(41===t||42===t||43===t||63===t||93===t||125===t||46===t&&92!==e.charCodeAt(o-1)||92===t&>(n))break;n=t}if(o1&&kt(e.slice(1,i),94!==e.charCodeAt(1),!0,t),oObject.prototype.hasOwnProperty.call(yo,e),vo=(e,t)=>"true"===e&&!t.has("true")||!("false"===e&&!t.has("false"))&&!!t.get(e),_o=(e,t)=>{if(0===e.length)return!1;if((e=>bo.test(e))(e))return"!"===e[0]?!vo(e.slice(1),t):vo(e,t);const o=(e=>e.match(ko))(e);if(!o||0===o.length)return!1;if(e.length!==o.reduce(((e,t)=>e+t.length),0))return!1;const i=[],n=[];for(const e of o)if("("===e)n.push(e);else if(")"===e){for(;0!==n.length&&"("!==n[n.length-1];)i.push(n.pop());if(0===n.length)return!1;n.pop()}else if(wo(e)){for(;n.length&&wo(n[n.length-1])&&yo[e]<=yo[n[n.length-1]];)i.push(n.pop());n.push(e)}else i.push(vo(e,t));if("("===n[0]||")"===n[0])return!1;for(;0!==n.length;)i.push(n.pop());for(const e of i)if(!0===e||!1===e)n.push(e);else if("!"===e)n.push(!n.pop());else if(wo(e)){const t=n.pop(),o=n.pop();"&&"===e?n.push(o&&t):n.push(o||t)}return!0===n[0]},Co=class e{static getCondition(e){return e.slice(5).replace(/\s/g,"")}static parse(t,o){return new this({condition:e.getCondition(t),filterIDs:o})}static deserialize(e){const t=e.getUTF8(),o=new Set;for(let t=0,i=e.getUint32();t2)for(;e4&&32===t.charCodeAt(0)&&32===t.charCodeAt(1)&&32===t.charCodeAt(2)&&32===t.charCodeAt(3)&&32!==t.charCodeAt(4)))break;a+=t.slice(4),e+=1}0!==a.length&&a.charCodeAt(a.length-1)<=32&&(a=a.trim());const l=xo(a,{extendedNonSupportedTypes:!0});if(l===go.NETWORK&&!0===t.loadNetworkFilters){const i=lo.parse(a,t.debug);null!==i?(o.push(i),r.length>0&&r[r.length-1].filterIDs.add(i.getId())):n.push({lineNumber:e,filter:a,filterType:l})}else if(l===go.COSMETIC&&!0===t.loadCosmeticFilters){const o=Ht.parse(a,t.debug);null!==o?!0!==t.loadGenericCosmeticsFilters&&!1!==o.isGenericHide()||(i.push(o),r.length>0&&r[r.length-1].filterIDs.add(o.getId())):n.push({lineNumber:e,filter:a,filterType:go.COSMETIC})}else if(t.loadPreprocessors){const t=Ao(a);if(t===uo.BEGIF)r.length>0?r.push(new Co({condition:`(${r[r.length-1].condition})&&(${Co.getCondition(a)})`})):r.push(Co.parse(a));else if((t===uo.ENDIF||t===uo.ELSE)&&r.length>0){const e=r.pop();c.push(e),t===uo.ELSE&&r.push(new Co({condition:`!(${e.condition})`}))}else l===go.NOT_SUPPORTED_ADGUARD&&n.push({lineNumber:e,filter:a,filterType:l})}else l===go.NOT_SUPPORTED_ADGUARD&&n.push({lineNumber:e,filter:a,filterType:l})}return{networkFilters:o,cosmeticFilters:i,preprocessors:c.filter((e=>e.filterIDs.size>0)),notSupportedFilters:n}}(fo=go||(go={}))[fo.NOT_SUPPORTED=0]="NOT_SUPPORTED",fo[fo.NETWORK=1]="NETWORK",fo[fo.COSMETIC=2]="COSMETIC",fo[fo.NOT_SUPPORTED_EMPTY=100]="NOT_SUPPORTED_EMPTY",fo[fo.NOT_SUPPORTED_COMMENT=101]="NOT_SUPPORTED_COMMENT",fo[fo.NOT_SUPPORTED_ADGUARD=102]="NOT_SUPPORTED_ADGUARD";var Eo="video/flv",Io={contentType:`${Eo};base64`,aliases:[Eo,".flv","flv"],body:"RkxWAQEAAAAJAAAAABIAALgAAAAAAAAAAgAKb25NZXRhRGF0YQgAAAAIAAhkdXJhdGlvbgAAAAAAAAAAAAAFd2lkdGgAP/AAAAAAAAAABmhlaWdodAA/8AAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAaGoAAAAAAAAJZnJhbWVyYXRlAEBZAAAAAAAAAAx2aWRlb2NvZGVjaWQAQAAAAAAAAAAAB2VuY29kZXICAA1MYXZmNTcuNDEuMTAwAAhmaWxlc2l6ZQBAaoAAAAAAAAAACQAAAMM="},Fo="image/gif",To={contentType:`${Fo};base64`,aliases:[Fo,".gif","gif"],body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},Oo="text/html",Po={contentType:Oo,aliases:[Oo,".html","html",".htm","htm","noopframe","noop.html"],body:""},Ro="image/vnd.microsoft.icon",zo={contentType:`${Ro};base64`,aliases:[Ro,".ico","ico"],body:"AAABAAEAAQEAAAEAGAAwAAAAFgAAACgAAAABAAAAAgAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAA=="},Lo="image/jpeg",Bo={contentType:`${Lo};base64`,aliases:[Lo,".jpg","jpg",".jpeg","jpeg"],body:"/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k="},Uo="application/javascript",No={contentType:Uo,aliases:[Uo,".js","js","javascript",".jsx","jsx","typescript",".ts","ts","noop.js","noopjs"],body:""},Vo="application/json",jo={contentType:Vo,aliases:[Vo,".json","json"],body:"0"},Mo="audio/mpeg",Do={contentType:`${Mo};base64`,aliases:[Mo,".mp3","mp3","noop-0.1s.mp3","noopmp3-0.1s"],body:"/+MYxAAAAANIAAAAAExBTUUzLjk4LjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},Ho="video/mp4",Wo={contentType:`${Ho};base64`,aliases:[Ho,".mp4","mp4",".m4a","m4a",".m4p","m4p",".m4b","m4b",".m4r","m4r",".m4v","m4v","noop-1s.mp4","noopmp4-1s"],body:"AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="},qo="application/pdf",Go={contentType:`${qo};base64`,aliases:[qo,".pdf","pdf"],body:"JVBERi0xLgoxIDAgb2JqPDwvUGFnZXMgMiAwIFI+PmVuZG9iagoyIDAgb2JqPDwvS2lkc1szIDAgUl0vQ291bnQgMT4+ZW5kb2JqCjMgMCBvYmo8PC9QYXJlbnQgMiAwIFI+PmVuZG9iagp0cmFpbGVyIDw8L1Jvb3QgMSAwIFI+Pg=="},$o="image/png",Ko={contentType:`${$o};base64`,aliases:[$o,".png","png"],body:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="},Qo="image/svg+xml",Yo={contentType:Qo,aliases:[Qo,".svg","svg"],body:"https://raw.githubusercontent.com/mathiasbynens/small/master/svg.svg"},Xo="text/plain",Zo={contentType:Xo,aliases:[Xo,".txt","txt","text","nooptext","noop.txt"],body:""},Jo="audio/wav",ei={contentType:`${Jo};base64`,aliases:[Jo,".wav","wav"],body:"UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA="},ti="video/webm",oi={contentType:`${ti};base64`,aliases:[ti,".webm","webm"],body:"GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA="},ii="image/webp",ni={contentType:`${ii};base64`,aliases:[ii,".webp","webp"],body:"UklGRhIAAABXRUJQVlA4TAYAAAAvQWxvAGs="},si="video/wmv",ci={contentType:`${si};base64`,aliases:[si,".wmv","wmv"],body:"MCaydY5mzxGm2QCqAGLObOUBAAAAAAAABQAAAAECodyrjEepzxGO5ADADCBTZWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcCAAAAAAAAAIA+1d6xnQEAAAAAAAAAAMAF2QEAAAAAAAAAAAAAAAAcDAAAAAAAAAIAAACADAAAgAwAAEANAwC1A79fLqnPEY7jAMAMIFNlLgAAAAAAAAAR0tOruqnPEY7mAMAMIFNlBgAAAAAAQKTQ0gfj0hGX8ACgyV6oUGQAAAAAAAAAAQAoAFcATQAvAEUAbgBjAG8AZABpAG4AZwBTAGUAdAB0AGkAbgBnAHMAAAAAABwATABhAHYAZgA1ADcALgA0ADEALgAxADAAMAAAAJEH3Le3qc8RjuYAwAwgU2WBAAAAAAAAAMDvGbxNW88RqP0AgF9cRCsAV/sgVVvPEaj9AIBfXEQrAAAAAAAAAAAzAAAAAAAAAAEAAAAAAAEAAAABAAAAAigAKAAAAAEAAAABAAAAAQAYAE1QNDMDAAAAAAAAAAAAAAAAAAAAAAAAAEBS0YYdMdARo6QAoMkDSPZMAAAAAAAAAEFS0YYdMdARo6QAoMkDSPYBAAAAAQAKAG0AcwBtAHAAZQBnADQAdgAzAAAAAAAEAE1QNDM2JrJ1jmbPEabZAKoAYs5sMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQ=="},ri=(()=>{const e={};for(const t of[Io,To,Po,zo,Bo,No,jo,Do,Wo,Go,Ko,Yo,Zo,ei,oi,ni,ci])for(const o of t.aliases)e[o]=t;return e})();function ai(e){return ri[e]||Zo}function li(e){if(null===e)return!1;if("object"!=typeof e)return!1;const{name:t,aliases:o,body:i,contentType:n}=e;return"string"==typeof t&&(!(!Array.isArray(o)||!o.every((e=>"string"==typeof e)))&&("string"==typeof i&&"string"==typeof n))}function pi(e){if(null===e)return!1;if("object"!=typeof e)return!1;const{name:t,aliases:o,body:i,dependencies:n,executionWorld:s,requiresTrust:c}=e;return"string"==typeof t&&(!(!Array.isArray(o)||!o.every((e=>"string"==typeof e)))&&("string"==typeof i&&(!(!Array.isArray(n)||!n.every((e=>"string"==typeof e)))&&((void 0===s||"MAIN"===s||"ISOLATED"===s)&&(void 0===c||"boolean"==typeof c)))))}var di=class e{static deserialize(t){const o=t.getASCII(),i=[],n=[];for(let e=0,o=t.getUint16();e["if (typeof scriptletGlobals === 'undefined') { var scriptletGlobals = {}; }",...t,`(${e})(...['{{1}}','{{2}}','{{3}}','{{4}}','{{5}}','{{6}}','{{7}}','{{8}}','{{9}}','{{10}}'].filter((a,i) => a !== '{{'+(i+1)+'}}').map((a) => decodeURIComponent(a)))`].join(";"))(t.body,i),this.scriptletsCache.set(t.name,o),o}getSurrogate(e){const t=this.resourcesByName.get(e.endsWith(".js")?e:`${e}.js`);if(void 0!==t&&"application/javascript"===t.contentType)return t.body}getScriptletCanonicalName(e){var t;return null===(t=this.getRawScriptlet(e))||void 0===t?void 0:t.name}getRawScriptlet(e){if(!e.endsWith(".fn"))return this.scriptletsByName.get(e.endsWith(".js")?e:`${e}.js`)}getScriptletDependencies(e){const t=new Map,o=[...e.dependencies];for(;o.length>0;){const e=o.pop();if(t.has(e))continue;const i=this.scriptletsByName.get(e);t.set(e,i.body),o.push(...i.dependencies)}return Array.from(t.values())}getSerializedSize(){let e=oe(this.checksum);e+=2;for(const{name:t,aliases:o,body:i,contentType:n}of this.resources)e+=oe(t),e+=o.reduce(((e,t)=>e+oe(t)),2),e+=ie(i),e+=oe(n);e+=2;for(const{name:t,aliases:o,body:i,dependencies:n}of this.scriptlets)e+=oe(t),e+=o.reduce(((e,t)=>e+oe(t)),2),e+=ie(i),e+=1,e+=1,e+=1,e+=1,e+=n.reduce(((e,t)=>e+oe(t)),2);return e}serialize(e){e.pushASCII(this.checksum),e.pushUint16(this.resources.length);for(const{name:t,aliases:o,body:i,contentType:n}of this.resources){e.pushASCII(t),e.pushUint16(o.length);for(const t of o)e.pushASCII(t);e.pushUTF8(i),e.pushASCII(n)}e.pushUint16(this.scriptlets.length);for(const{name:t,aliases:o,body:i,dependencies:n,executionWorld:s,requiresTrust:c}of this.scriptlets){e.pushASCII(t),e.pushUint16(o.length);for(const t of o)e.pushASCII(t);e.pushUTF8(i),e.pushBool(void 0!==s),e.pushBool("ISOLATED"===s),e.pushBool(void 0!==c),e.pushBool(!0===c),e.pushUint16(n.length),n.forEach((t=>e.pushASCII(t)))}}};var ui=new Uint32Array(0);function hi(e){return`(?:${e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&")})`}function mi(e,t,o){let i=e.get(t);void 0===i&&(i=[],e.set(t,i)),i.push(o)}function Ai(e,t){const o=new Map;for(const i of e)mi(o,t(i),i);return Array.from(o.values())}function gi(e,t){const o=[],i=[];for(const n of e)t(n)?o.push(n):i.push(n);return{negative:i,positive:o}}var fi=[{description:"Remove duplicated filters by ID",fusion:e=>e[0],groupByCriteria:e=>""+e.getId(),select:()=>!0},{description:"Group idential filter with same mask but different domains in single filters",fusion:e=>{const t=[],o=new Set,i=new Set,n=new Set,s=new Set;for(const{domains:c}of e)if(void 0!==c){if(void 0!==c.parts&&t.push(c.parts),void 0!==c.hostnames)for(const e of c.hostnames)o.add(e);if(void 0!==c.entities)for(const e of c.entities)n.add(e);if(void 0!==c.notHostnames)for(const e of c.notHostnames)i.add(e);if(void 0!==c.notEntities)for(const e of c.notEntities)s.add(e)}return new lo(Object.assign({},e[0],{domains:new Tt({hostnames:0!==o.size?new Uint32Array(o).sort():void 0,entities:0!==n.size?new Uint32Array(n).sort():void 0,notHostnames:0!==i.size?new Uint32Array(i).sort():void 0,notEntities:0!==s.size?new Uint32Array(s).sort():void 0,parts:0!==t.length?t.join(","):void 0}),rawLine:void 0!==e[0].rawLine?e.map((({rawLine:e})=>e)).join(" <+> "):void 0}))},groupByCriteria:e=>{var t;return e.getHostname()+e.getFilter()+e.getMask()+(null!==(t=e.optionValue)&&void 0!==t?t:"")},select:e=>!e.isCSP()&&void 0===e.denyallow&&void 0!==e.domains},{description:"Group simple patterns, into a single filter",fusion:e=>{const t=[];for(const o of e)o.isRegex()?t.push(`(?:${o.getRegex().source})`):o.isRightAnchor()?t.push(`${hi(o.getFilter())}$`):o.isLeftAnchor()?t.push(`^${hi(o.getFilter())}`):t.push(hi(o.getFilter()));return new lo(Object.assign({},e[0],{mask:at(e[0].mask,Gt.isRegex),rawLine:void 0!==e[0].rawLine?e.map((({rawLine:e})=>e)).join(" <+> "):void 0,regex:new RegExp(t.join("|"))}))},groupByCriteria:e=>""+(e.getMask()&~Gt.isRegex&~Gt.isFullRegex),select:e=>void 0===e.domains&&void 0===e.denyallow&&!e.isHostnameAnchor()&&!e.isRedirect()&&!e.isCSP()}];function ki(e){return e}function bi(e){return e}function yi(e){const t=[];let o=e;for(const{select:e,fusion:i,groupByCriteria:n}of fi){const{positive:s,negative:c}=gi(o,e);o=c;const r=Ai(s,n);for(const e of r)e.length>1?t.push(i(e)):o.push(e[0])}for(const e of o)t.push(e);return t}function wi(e){return e--,e|=e>>1,e|=e>>2,e|=e>>4,e|=e>>8,e|=e>>16,++e}var vi=1;var _i=Number.MAX_SAFE_INTEGER>>>0,Ci=class e{static deserialize(t,o,i,n){const s=t.getUint32(),c=t.getUint32(),r=t.getUint32(),a=ce.fromUint8Array(t.getBytes(!0),n),l=a.getUint32ArrayView(s),p=a.getUint32ArrayView(c),d=a.pos;return a.seekZero(),new e({config:n,deserialize:o,filters:[],optimize:i}).updateInternals({bucketsIndex:p,filtersIndexStart:d,numberOfFilters:r,tokensLookupIndex:l,view:a})}constructor({deserialize:e,filters:t,optimize:o,config:i}){this.bucketsIndex=Y,this.filtersIndexStart=0,this.numberOfFilters=0,this.tokensLookupIndex=Y,this.cache=new Map,this.view=ce.empty(i),this.deserializeFilter=e,this.optimize=o,this.config=i,0!==t.length&&this.update(t,void 0)}getFilters(){const e=[];if(0===this.numberOfFilters)return e;this.view.setPos(this.filtersIndexStart);for(let t=0;t!t.has(e.getId())||(r-=e.getSerializedSize(o),!1))));for(const t of e)r+=t.getSerializedSize(o),a.push(t)}else{a=e;for(const t of e)r+=t.getSerializedSize(o)}if(0===a.length)return void this.updateInternals({bucketsIndex:Y,filtersIndexStart:0,numberOfFilters:0,tokensLookupIndex:Y,view:ce.empty(this.config)});!0===this.config.debug&&a.sort(((e,t)=>e.getId()-t.getId()));const l=new Uint32Array(Math.max(wi(2*a.length),256));for(const e of a){const t=e.getTokens();s.push(t),c+=2*t.length,n+=t.length;for(const e of t){i+=e.length;for(const t of e)l[t%l.length]+=1}}r+=4*c;const p=Math.max(2,wi(n)),d=p-1,u=[];for(let e=0;e1?this.optimize(c):c,lastRequestSeen:-1},!0===this.config.enableInMemoryCache&&this.cache.set(e,i)}if(i.lastRequestSeen!==t){i.lastRequestSeen=t;const e=i.filters;for(let t=0;t0){const o=e[t];e[t]=e[t-1],e[t-1]=o}return!1}}return!0}},xi=new Uint8Array(4),Si=class e{static deserialize(t,o,i){const n=new e({deserialize:o,config:i,filters:[]});return n.filters=t.getBytes(),n}constructor({config:e,deserialize:t,filters:o}){this.deserialize=t,this.filters=xi,this.config=e,0!==o.length&&this.update(o,void 0)}update(e,t){let o=this.filters.byteLength,i=[];const n=this.config.enableCompression,s=this.getFilters();if(0!==s.length)if(void 0===t||0===t.size)i=s;else for(const e of s)!1===t.has(e.getId())?i.push(e):o-=e.getSerializedSize(n);const c=i.length!==s.length,r=i.length;for(const t of e)o+=t.getSerializedSize(n),i.push(t);const a=i.length>r;if(0===i.length)this.filters=xi;else if(!0===a||!0===c){const e=ce.allocate(o,this.config);e.pushUint32(i.length),!0===this.config.debug&&i.sort(((e,t)=>e.getId()-t.getId()));for(const t of i)t.serialize(e);this.filters=e.buffer}}getSerializedSize(){return ee(this.filters,!1)}serialize(e){e.pushBytes(this.filters)}getFilters(){if(this.filters.byteLength<=4)return[];const e=[],t=ce.fromUint8Array(this.filters,this.config),o=t.getUint32();for(let i=0;i(!0!==c&&!0!==o.isScriptInject()||!o.match(t,e)||(null==p?void 0:p(o))||u.push(o),!0))),!0===s&&!0===a){const o=this.getGenericRules(l);for(const i of o)!0!==i.match(t,e)||(null==p?void 0:p(i))||u.push(i)}!0===s&&!0===r&&0!==o.length&&this.classesIndex.iterMatchingFilters(ut(o),(o=>(o.match(t,e)&&!(null==p?void 0:p(o))&&u.push(o),!0))),!0===s&&!0===r&&0!==n.length&&this.idsIndex.iterMatchingFilters(ut(n),(o=>(o.match(t,e)&&!(null==p?void 0:p(o))&&u.push(o),!0))),!0===s&&!0===r&&0!==i.length&&this.hrefsIndex.iterMatchingFilters(function(e){const t=e.sort();let o=1;for(let e=1;e{return t=e,it.reset(),bt(t,it),it.slice();var t})))),(o=>(o.match(t,e)&&!(null==p?void 0:p(o))&&u.push(o),!0)));const h=[];return 0!==u.length&&this.unhideIndex.iterMatchingFilters(d,(o=>(o.match(t,e)&&!(null==p?void 0:p(o))&&h.push(o),!0))),{filters:u,unhides:h}}getStylesheetsFromFilters({filters:e,extendedFilters:t},{getBaseRules:o,allowGenericHides:i,hidingStyle:n=Rt}){let s=!1===o||!1===i?"":this.getBaseStylesheet(n);0!==e.length&&(0!==s.length&&(s+="\n\n"),s+=Fi(e,n));const c=[];if(0!==t.length){const e=new Map;for(const o of t){const t=o.getSelectorAST();if(void 0!==t){const i=o.isRemove()?void 0:o.getStyleAttributeHash();void 0!==i&&e.set(o.getStyle(n),i),c.push({ast:t,remove:o.isRemove(),attribute:i})}}0!==e.size&&(0!==s.length&&(s+="\n\n"),s+=[...e.entries()].map((([e,t])=>`[${t}] { ${e} }`)).join("\n\n"))}return{stylesheet:s,extended:c}}getGenericRules(e){return null===this.extraGenericRules?this.lazyPopulateGenericRulesCache(e).genericRules:this.extraGenericRules}getBaseStylesheet(e){return null===this.baseStylesheet?this.lazyPopulateGenericRulesCache(e).baseStylesheet:this.baseStylesheet}lazyPopulateGenericRulesCache(e){if(null===this.baseStylesheet||null===this.extraGenericRules){const t=this.unhideIndex.getFilters(),o=new Set;for(const e of t)o.add(e.getSelector());const i=this.genericRules.getFilters(),n=[],s=[];for(const e of i)e.hasCustomStyle()||e.isScriptInject()||e.hasHostnameConstraint()||o.has(e.getSelector())?s.push(e):n.push(e);this.baseStylesheet=Fi(n,e),this.extraGenericRules=s}return{baseStylesheet:this.baseStylesheet,genericRules:this.extraGenericRules}}},Pi=class e{static deserialize(t,o){const i=new e({config:o});return i.index=Ci.deserialize(t,lo.deserialize,o.enableOptimizations?yi:ki,o),i.badFilters=Si.deserialize(t,lo.deserialize,o),i}constructor({filters:e=[],config:t}){this.index=new Ci({config:t,deserialize:lo.deserialize,filters:[],optimize:t.enableOptimizations?yi:ki}),this.badFiltersIds=null,this.badFilters=new Si({config:t,deserialize:lo.deserialize,filters:[]}),0!==e.length&&this.update(e,void 0)}getFilters(){return[].concat(this.badFilters.getFilters(),this.index.getFilters())}update(e,t){const o=[],i=[];for(const t of e)t.isBadFilter()?o.push(t):i.push(t);this.badFilters.update(o,t),this.index.update(i,t),this.badFiltersIds=null}getSerializedSize(){return this.badFilters.getSerializedSize()+this.index.getSerializedSize()}serialize(e){this.index.serialize(e),this.badFilters.serialize(e)}matchAll(e,t){const o=[];return this.index.iterMatchingFilters(e.getTokens(),(i=>(i.match(e)&&!1===this.isFilterDisabled(i)&&!(null==t?void 0:t(i))&&o.push(i),!0))),o}match(e,t){let o;return this.index.iterMatchingFilters(e.getTokens(),(i=>!(i.match(e)&&!1===this.isFilterDisabled(i)&&!(null==t?void 0:t(i)))||(o=i,!1))),o}isFilterDisabled(e){if(null===this.badFiltersIds){const e=this.badFilters.getFilters();if(0===e.length)return!1;const t=new Set;for(const o of e)t.add(o.getIdWithoutBadFilter());this.badFiltersIds=t}return this.badFiltersIds.has(e.getId())}},Ri=class e{static deserialize(t,o){const i=new e({config:o});return i.networkIndex=Ci.deserialize(t,lo.deserialize,o.enableOptimizations?yi:ki,o),i.exceptionsIndex=Ci.deserialize(t,lo.deserialize,o.enableOptimizations?yi:ki,o),i.cosmeticIndex=Ci.deserialize(t,Ht.deserialize,bi,o),i.unhideIndex=Ci.deserialize(t,Ht.deserialize,bi,o),i}constructor({filters:e=[],config:t}){this.config=t,this.networkIndex=new Ci({config:t,deserialize:lo.deserialize,filters:[],optimize:t.enableOptimizations?yi:ki}),this.exceptionsIndex=new Ci({config:t,deserialize:lo.deserialize,filters:[],optimize:t.enableOptimizations?yi:ki}),this.cosmeticIndex=new Ci({config:t,deserialize:Ht.deserialize,filters:[],optimize:bi}),this.unhideIndex=new Ci({config:t,deserialize:Ht.deserialize,filters:[],optimize:bi}),0!==e.length&&this.update(e,void 0)}update(e,t){const o=[],i=[],n=[],s=[];for(const t of e)t.isNetworkFilter()?t.isException()?i.push(t):o.push(t):t.isCosmeticFilter()&&(t.isUnhide()?s.push(t):n.push(t));this.networkIndex.update(o,t),this.exceptionsIndex.update(i,t),this.cosmeticIndex.update(n,t),this.unhideIndex.update(s,t)}serialize(e){this.networkIndex.serialize(e),this.exceptionsIndex.serialize(e),this.cosmeticIndex.serialize(e),this.unhideIndex.serialize(e)}getSerializedSize(){return this.networkIndex.getSerializedSize()+this.exceptionsIndex.getSerializedSize()+this.cosmeticIndex.getSerializedSize()+this.unhideIndex.getSerializedSize()}getHTMLFilters(e,t){const o=[],i=[],n=[],s=[];if(!0===this.config.loadNetworkFilters&&this.networkIndex.iterMatchingFilters(e.getTokens(),(i=>(i.match(e)&&!(null==t?void 0:t(i))&&o.push(i),!0))),0!==o.length&&this.exceptionsIndex.iterMatchingFilters(e.getTokens(),(o=>(o.match(e)&&!(null==t?void 0:t(o))&&n.push(o),!0))),!0===this.config.loadCosmeticFilters&&e.isMainFrame()){const{hostname:o,domain:n=""}=e,c=Ti(o,n);this.cosmeticIndex.iterMatchingFilters(c,(e=>(e.match(o,n)&&!(null==t?void 0:t(e))&&i.push(e),!0))),0!==i.length&&this.unhideIndex.iterMatchingFilters(c,(e=>(e.match(o,n)&&!(null==t?void 0:t(e))&&s.push(e),!0)))}return{networkFilters:o,cosmeticFilters:i,unhides:s,exceptions:n}}getFilters(){return[].concat(this.networkIndex.getFilters(),this.exceptionsIndex.getFilters(),this.cosmeticIndex.getFilters(),this.unhideIndex.getFilters())}},zi=Number.MAX_SAFE_INTEGER>>>0,Li=class e{static deserialize(t,o){const i=t.getUint32(),n=t.getUint32(),s=t.getUint32(),c=ce.fromUint8Array(t.getBytes(!0),{enableCompression:!1}),r=c.getUint32ArrayView(i),a=c.getUint32ArrayView(n),l=c.pos;return c.seekZero(),new e({deserialize:o,values:[],getKeys:()=>[],getSerializedSize:()=>0,serialize:()=>{}}).updateInternals({bucketsIndex:a,valuesIndexStart:l,numberOfValues:s,tokensLookupIndex:r,view:c})}constructor({serialize:e,deserialize:t,getKeys:o,getSerializedSize:i,values:n}){if(this.cache=new Map,this.bucketsIndex=Y,this.tokensLookupIndex=Y,this.valuesIndexStart=0,this.numberOfValues=0,this.view=ce.empty({enableCompression:!1}),this.deserializeValue=t,0!==n.length){const t=[];let s=0,c=0;for(const e of n)c+=i(e);if(0===n.length)return void this.updateInternals({bucketsIndex:Y,valuesIndexStart:0,numberOfValues:0,tokensLookupIndex:Y,view:ce.empty({enableCompression:!1})});for(const e of n){const i=o(e);t.push(i),s+=2*i.length}c+=4*s;const r=Math.max(2,wi(n.length)),a=r-1,l=[];for(let e=0;e[Ui(e)],serialize:Vi,deserialize:ji,values:e})}function Di(e){if(null===e)return!1;if("object"!=typeof e)return!1;const{key:t,name:o,description:i,country:n,website_url:s,privacy_policy_url:c,privacy_contact:r,ghostery_id:a}=e;return"string"==typeof t&&("string"==typeof o&&((null===i||"string"==typeof i)&&((null===n||"string"==typeof n)&&((null===s||"string"==typeof s)&&((null===c||"string"==typeof c)&&((null===r||"string"==typeof r)&&(null===a||"string"==typeof a)))))))}function Hi(e){return dt(e.key)}function Wi(e){return ie(e.key)+ie(e.name)+ie(e.description||"")+ie(e.website_url||"")+ie(e.country||"")+ie(e.privacy_policy_url||"")+ie(e.privacy_contact||"")+ie(e.ghostery_id||"")}function qi(e,t){t.pushUTF8(e.key),t.pushUTF8(e.name),t.pushUTF8(e.description||""),t.pushUTF8(e.website_url||""),t.pushUTF8(e.country||""),t.pushUTF8(e.privacy_policy_url||""),t.pushUTF8(e.privacy_contact||""),t.pushUTF8(e.ghostery_id||"")}function Gi(e){return{key:e.getUTF8(),name:e.getUTF8(),description:e.getUTF8()||null,website_url:e.getUTF8()||null,country:e.getUTF8()||null,privacy_policy_url:e.getUTF8()||null,privacy_contact:e.getUTF8()||null,ghostery_id:e.getUTF8()||null}}function $i(e){return new Li({getSerializedSize:Wi,getKeys:e=>[Hi(e)],serialize:qi,deserialize:Gi,values:e})}function Ki(e){if(null===e)return!1;if("object"!=typeof e)return!1;const{key:t,name:o,category:i,organization:n,alias:s,website_url:c,domains:r,filters:a}=e;return"string"==typeof t&&("string"==typeof o&&("string"==typeof i&&((null===n||"string"==typeof n)&&(("string"==typeof s||null===s)&&((null===c||"string"==typeof c)&&(!(!Array.isArray(r)||!r.every((e=>"string"==typeof e)))&&!(!Array.isArray(a)||!a.every((e=>"string"==typeof e)))))))))}function Qi(e){const t=[];for(const o of e.filters){const e=lo.parse(o);null!==e&&t.push(e.getId())}for(const o of e.domains){const e=lo.parse(`||${o}^`);null!==e&&t.push(e.getId())}return[...new Set(t)]}function Yi(e){let t=J(e.domains.length);for(const o of e.domains)t+=ie(o);let o=J(e.filters.length);for(const t of e.filters)o+=ie(t);return ie(e.key)+ie(e.name)+ie(e.category)+ie(e.organization||"")+ie(e.alias||"")+ie(e.website_url||"")+ie(e.ghostery_id||"")+t+o}function Xi(e,t){t.pushUTF8(e.key),t.pushUTF8(e.name),t.pushUTF8(e.category),t.pushUTF8(e.organization||""),t.pushUTF8(e.alias||""),t.pushUTF8(e.website_url||""),t.pushUTF8(e.ghostery_id||""),t.pushLength(e.domains.length);for(const o of e.domains)t.pushUTF8(o);t.pushLength(e.filters.length);for(const o of e.filters)t.pushUTF8(o)}function Zi(e){const t=e.getUTF8(),o=e.getUTF8(),i=e.getUTF8(),n=e.getUTF8()||null,s=e.getUTF8()||null,c=e.getUTF8()||null,r=e.getUTF8()||null,a=e.getLength(),l=[];for(let t=0;t=2;t.shift()){const e=t.join("."),o=lo.parse(`||${e}^`);if(null===o)continue;const i=this.fromId(o.getId());if(i.length>0)return i}return[]}fromId(e){var t,o;const i=[];for(const n of this.patterns.get(e))i.push({pattern:n,category:null===(t=this.categories.get(Ui({key:n.category})))||void 0===t?void 0:t[0],organization:null!==n.organization?null===(o=this.organizations.get(Hi({key:n.organization})))||void 0===o?void 0:o[0]:null});return i}},tn=class{static deserialize(e){const t=new Set;for(let o=0,i=e.getUint32();ot.condition===e.condition));if(t)for(const o of e.filterIDs)t.filterIDs.delete(o)}if(e)for(const t of e){const e=this.preprocessors.find((e=>e.condition===t.condition));if(e)for(const o of t.filterIDs)e.filterIDs.add(o);else this.preprocessors.push(t)}(t&&0!==t.length||e&&0!==e.length)&&this.updateEnv(o)}serialize(e){e.pushUint32(this.excluded.size);for(const t of this.excluded)e.pushUint32(t);e.pushUint32(this.preprocessors.length);for(const t of this.preprocessors)t.serialize(e)}getSerializedSize(){let e=4*(1+this.excluded.size);e+=4;for(const t of this.preprocessors)e+=t.getSerializedSize();return e}};function on(e){if(0===e.length)return!1;let t,o=0;for(const i of e){const e=(i.isImportant()?4:0)|(i.isException()?1:2);e>=o&&(o=e,t=i)}return void 0!==t&&t.isException()}var nn=class extends ue{static fromCached(e,t){if(void 0===t)return e();const{path:o,read:i,write:n}=t;return i(o).then((e=>this.deserialize(e))).catch((()=>e().then((e=>n(o,e.serialize()).then((()=>e))))))}static empty(e={}){return new this({config:e})}static fromLists(e,t,o={},i){return this.fromCached((()=>{const i=function(e,t){return Promise.all(t.map((t=>he(e,t))))}(e,t),n=function(e){return he(e,`${me}/ublock-origin/resources.json`)}(e);return Promise.all([i,n]).then((([e,t])=>{const i=this.parse(e.join("\n"),o);return void 0!==t&&i.updateResources(t,""+t.length),i}))}),i)}static fromPrebuiltAdsOnly(e=fetch,t){return this.fromLists(e,Ae,{},t)}static fromPrebuiltAdsAndTracking(e=fetch,t){return this.fromLists(e,ge,{},t)}static fromPrebuiltFull(e=fetch,t){return this.fromLists(e,fe,{},t)}static fromTrackerDB(e,t={}){const o=new re(t),i=new en(e),n=[];for(const e of i.getPatterns())n.push(...e.filters);const s=this.parse(n.join("\n"),o);return s.metadata=i,s}static merge(e,{skipResources:t=!1}={}){if(!e||e.length<2)throw new Error("merging engines requires at least two engines");const o=e[0].config,i=new Map,n=new Map,s=new Map,c=[],r={organizations:{},categories:{},patterns:{}},a=[],l=Object.keys(o).filter((function(e){return"boolean"==typeof o[e]&&!a.includes(e)}));for(const t of e){for(const e of l)if(o[e]!==t.config[e])throw new Error(`config "${e}" of all merged engines must be the same`);const e=t.getFilters();for(const t of e.networkFilters)n.set(t.getId(),t);for(const t of e.cosmeticFilters)s.set(t.getId(),t);for(const e of t.preprocessors.preprocessors)c.push(e);for(const[e,o]of t.lists)i.has(e)||i.set(e,o);if(void 0!==t.metadata){for(const e of t.metadata.organizations.getValues())void 0===r.organizations[e.key]&&(r.organizations[e.key]=e);for(const e of t.metadata.categories.getValues())void 0===r.categories[e.key]&&(r.categories[e.key]=e);for(const e of t.metadata.patterns.getValues())void 0===r.patterns[e.key]&&(r.patterns[e.key]=e)}}const p=new this({networkFilters:Array.from(n.values()),cosmeticFilters:Array.from(s.values()),preprocessors:c,lists:i,config:o});if(Object.keys(r.categories).length+Object.keys(r.organizations).length+Object.keys(r.patterns).length!==0&&(p.metadata=new en(r)),!0!==t){for(const t of e.slice(1))if(t.resources.checksum!==e[0].resources.checksum)throw new Error(`resource checksum of all merged engines must match with the first one: "${e[0].resources.checksum}" but got: "${t.resources.checksum}"`);p.resources=di.copy(e[0].resources)}return p}static parse(e,t={}){const o=new re(t);return new this({...So(e,o),config:o})}static deserialize(e){const t=ce.fromUint8Array(e,{enableCompression:!1}),o=t.getUint16();if(699!==o)throw new Error(`serialized engine version mismatch, expected 699 but got ${o}`);const i=re.deserialize(t);if(i.enableCompression&&t.enableCompression(),i.integrityCheck){const o=t.pos;t.pos=e.length-4;const i=t.checksum(),n=t.getUint32();if(i!==n)throw new Error(`serialized engine checksum mismatch, expected ${n} but got ${i}`);t.pos=o}const n=new this({config:i});n.resources=di.deserialize(t);const s=new Map,c=t.getUint16();for(let e=0;ee.getId()))).concat(o.map((e=>e.getId()))));l.push(new Co({condition:e,filterIDs:n}))}if(void 0!==t.added&&0!==t.added.length){const{networkFilters:o,cosmeticFilters:i}=So(t.added.join("\n"),this.config),n=new Set([].concat(i.map((e=>e.getId()))).concat(o.map((e=>e.getId()))));c.push(new Co({condition:e,filterIDs:n}))}}return this.update({newCosmeticFilters:n,newNetworkFilters:s,newPreprocessors:c,removedCosmeticFilters:r.map((e=>e.getId())),removedNetworkFilters:a.map((e=>e.getId())),removedPreprocessors:l},i)}getHtmlFilters(e){const t=[];if(!1===this.config.enableHtmlFiltering)return t;const{networkFilters:o,exceptions:i,cosmeticFilters:n,unhides:s}=this.htmlFilters.getHTMLFilters(e,this.isFilterExcluded.bind(this));if(0!==n.length){const o=new Map(s.map((e=>[e.getSelector(),e])));for(const i of n){const n=i.getExtendedSelector();if(void 0===n)continue;const s=o.get(i.getSelector());void 0===s&&t.push(n),this.emit("filter-matched",{filter:i,exception:s},{request:e,filterType:go.COSMETIC})}}if(0!==o.length){const n=new Map;let s;for(const e of i){const t=e.optionValue;if(""===t){s=e;break}n.set(t,e)}for(const i of o){const o=i.getHtmlModifier();if(null===o)continue;const c=s||n.get(i.optionValue);this.emit("filter-matched",{filter:i,exception:c},{request:e,filterType:go.NETWORK}),void 0===c&&t.push(["replace",o])}}return 0!==t.length&&this.emit("html-filtered",t,e.url),t}getCosmeticsFilters({url:e,hostname:t,domain:o,classes:i,hrefs:n,ids:s,getBaseRules:c=!0,getInjectionRules:r=!0,getExtendedRules:a=!0,getRulesFromDOM:l=!0,getRulesFromHostname:p=!0,hidingStyle:d,callerContext:u}){if(!1===this.config.loadCosmeticFilters)return{active:!1,extended:[],scripts:[],styles:""};o||(o="");let h=!0,m=!0;const A=this.hideExceptions.matchAll(Ft.fromRawDetails({domain:o,hostname:t,url:e,sourceDomain:"",sourceHostname:"",sourceUrl:""}),this.isFilterExcluded.bind(this)),g=[],f=[];for(const e of A){if(e.isElemHide()){h=!1,m=!1;break}e.isSpecificHide()?f.push(e):e.isGenericHide()&&g.push(e)}!0===h&&(h=!1===on(g)),!0===m&&(m=!1===on(f));const{filters:k,unhides:b}=this.cosmetics.getCosmeticsFilters({domain:o,hostname:t,classes:i,hrefs:n,ids:s,allowGenericHides:h,allowSpecificHides:m,getRulesFromDOM:l,getRulesFromHostname:p,hidingStyle:d,isFilterExcluded:this.isFilterExcluded.bind(this)});let y=!1;const w=new Map;for(const e of b)!0===e.isScriptInject()&&!0===e.isUnhide()&&0===e.getSelector().length&&(y=!0),w.set(Dt(e,this.resources.getScriptletCanonicalName.bind(this.resources)),e);const v=[],_=[],C=[];if(0!==k.length)for(const t of k){const o=w.get(Dt(t,this.resources.getScriptletCanonicalName.bind(this.resources)));if(void 0!==o)continue;let i=!1;!0===t.isScriptInject()?!0===r&&!1===y&&(v.push(t),i=!0):t.isExtended()?!0===a&&(C.push(t),i=!0):(_.push(t),i=!0),i&&this.emit("filter-matched",{filter:t,exception:o},{url:e,callerContext:u,filterType:go.COSMETIC})}const x=[];for(const t of v){const o=t.getScript(this.resources.getScriptlet.bind(this.resources));void 0!==o&&(this.emit("script-injected",o,e),x.push(o))}const{stylesheet:S,extended:E}=this.cosmetics.getStylesheetsFromFilters({filters:_,extendedFilters:C},{getBaseRules:c,allowGenericHides:h,hidingStyle:d});return 0!==S.length&&this.emit("style-injected",S,e),{active:!0,extended:E,scripts:x,styles:S}}matchAll(e){const t=[];return e.isSupported&&(Array.prototype.push.apply(t,this.importants.matchAll(e,this.isFilterExcluded.bind(this))),Array.prototype.push.apply(t,this.filters.matchAll(e,this.isFilterExcluded.bind(this))),Array.prototype.push.apply(t,this.exceptions.matchAll(e,this.isFilterExcluded.bind(this))),Array.prototype.push.apply(t,this.csp.matchAll(e,this.isFilterExcluded.bind(this))),Array.prototype.push.apply(t,this.hideExceptions.matchAll(e,this.isFilterExcluded.bind(this))),Array.prototype.push.apply(t,this.redirects.matchAll(e,this.isFilterExcluded.bind(this)))),new Set(t)}getCSPDirectives(e){if(!this.config.loadNetworkFilters)return;if(!0!==e.isSupported||!1===e.isMainFrame())return;const t=this.csp.matchAll(e,this.isFilterExcluded.bind(this));if(0===t.length)return;const o=new Map,i=[];for(const n of t)if(n.isException()){if(void 0===n.csp)return void this.emit("filter-matched",{exception:n},{request:e,filterType:go.NETWORK});o.set(n.csp,n)}else i.push(n);if(0===i.length)return;const n=new Set;for(const t of i.values()){const i=o.get(t.csp);void 0===i&&n.add(t.csp),this.emit("filter-matched",{filter:t,exception:i},{request:e,filterType:go.NETWORK})}const s=Array.from(n).join("; ");return s.length>0&&this.emit("csp-injected",e,s),s}match(e,t=!1){const o={exception:void 0,filter:void 0,match:!1,redirect:void 0,metadata:void 0};if(!this.config.loadNetworkFilters)return o;if(e.isSupported){let t,i;if(o.filter=this.importants.match(e,this.isFilterExcluded.bind(this)),void 0===o.filter){const n=this.redirects.matchAll(e,this.isFilterExcluded.bind(this)).sort(((e,t)=>t.getRedirectPriority()-e.getRedirectPriority()));if(0!==n.length)for(const e of n)"none"===e.getRedirectResource()?t=e:e.isRedirectRule()?void 0===i&&(i=e):void 0===o.filter&&(o.filter=e);void 0===o.filter&&(o.filter=this.filters.match(e,this.isFilterExcluded.bind(this)),void 0!==i&&void 0!==o.filter&&(o.filter=i)),void 0!==o.filter&&(o.exception=this.exceptions.match(e,this.isFilterExcluded.bind(this)))}void 0!==o.filter&&void 0===o.exception&&o.filter.isRedirect()&&(void 0!==t?o.exception=t:o.redirect=this.resources.getResource(o.filter.getRedirectResource()))}return o.match=void 0===o.exception&&void 0!==o.filter,o.filter&&this.emit("filter-matched",{filter:o.filter,exception:o.exception},{request:e,filterType:go.NETWORK}),void 0!==o.exception?this.emit("request-whitelisted",e,o):void 0!==o.redirect?this.emit("request-redirected",e,o):void 0!==o.filter?this.emit("request-blocked",e,o):this.emit("request-allowed",e,o),!0===t&&void 0!==o.filter&&this.metadata&&(o.metadata=this.metadata.fromFilter(o.filter)),o}getPatternMetadata(e,{getDomainMetadata:t=!1}={}){if(void 0===this.metadata)return[];const o=new Set,i=[];for(const t of this.matchAll(e))for(const e of this.metadata.fromFilter(t))o.has(e.pattern.key)||(o.add(e.pattern.key),i.push(e));if(t)for(const t of this.metadata.fromDomain(e.hostname))o.has(t.pattern.key)||(o.add(t.pattern.key),i.push(t));return i}blockScripts(){return this.updateFromDiff({added:[qt().scripts().redirectTo("javascript").toString()]}),this}blockImages(){return this.updateFromDiff({added:[qt().images().redirectTo("png").toString()]}),this}blockMedias(){return this.updateFromDiff({added:[qt().medias().redirectTo("mp4").toString()]}),this}blockFrames(){return this.updateFromDiff({added:[qt().frames().redirectTo("html").toString()]}),this}blockFonts(){return this.updateFromDiff({added:[qt().fonts().toString()]}),this}blockStyles(){return this.updateFromDiff({added:[qt().styles().toString()]}),this}};function sn(e){const t=new Set(["br","head","link","meta","script","style","s"]),o=new Set,i=new Set,n=new Set,s=new Set;for(const c of e)for(const e of[c,...c.querySelectorAll("[id]:not(html):not(body),[class]:not(html):not(body),[href]:not(html):not(body)")]){if(s.has(e))continue;if(s.add(e),t.has(e.nodeName.toLowerCase()))continue;const c=e.getAttribute("id");"string"==typeof c&&n.add(c);const r=e.classList;for(const e of r)o.add(e);const a=e.getAttribute("href");"string"==typeof a&&i.add(a)}return{classes:Array.from(o),hrefs:Array.from(i),ids:Array.from(n)}}function cn(e){try{const t=ot(location.href),o=t.hostname||"",i=t.domain||"";return e.getCosmeticsFilters({url:location.href,hostname:o,domain:i,...sn([document.documentElement]),getBaseRules:!0,getInjectionRules:!1,getExtendedRules:!0,getRulesFromDOM:!0,getRulesFromHostname:!0,hidingStyle:A("opacity")}).styles}catch(e){return console.error("Error getting cosmetic rules",e),""}}function rn(e){if(e){return e.replace(/\s*{[^\\}]*}\s*/g,",").replace(/,$/,"")}return""}var an=new Uint8Array([]);var ln=[{name:"192.com",detectCmp:[{exists:".ont-cookies"}],detectPopup:[{visible:".ont-cookies"}],optIn:[{click:".ont-btn-main.ont-cookies-btn.js-ont-btn-ok2"}],optOut:[{click:".ont-cookes-btn-manage"},{click:".ont-btn-main.ont-cookies-btn.js-ont-btn-choose"}],test:[{eval:"EVAL_ONENINETWO_0"}]},{name:"1password-com",cosmetic:!0,prehideSelectors:['footer #footer-root [aria-label="Cookie Consent"]'],detectCmp:[{exists:'footer #footer-root [aria-label="Cookie Consent"]'}],detectPopup:[{visible:'footer #footer-root [aria-label="Cookie Consent"]'}],optIn:[{click:'footer #footer-root [aria-label="Cookie Consent"] button'}],optOut:[{hide:'footer #footer-root [aria-label="Cookie Consent"]'}]},{name:"aa",vendorUrl:"https://aa.com",prehideSelectors:[],cosmetic:!0,detectCmp:[{exists:"#aa_optoutmulti-Modal,#cookieBannerMessage"}],detectPopup:[{visible:"#aa_optoutmulti-Modal,#cookieBannerMessage"}],optIn:[{hide:"#aa_optoutmulti-Modal,#cookieBannerMessage"},{waitForThenClick:"#aa_optoutmulti_checkBox"},{waitForThenClick:"#aa_optoutmulti-Modal button.optoutmulti_button"}],optOut:[{hide:"#aa_optoutmulti-Modal,#cookieBannerMessage"}]},{name:"abc",vendorUrl:"https://abc.net.au",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?abc\\.net\\.au/"},prehideSelectors:[],detectCmp:[{exists:"[data-component=CookieBanner]"}],detectPopup:[{visible:"[data-component=CookieBanner] [data-component=CookieBanner_AcceptAll]"}],optIn:[{waitForThenClick:"[data-component=CookieBanner] [data-component=CookieBanner_AcceptAll]"}],optOut:[{waitForThenClick:"[data-component=CookieBanner] [data-component=CookieBanner_AcceptABCRequired]"}],test:[{eval:"EVAL_ABC_TEST"}]},{name:"abconcerts.be",vendorUrl:"https://unknown",intermediate:!1,prehideSelectors:["dialog.cookie-consent"],detectCmp:[{exists:"dialog.cookie-consent form.cookie-consent__form"}],detectPopup:[{visible:"dialog.cookie-consent form.cookie-consent__form"}],optIn:[{waitForThenClick:"dialog.cookie-consent form.cookie-consent__form button[value=yes]"}],optOut:[{if:{exists:"dialog.cookie-consent form.cookie-consent__form button[value=no]"},then:[{click:"dialog.cookie-consent form.cookie-consent__form button[value=no]"}],else:[{click:"dialog.cookie-consent form.cookie-consent__form button.cookie-consent__options-toggle"},{waitForThenClick:'dialog.cookie-consent form.cookie-consent__form button[value="save_options"]'}]}]},{name:"acris",prehideSelectors:["div.acris-cookie-consent"],detectCmp:[{exists:"[data-acris-cookie-consent]"}],detectPopup:[{visible:".acris-cookie-consent.is--modal"}],optIn:[{waitForVisible:"#ccConsentAcceptAllButton",check:"any"},{wait:500},{waitForThenClick:"#ccConsentAcceptAllButton"}],optOut:[{waitForVisible:"#ccAcceptOnlyFunctional",check:"any"},{wait:500},{waitForThenClick:"#ccAcceptOnlyFunctional"}]},{name:"activobank.pt",runContext:{urlPattern:"^https://(www\\.)?activobank\\.pt"},prehideSelectors:["aside#cookies,.overlay-cookies"],detectCmp:[{exists:"#cookies .cookies-btn"}],detectPopup:[{visible:"#cookies #submitCookies"}],optIn:[{waitForThenClick:"#cookies #submitCookies"}],optOut:[{waitForThenClick:"#cookies #rejectCookies"}]},{name:"Adroll",prehideSelectors:["#adroll_consent_container"],detectCmp:[{exists:"#adroll_consent_container"}],detectPopup:[{visible:"#adroll_consent_container"}],optIn:[{waitForThenClick:"#adroll_consent_accept"}],optOut:[{waitForThenClick:"#adroll_consent_reject"}],test:[{eval:"EVAL_ADROLL_0"}]},{name:"affinity.serif.com",detectCmp:[{exists:".c-cookie-banner button[data-qa='allow-all-cookies']"}],detectPopup:[{visible:".c-cookie-banner"}],optIn:[{click:'button[data-qa="allow-all-cookies"]'}],optOut:[{click:'button[data-qa="manage-cookies"]'},{waitFor:'.c-cookie-banner ~ [role="dialog"]'},{waitForThenClick:'.c-cookie-banner ~ [role="dialog"] input[type="checkbox"][value="true"]',all:!0},{click:'.c-cookie-banner ~ [role="dialog"] .c-modal__action button'}],test:[{wait:500},{eval:"EVAL_AFFINITY_SERIF_COM_0"}]},{name:"agolde.com",cosmetic:!0,prehideSelectors:["#modal-1 div[data-micromodal-close]"],detectCmp:[{exists:"#modal-1 div[aria-labelledby=modal-1-title]"}],detectPopup:[{exists:"#modal-1 div[data-micromodal-close]"}],optIn:[{click:'button[aria-label="Close modal"]'}],optOut:[{hide:"#modal-1 div[data-micromodal-close]"}]},{name:"aliexpress",vendorUrl:"https://aliexpress.com/",runContext:{urlPattern:"^https://.*\\.aliexpress\\.com/"},prehideSelectors:["#gdpr-new-container"],detectCmp:[{exists:"#gdpr-new-container,#voyager-gdpr > div"}],detectPopup:[{visible:"#gdpr-new-container,#voyager-gdpr > div"}],optIn:[{waitForThenClick:"#gdpr-new-container .btn-accept,#voyager-gdpr > div > div > button:nth-child(1)"}],optOut:[{if:{exists:"#voyager-gdpr > div"},then:[{waitForThenClick:"#voyager-gdpr > div > div > button:nth-child(2)"}],else:[{waitForThenClick:"#gdpr-new-container .btn-more"},{waitFor:"#gdpr-new-container .gdpr-dialog-switcher"},{click:"#gdpr-new-container .switcher-on",all:!0,optional:!0},{click:"#gdpr-new-container .btn-save"}]}]},{name:"almacmp",prehideSelectors:["#alma-cmpv2-container"],detectCmp:[{exists:"#alma-cmpv2-container"}],detectPopup:[{visible:"#alma-cmpv2-container #almacmp-modal-layer1"}],optIn:[{waitForThenClick:"#alma-cmpv2-container #almacmp-modal-layer1 #almacmp-modalConfirmBtn"}],optOut:[{waitForThenClick:"#alma-cmpv2-container #almacmp-modal-layer1 #almacmp-modalSettingBtn"},{waitFor:"#alma-cmpv2-container #almacmp-modal-layer2"},{waitForThenClick:"#alma-cmpv2-container #almacmp-modal-layer2 #almacmp-reject-all-layer2"}],test:[{eval:"EVAL_ALMACMP_0"}]},{name:"altium.com",cosmetic:!0,prehideSelectors:[".altium-privacy-bar"],detectCmp:[{exists:".altium-privacy-bar"}],detectPopup:[{exists:".altium-privacy-bar"}],optIn:[{click:"a.altium-privacy-bar__btn"}],optOut:[{hide:".altium-privacy-bar"}]},{name:"amazon.com",prehideSelectors:['span[data-action="sp-cc"][data-sp-cc*="rejectAllAction"]'],detectCmp:[{exists:'span[data-action="sp-cc"][data-sp-cc*="rejectAllAction"]'}],detectPopup:[{visible:'span[data-action="sp-cc"][data-sp-cc*="rejectAllAction"]'}],optIn:[{waitForVisible:"#sp-cc-accept"},{wait:500},{click:"#sp-cc-accept"}],optOut:[{waitForVisible:"#sp-cc-rejectall-link"},{wait:500},{click:"#sp-cc-rejectall-link"}]},{name:"amex",vendorUrl:"https://www.americanexpress.com/",cosmetic:!1,prehideSelectors:["#user-consent-management-granular-banner-overlay"],detectCmp:[{exists:"#user-consent-management-granular-banner-overlay"}],detectPopup:[{visible:"#user-consent-management-granular-banner-overlay"}],optIn:[{waitForThenClick:"[data-testid=granular-banner-button-accept-all]"}],optOut:[{waitForThenClick:"[data-testid=granular-banner-button-decline-all]"}]},{name:"aquasana.com",prehideSelectors:["#consent-tracking"],detectCmp:[{exists:"#consent-tracking"}],detectPopup:[{exists:"#consent-tracking"}],optIn:[{waitForThenClick:"#consent-tracking .affirm.btn"}],optOut:[{if:{exists:"#consent-tracking .decline.btn"},then:[{click:"#consent-tracking .decline.btn"}],else:[{hide:"#consent-tracking"}]}]},{name:"arbeitsagentur",vendorUrl:"https://www.arbeitsagentur.de/",prehideSelectors:[".modal-open bahf-cookie-disclaimer-dpl3"],detectCmp:[{exists:"bahf-cookie-disclaimer-dpl3"}],detectPopup:[{visible:"bahf-cookie-disclaimer-dpl3"}],optIn:[{waitForThenClick:["bahf-cookie-disclaimer-dpl3","#bahf-cookie-disclaimer-modal .ba-btn-primary"]}],optOut:[{waitForThenClick:["bahf-cookie-disclaimer-dpl3","#bahf-cookie-disclaimer-modal .ba-btn-contrast"]}],test:[{eval:"EVAL_ARBEITSAGENTUR_TEST"}]},{name:"asus",vendorUrl:"https://www.asus.com/",runContext:{urlPattern:"^https://www\\.asus\\.com/"},prehideSelectors:["#cookie-policy-info,#cookie-policy-info-bg"],detectCmp:[{exists:"#cookie-policy-info"}],detectPopup:[{visible:"#cookie-policy-info"}],optIn:[{waitForThenClick:'#cookie-policy-info [data-agree="Accept Cookies"]'}],optOut:[{if:{exists:"#cookie-policy-info .btn-reject"},then:[{waitForThenClick:"#cookie-policy-info .btn-reject"}],else:[{waitForThenClick:"#cookie-policy-info .btn-setting"},{waitForThenClick:'#cookie-policy-lightbox-wrapper [data-agree="Save Settings"]'}]}]},{name:"athlinks-com",runContext:{urlPattern:"^https://(www\\.)?athlinks\\.com/"},cosmetic:!0,prehideSelectors:["#footer-container ~ div"],detectCmp:[{exists:"#footer-container ~ div"}],detectPopup:[{visible:"#footer-container > div"}],optIn:[{click:"#footer-container ~ div button"}],optOut:[{hide:"#footer-container ~ div"}]},{name:"ausopen.com",cosmetic:!0,detectCmp:[{exists:".gdpr-popup__message"}],detectPopup:[{visible:".gdpr-popup__message"}],optOut:[{hide:".gdpr-popup__message"}],optIn:[{click:".gdpr-popup__message button"}]},{name:"automattic-cmp-optout",prehideSelectors:['form[class*="cookie-banner"][method="post"]'],detectCmp:[{exists:'form[class*="cookie-banner"][method="post"]'}],detectPopup:[{visible:'form[class*="cookie-banner"][method="post"]'}],optIn:[{click:'a[class*="accept-all-button"]'}],optOut:[{click:'form[class*="cookie-banner"] div[class*="simple-options"] a[class*="customize-button"]'},{waitForThenClick:"input[type=checkbox][checked]:not([disabled])",all:!0},{click:'a[class*="accept-selection-button"]'}]},{name:"aws.amazon.com",prehideSelectors:["#awsccc-cb-content","#awsccc-cs-container","#awsccc-cs-modalOverlay","#awsccc-cs-container-inner"],detectCmp:[{exists:"#awsccc-cb-content"}],detectPopup:[{visible:"#awsccc-cb-content"}],optIn:[{click:"button[data-id=awsccc-cb-btn-accept"}],optOut:[{click:"button[data-id=awsccc-cb-btn-customize]"},{waitFor:"input[aria-checked]"},{click:"input[aria-checked=true]",all:!0,optional:!0},{click:"button[data-id=awsccc-cs-btn-save]"}]},{name:"axeptio",prehideSelectors:[".axeptio_widget"],detectCmp:[{exists:".axeptio_widget"}],detectPopup:[{visible:".axeptio_widget"}],optIn:[{waitFor:".axeptio-widget--open"},{click:"button#axeptio_btn_acceptAll"}],optOut:[{waitFor:".axeptio-widget--open"},{click:"button#axeptio_btn_dismiss"}],test:[{eval:"EVAL_AXEPTIO_0"}]},{name:"baden-wuerttemberg.de",prehideSelectors:[".cookie-alert.t-dark"],cosmetic:!0,detectCmp:[{exists:".cookie-alert.t-dark"}],detectPopup:[{visible:".cookie-alert.t-dark"}],optIn:[{click:".cookie-alert__form input:not([disabled]):not([checked])"},{click:".cookie-alert__button button"}],optOut:[{hide:".cookie-alert.t-dark"}]},{name:"bahn-de",vendorUrl:"https://www.bahn.de/",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?bahn\\.de/"},intermediate:!1,prehideSelectors:[],detectCmp:[{exists:["body > div:first-child","#consent-layer"]}],detectPopup:[{visible:["body > div:first-child","#consent-layer"]}],optIn:[{waitForThenClick:["body > div:first-child","#consent-layer .js-accept-all-cookies"]}],optOut:[{waitForThenClick:["body > div:first-child","#consent-layer .js-accept-essential-cookies"]}],test:[{eval:"EVAL_BAHN_TEST"}]},{name:"bbb.org",runContext:{urlPattern:"^https://www\\.bbb\\.org/"},cosmetic:!0,prehideSelectors:['div[aria-label="use of cookies on bbb.org"]'],detectCmp:[{exists:'div[aria-label="use of cookies on bbb.org"]'}],detectPopup:[{visible:'div[aria-label="use of cookies on bbb.org"]'}],optIn:[{click:'div[aria-label="use of cookies on bbb.org"] button.bds-button-unstyled span.visually-hidden'}],optOut:[{hide:'div[aria-label="use of cookies on bbb.org"]'}]},{name:"bing.com",prehideSelectors:["#bnp_container"],detectCmp:[{exists:"#bnp_cookie_banner"}],detectPopup:[{visible:"#bnp_cookie_banner"},{visible:"#bnp_btn_accept,#bnp_btn_reject"}],optIn:[{waitForThenClick:"#bnp_btn_accept"}],optOut:[{wait:500},{waitForThenClick:"#bnp_btn_reject"}],test:[{eval:"EVAL_BING_0"}]},{name:"blocksy",vendorUrl:"https://creativethemes.com/blocksy/docs/extensions/cookies-consent/",cosmetic:!1,runContext:{main:!0,frame:!1},intermediate:!1,prehideSelectors:[".cookie-notification"],detectCmp:[{exists:"#blocksy-ext-cookies-consent-styles-css"}],detectPopup:[{visible:".cookie-notification"}],optIn:[{click:".cookie-notification .ct-cookies-decline-button"}],optOut:[{waitForThenClick:".cookie-notification .ct-cookies-decline-button"}],test:[{eval:"EVAL_BLOCKSY_0"}]},{name:"borlabs",detectCmp:[{exists:"._brlbs-block-content"}],detectPopup:[{visible:"._brlbs-bar-wrap,._brlbs-box-wrap"}],optIn:[{click:"a[data-cookie-accept-all]"}],optOut:[{click:"a[data-cookie-individual]"},{waitForVisible:".cookie-preference"},{click:"input[data-borlabs-cookie-checkbox]:checked",all:!0,optional:!0},{click:"#CookiePrefSave"},{wait:500}],prehideSelectors:["#BorlabsCookieBox"],test:[{eval:"EVAL_BORLABS_0"}]},{name:"bundesregierung.de",prehideSelectors:[".bpa-cookie-banner"],detectCmp:[{exists:".bpa-cookie-banner"}],detectPopup:[{visible:".bpa-cookie-banner .bpa-module-full-hero"}],optIn:[{click:".bpa-accept-all-button"}],optOut:[{wait:500,comment:"click is not immediately recognized"},{waitForThenClick:".bpa-close-button"}],test:[{eval:"EVAL_BUNDESREGIERUNG_DE_0"}]},{name:"burpee.com",cosmetic:!0,prehideSelectors:["#notice-cookie-block"],detectCmp:[{exists:"#notice-cookie-block"}],detectPopup:[{exists:"#html-body #notice-cookie-block"}],optIn:[{click:"#btn-cookie-allow"}],optOut:[{hide:"#html-body #notice-cookie-block, #notice-cookie"}]},{name:"canva.com",prehideSelectors:['div[role="dialog"] a[data-anchor-id="cookie-policy"]'],detectCmp:[{exists:'div[role="dialog"] a[data-anchor-id="cookie-policy"]'}],detectPopup:[{exists:'div[role="dialog"] a[data-anchor-id="cookie-policy"]'}],optIn:[{click:'div[role="dialog"] button:nth-child(1)'}],optOut:[{if:{exists:'div[role="dialog"] button:nth-child(3)'},then:[{click:'div[role="dialog"] button:nth-child(2)'}],else:[{click:'div[role="dialog"] button:nth-child(2)'},{waitFor:'div[role="dialog"] a[data-anchor-id="cookie-policy"]'},{waitFor:'div[role="dialog"] button[role=switch]'},{click:'div[role="dialog"] button:nth-child(2):not([role])'},{click:'div[role="dialog"] div:last-child button:only-child'}]}],test:[{eval:"EVAL_CANVA_0"}]},{name:"canyon.com",runContext:{urlPattern:"^https://www\\.canyon\\.com/"},prehideSelectors:["div.modal.cookiesModal.is-open"],detectCmp:[{exists:"div.modal.cookiesModal.is-open"}],detectPopup:[{visible:"div.modal.cookiesModal.is-open"}],optIn:[{click:'div.cookiesModal__buttonWrapper > button[data-closecause="close-by-submit"]'}],optOut:[{click:'div.cookiesModal__buttonWrapper > button[data-closecause="close-by-manage-cookies"]'},{waitForThenClick:"button#js-manage-data-privacy-save-button"}]},{name:"cassie",vendorUrl:"https://trustcassie.com",cosmetic:!1,runContext:{main:!0,frame:!1},prehideSelectors:[".cassie-cookie-module"],detectCmp:[{exists:".cassie-pre-banner"}],detectPopup:[{visible:"#cassie_pre_banner_text"}],optIn:[{waitForThenClick:".cassie-accept-all"}],optOut:[{waitForThenClick:".cassie-reject-all"}]},{name:"cc-banner-springer",prehideSelectors:[".cc-banner[data-cc-banner]"],detectCmp:[{exists:".cc-banner[data-cc-banner]"}],detectPopup:[{visible:".cc-banner[data-cc-banner]"}],optIn:[{waitForThenClick:".cc-banner[data-cc-banner] button[data-cc-action=accept]"}],optOut:[{if:{exists:".cc-banner[data-cc-banner] button[data-cc-action=reject]"},then:[{click:".cc-banner[data-cc-banner] button[data-cc-action=reject]"}],else:[{waitForThenClick:".cc-banner[data-cc-banner] button[data-cc-action=preferences]"},{waitFor:".cc-preferences[data-cc-preferences]"},{click:".cc-preferences[data-cc-preferences] input[type=radio][data-cc-action=toggle-category][value=off]",all:!0,optional:!0},{if:{exists:".cc-preferences[data-cc-preferences] button[data-cc-action=reject]"},then:[{click:".cc-preferences[data-cc-preferences] button[data-cc-action=reject]"}],else:[{click:".cc-preferences[data-cc-preferences] button[data-cc-action=save]"}]}]}],test:[{eval:"EVAL_CC_BANNER2_0"}]},{name:"cc_banner",cosmetic:!0,prehideSelectors:[".cc_banner-wrapper"],detectCmp:[{exists:".cc_banner-wrapper"}],detectPopup:[{visible:".cc_banner"}],optIn:[{click:".cc_btn_accept_all"}],optOut:[{hide:".cc_banner-wrapper"}]},{name:"check24-partnerprogramm-de",prehideSelectors:["[data-modal-content]:has([data-toggle-target^='cookie'])"],detectCmp:[{exists:"[data-toggle-target^='cookie']"}],detectPopup:[{visible:"[data-toggle-target^='cookie']",check:"any"}],optIn:[{waitForThenClick:"[data-cookie-accept-all]"}],optOut:[{waitForThenClick:"[data-cookie-dismiss-all]"}]},{name:"ciaopeople.it",prehideSelectors:["#cp-gdpr-choices"],detectCmp:[{exists:"#cp-gdpr-choices"}],detectPopup:[{visible:"#cp-gdpr-choices"}],optIn:[{waitForThenClick:".gdpr-btm__right > button:nth-child(2)"}],optOut:[{waitForThenClick:".gdpr-top-content > button"},{waitFor:".gdpr-top-back"},{waitForThenClick:".gdpr-btm__right > button:nth-child(1)"}],test:[{visible:"#cp-gdpr-choices",check:"none"}]},{vendorUrl:"https://www.civicuk.com/cookie-control/",name:"civic-cookie-control",prehideSelectors:["#ccc-module,#ccc-overlay,#ccc"],detectCmp:[{exists:"#ccc-module,#ccc-notify"}],detectPopup:[{visible:"#ccc"},{visible:"#ccc-module,#ccc-notify"}],optOut:[{if:{exists:"#ccc-notify"},then:[{waitForThenClick:["#ccc #ccc-notify .ccc-notify-buttons","xpath///button[contains(., 'Settings') or contains(., 'Cookie Preferences')]"]},{waitForVisible:"#ccc-module"}]},{if:{exists:"#ccc-reject-settings"},then:[{waitForThenClick:"#ccc-reject-settings"}],else:[{waitForThenClick:"#ccc-dismiss-button"}]}],optIn:[{waitForThenClick:"#ccc-recommended-settings,#ccc-notify-accept"}]},{name:"click.io",prehideSelectors:["#cl-consent"],detectCmp:[{exists:"#cl-consent"}],detectPopup:[{visible:"#cl-consent"}],optIn:[{waitForThenClick:'#cl-consent [data-role="b_agree"]'}],optOut:[{waitFor:'#cl-consent [data-role="b_options"]'},{wait:500},{click:'#cl-consent [data-role="b_options"]'},{waitFor:'.cl-consent-popup.cl-consent-visible [data-role="alloff"]'},{click:'.cl-consent-popup.cl-consent-visible [data-role="alloff"]',all:!0},{click:'[data-role="b_save"]'}],test:[{eval:"EVAL_CLICKIO_0",comment:"TODO: this only checks if we interacted at all"}]},{name:"clinch",intermediate:!1,runContext:{frame:!1,main:!0},prehideSelectors:[".consent-modal[role=dialog]"],detectCmp:[{exists:".consent-modal[role=dialog]"}],detectPopup:[{visible:".consent-modal[role=dialog]"}],optIn:[{click:"#consent_agree"}],optOut:[{if:{exists:"#consent_reject"},then:[{click:"#consent_reject"}],else:[{click:"#manage_cookie_preferences"},{click:"#cookie_consent_preferences input:checked",all:!0,optional:!0},{click:"#consent_save"}]}],test:[{eval:"EVAL_CLINCH_0"}]},{name:"clustrmaps.com",runContext:{urlPattern:"^https://(www\\.)?clustrmaps\\.com/"},cosmetic:!0,prehideSelectors:["#gdpr-cookie-message"],detectCmp:[{exists:"#gdpr-cookie-message"}],detectPopup:[{visible:"#gdpr-cookie-message"}],optIn:[{click:"button#gdpr-cookie-accept"}],optOut:[{hide:"#gdpr-cookie-message"}]},{name:"coinbase",intermediate:!1,runContext:{frame:!0,main:!0,urlPattern:"^https://(www|help)\\.coinbase\\.com"},prehideSelectors:[],detectCmp:[{exists:"div[class^=CookieBannerContent__Container]"}],detectPopup:[{visible:"div[class^=CookieBannerContent__Container]"}],optIn:[{click:"div[class^=CookieBannerContent__CTA] :nth-last-child(1)"}],optOut:[{click:"button[class^=CookieBannerContent__Settings]"},{click:"div[class^=CookiePreferencesModal__CategoryContainer] input:checked",all:!0,optional:!0},{click:"div[class^=CookiePreferencesModal__ButtonContainer] > button"}],test:[{eval:"EVAL_COINBASE_0"}]},{name:"Complianz banner",prehideSelectors:["#cmplz-cookiebanner-container"],detectCmp:[{exists:"#cmplz-cookiebanner-container .cmplz-cookiebanner"}],detectPopup:[{visible:"#cmplz-cookiebanner-container .cmplz-cookiebanner",check:"any"}],optIn:[{waitForThenClick:".cmplz-cookiebanner .cmplz-accept"}],optOut:[{waitForThenClick:".cmplz-cookiebanner .cmplz-deny"}],test:[{eval:"EVAL_COMPLIANZ_BANNER_0"}]},{name:"Complianz categories",prehideSelectors:['.cc-type-categories[aria-describedby="cookieconsent:desc"]'],detectCmp:[{exists:'.cc-type-categories[aria-describedby="cookieconsent:desc"]'}],detectPopup:[{visible:'.cc-type-categories[aria-describedby="cookieconsent:desc"]'}],optIn:[{any:[{click:".cc-accept-all"},{click:".cc-allow-all"},{click:".cc-allow"},{click:".cc-dismiss"}]}],optOut:[{if:{exists:'.cc-type-categories[aria-describedby="cookieconsent:desc"] .cc-dismiss'},then:[{click:".cc-dismiss"}],else:[{click:".cc-type-categories input[type=checkbox]:not([disabled]):checked",all:!0,optional:!0},{click:".cc-save"}]}]},{name:"Complianz notice",prehideSelectors:['.cc-type-info[aria-describedby="cookieconsent:desc"]'],cosmetic:!0,detectCmp:[{exists:'.cc-type-info[aria-describedby="cookieconsent:desc"] .cc-compliance .cc-btn'}],detectPopup:[{visible:'.cc-type-info[aria-describedby="cookieconsent:desc"] .cc-compliance .cc-btn'}],optIn:[{click:".cc-accept-all",optional:!0},{click:".cc-allow",optional:!0},{click:".cc-dismiss",optional:!0}],optOut:[{if:{exists:".cc-deny"},then:[{click:".cc-deny"}],else:[{hide:'[aria-describedby="cookieconsent:desc"]'}]}]},{name:"Complianz opt-both",prehideSelectors:['[aria-describedby="cookieconsent:desc"] .cc-type-opt-both'],detectCmp:[{exists:'[aria-describedby="cookieconsent:desc"] .cc-type-opt-both'}],detectPopup:[{visible:'[aria-describedby="cookieconsent:desc"] .cc-type-opt-both'}],optIn:[{click:".cc-accept-all",optional:!0},{click:".cc-allow",optional:!0},{click:".cc-dismiss",optional:!0}],optOut:[{waitForThenClick:".cc-deny"}]},{name:"Complianz opt-out",prehideSelectors:['[aria-describedby="cookieconsent:desc"].cc-type-opt-out'],detectCmp:[{exists:'[aria-describedby="cookieconsent:desc"].cc-type-opt-out'}],detectPopup:[{visible:'[aria-describedby="cookieconsent:desc"].cc-type-opt-out'}],optIn:[{click:".cc-accept-all",optional:!0},{click:".cc-allow",optional:!0},{click:".cc-dismiss",optional:!0}],optOut:[{if:{exists:".cc-deny"},then:[{click:".cc-deny"}],else:[{if:{exists:".cmp-pref-link"},then:[{click:".cmp-pref-link"},{waitForThenClick:".cmp-body [id*=rejectAll]"},{waitForThenClick:".cmp-body .cmp-save-btn"}]}]}]},{name:"Complianz optin",prehideSelectors:['.cc-type-opt-in[aria-describedby="cookieconsent:desc"]'],detectCmp:[{exists:'.cc-type-opt-in[aria-describedby="cookieconsent:desc"]'}],detectPopup:[{visible:'.cc-type-opt-in[aria-describedby="cookieconsent:desc"]'}],optIn:[{any:[{click:".cc-accept-all"},{click:".cc-allow"},{click:".cc-dismiss"}]}],optOut:[{if:{visible:".cc-deny"},then:[{click:".cc-deny"}],else:[{if:{visible:".cc-settings"},then:[{waitForThenClick:".cc-settings"},{waitForVisible:".cc-settings-view"},{click:".cc-settings-view input[type=checkbox]:not([disabled]):checked",all:!0,optional:!0},{click:".cc-settings-view .cc-btn-accept-selected"}],else:[{click:".cc-dismiss"}]}]}]},{name:"cookie-consent-spice",cosmetic:!1,runContext:{main:!0,frame:!1},prehideSelectors:[".spicy-consent-wrapper",".spicy-consent-bar"],detectCmp:[{exists:".spicy-consent-bar"}],detectPopup:[{visible:".spicy-consent-bar"}],optIn:[{waitForThenClick:".spicy-consent-bar__action-accept"}],optOut:[{waitForThenClick:".js-decline-all-cookies"}]},{name:"cookie-law-info",prehideSelectors:["#cookie-law-info-bar"],detectCmp:[{exists:"#cookie-law-info-bar"},{eval:"EVAL_COOKIE_LAW_INFO_DETECT"}],detectPopup:[{visible:"#cookie-law-info-bar"}],optIn:[{click:'[data-cli_action="accept_all"]'}],optOut:[{hide:"#cookie-law-info-bar"},{eval:"EVAL_COOKIE_LAW_INFO_0"}],test:[{eval:"EVAL_COOKIE_LAW_INFO_1"}]},{name:"cookie-manager-popup",cosmetic:!1,runContext:{main:!0,frame:!1},intermediate:!1,detectCmp:[{exists:"#notice-cookie-block #allow-functional-cookies, #notice-cookie-block #btn-cookie-settings"}],detectPopup:[{visible:"#notice-cookie-block"}],optIn:[{click:"#btn-cookie-allow"}],optOut:[{if:{exists:"#allow-functional-cookies"},then:[{click:"#allow-functional-cookies"}],else:[{waitForThenClick:"#btn-cookie-settings"},{waitForVisible:".modal-body"},{click:'.modal-body input:checked, .switch[data-switch="on"]',all:!0,optional:!0},{click:'[role="dialog"] .modal-footer button'}]}],prehideSelectors:["#btn-cookie-settings"],test:[{eval:"EVAL_COOKIE_MANAGER_POPUP_0"}]},{name:"cookie-notice",prehideSelectors:["#cookie-notice"],cosmetic:!0,detectCmp:[{visible:"#cookie-notice .cookie-notice-container"}],detectPopup:[{visible:"#cookie-notice"}],optIn:[{click:"#cn-accept-cookie"}],optOut:[{hide:"#cookie-notice"}]},{name:"cookie-script",vendorUrl:"https://cookie-script.com/",prehideSelectors:["#cookiescript_injected"],detectCmp:[{exists:"#cookiescript_injected"}],detectPopup:[{visible:"#cookiescript_injected"}],optOut:[{if:{exists:"#cookiescript_reject"},then:[{wait:100},{click:"#cookiescript_reject"}],else:[{click:"#cookiescript_manage"},{waitForVisible:".cookiescript_fsd_main"},{waitForThenClick:"#cookiescript_reject"}]}],optIn:[{click:"#cookiescript_accept"}]},{name:"cookieacceptbar",vendorUrl:"https://unknown",cosmetic:!0,prehideSelectors:["#cookieAcceptBar.cookieAcceptBar"],detectCmp:[{exists:"#cookieAcceptBar.cookieAcceptBar"}],detectPopup:[{visible:"#cookieAcceptBar.cookieAcceptBar"}],optIn:[{waitForThenClick:"#cookieAcceptBarConfirm"}],optOut:[{hide:"#cookieAcceptBar.cookieAcceptBar"}]},{name:"cookiealert",intermediate:!1,prehideSelectors:[],runContext:{frame:!0,main:!0},detectCmp:[{exists:".cookie-alert-extended"}],detectPopup:[{visible:".cookie-alert-extended-modal"}],optIn:[{click:"button[data-controller='cookie-alert/extended/button/accept']"},{eval:"EVAL_COOKIEALERT_0"}],optOut:[{click:"a[data-controller='cookie-alert/extended/detail-link']"},{click:".cookie-alert-configuration-input:checked",all:!0,optional:!0},{click:"button[data-controller='cookie-alert/extended/button/configuration']"},{eval:"EVAL_COOKIEALERT_0"}],test:[{eval:"EVAL_COOKIEALERT_2"}]},{name:"cookieconsent2",vendorUrl:"https://www.github.com/orestbida/cookieconsent",comment:"supports v2.x.x of the library",prehideSelectors:["#cc--main"],detectCmp:[{exists:"#cc--main"}],detectPopup:[{visible:"#cm"},{exists:"#s-all-bn"}],optIn:[{waitForThenClick:"#s-all-bn"}],optOut:[{waitForThenClick:"#s-rall-bn"}],test:[{eval:"EVAL_COOKIECONSENT2_TEST"}]},{name:"cookieconsent3",vendorUrl:"https://www.github.com/orestbida/cookieconsent",comment:"supports v3.x.x of the library",prehideSelectors:["#cc-main"],detectCmp:[{exists:"#cc-main"}],detectPopup:[{visible:"#cc-main .cm-wrapper"}],optIn:[{waitForThenClick:".cm__btn[data-role=all]"}],optOut:[{waitForThenClick:".cm__btn[data-role=necessary]"}],test:[{eval:"EVAL_COOKIECONSENT3_TEST"}]},{name:"cookiecuttr",vendorUrl:"https://github.com/cdwharton/cookieCuttr",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:""},prehideSelectors:[".cc-cookies"],detectCmp:[{exists:".cc-cookies .cc-cookie-accept"}],detectPopup:[{visible:".cc-cookies .cc-cookie-accept"}],optIn:[{waitForThenClick:".cc-cookies .cc-cookie-accept"}],optOut:[{if:{exists:".cc-cookies .cc-cookie-decline"},then:[{click:".cc-cookies .cc-cookie-decline"}],else:[{hide:".cc-cookies"}]}]},{name:"cookiefirst.com",prehideSelectors:["#cookiefirst-root,.cookiefirst-root,[aria-labelledby=cookie-preference-panel-title]"],detectCmp:[{exists:"#cookiefirst-root,.cookiefirst-root"}],detectPopup:[{visible:"#cookiefirst-root,.cookiefirst-root"}],optIn:[{click:"button[data-cookiefirst-action=accept]"}],optOut:[{if:{exists:"button[data-cookiefirst-action=adjust]"},then:[{click:"button[data-cookiefirst-action=adjust]"},{waitForVisible:"[data-cookiefirst-widget=modal]",timeout:1e3},{eval:"EVAL_COOKIEFIRST_1"},{wait:1e3},{click:"button[data-cookiefirst-action=save]"}],else:[{click:"button[data-cookiefirst-action=reject]"}]}],test:[{eval:"EVAL_COOKIEFIRST_0"}]},{name:"Cookie Information Banner",prehideSelectors:["#cookie-information-template-wrapper"],detectCmp:[{exists:"#cookie-information-template-wrapper"}],detectPopup:[{visible:"#cookie-information-template-wrapper"}],optIn:[{eval:"EVAL_COOKIEINFORMATION_1"}],optOut:[{hide:"#cookie-information-template-wrapper",comment:"some templates don't hide the banner automatically"},{eval:"EVAL_COOKIEINFORMATION_0"}],test:[{eval:"EVAL_COOKIEINFORMATION_2"}]},{name:"cookieyes",prehideSelectors:[".cky-overlay,.cky-consent-container"],detectCmp:[{exists:".cky-consent-container"}],detectPopup:[{visible:".cky-consent-container"}],optIn:[{waitForThenClick:".cky-consent-container [data-cky-tag=accept-button]"}],optOut:[{if:{exists:".cky-consent-container [data-cky-tag=reject-button]"},then:[{waitForThenClick:".cky-consent-container [data-cky-tag=reject-button]"}],else:[{if:{exists:".cky-consent-container [data-cky-tag=settings-button]"},then:[{click:".cky-consent-container [data-cky-tag=settings-button]"},{waitFor:".cky-modal-open input[type=checkbox]"},{click:".cky-modal-open input[type=checkbox]:checked",all:!0,optional:!0},{waitForThenClick:".cky-modal [data-cky-tag=detail-save-button]"}],else:[{hide:".cky-consent-container,.cky-overlay"}]}]}],test:[{eval:"EVAL_COOKIEYES_0"}]},{name:"corona-in-zahlen.de",prehideSelectors:[".cookiealert"],detectCmp:[{exists:".cookiealert"}],detectPopup:[{visible:".cookiealert"}],optOut:[{click:".configurecookies"},{click:".confirmcookies"}],optIn:[{click:".acceptcookies"}]},{name:"crossfit-com",cosmetic:!0,prehideSelectors:['body #modal > div > div[class^="_wrapper_"]'],detectCmp:[{exists:'body #modal > div > div[class^="_wrapper_"]'}],detectPopup:[{visible:'body #modal > div > div[class^="_wrapper_"]'}],optIn:[{click:'button[aria-label="accept cookie policy"]'}],optOut:[{hide:'body #modal > div > div[class^="_wrapper_"]'}]},{name:"csu-landtag-de",runContext:{urlPattern:"^https://(www\\.|)?csu-landtag\\.de"},prehideSelectors:["#cookie-disclaimer"],detectCmp:[{exists:"#cookie-disclaimer"}],detectPopup:[{visible:"#cookie-disclaimer"}],optIn:[{click:"#cookieall"}],optOut:[{click:"#cookiesel"}]},{name:"dailymotion-us",cosmetic:!0,prehideSelectors:['div[class*="CookiePopup__desktopContainer"]:has(div[class*="CookiePopup"])'],detectCmp:[{exists:'div[class*="CookiePopup__desktopContainer"]'}],detectPopup:[{visible:'div[class*="CookiePopup__desktopContainer"]'}],optIn:[{click:'div[class*="CookiePopup__desktopContainer"] > button > span'}],optOut:[{hide:'div[class*="CookiePopup__desktopContainer"]'}]},{name:"dailymotion.com",runContext:{urlPattern:"^https://(www\\.)?dailymotion\\.com/"},prehideSelectors:['div[class*="Overlay__container"]:has(div[class*="TCF2Popup"])'],detectCmp:[{exists:'div[class*="TCF2Popup"]'}],detectPopup:[{visible:'[class*="TCF2Popup"] a[href^="https://www.dailymotion.com/legal/cookiemanagement"]'}],optIn:[{waitForThenClick:'button[class*="TCF2Popup__button"]:not([class*="TCF2Popup__personalize"])'}],optOut:[{waitForThenClick:'button[class*="TCF2ContinueWithoutAcceptingButton"]'}],test:[{eval:"EVAL_DAILYMOTION_0"}]},{name:"dan-com",vendorUrl:"https://unknown",runContext:{main:!0,frame:!1},prehideSelectors:[],detectCmp:[{exists:".cookie-banner.show .cookie-banner__content-all-btn"}],detectPopup:[{visible:".cookie-banner.show .cookie-banner__content-all-btn"}],optIn:[{waitForThenClick:".cookie-banner__content-all-btn"}],optOut:[{waitForThenClick:".cookie-banner__content-essential-btn"}]},{name:"deepl.com",prehideSelectors:[".dl_cookieBanner_container"],detectCmp:[{exists:".dl_cookieBanner_container"}],detectPopup:[{visible:".dl_cookieBanner_container"}],optOut:[{click:".dl_cookieBanner--buttonSelected"}],optIn:[{click:".dl_cookieBanner--buttonAll"}]},{name:"delta.com",runContext:{urlPattern:"^https://www\\.delta\\.com/"},cosmetic:!0,prehideSelectors:["ngc-cookie-banner"],detectCmp:[{exists:"div.cookie-footer-container"}],detectPopup:[{visible:"div.cookie-footer-container"}],optIn:[{click:" button.cookie-close-icon"}],optOut:[{hide:"div.cookie-footer-container"}]},{name:"dmgmedia-us",prehideSelectors:["#mol-ads-cmp-iframe, div.mol-ads-cmp > form > div"],detectCmp:[{exists:"div.mol-ads-cmp > form > div"}],detectPopup:[{waitForVisible:"div.mol-ads-cmp > form > div"}],optIn:[{waitForThenClick:"button.mol-ads-cmp--btn-primary"}],optOut:[{waitForThenClick:"div.mol-ads-ccpa--message > u > a"},{waitForVisible:".mol-ads-cmp--modal-dialog"},{waitForThenClick:"a.mol-ads-cmp-footer-privacy"},{waitForThenClick:"button.mol-ads-cmp--btn-secondary"}]},{name:"dmgmedia",prehideSelectors:['[data-project="mol-fe-cmp"]'],detectCmp:[{exists:'[data-project="mol-fe-cmp"] [class*=footer]'}],detectPopup:[{visible:'[data-project="mol-fe-cmp"] [class*=footer]'}],optIn:[{waitForThenClick:'[data-project="mol-fe-cmp"] button[class*=primary]'}],optOut:[{waitForThenClick:'[data-project="mol-fe-cmp"] button[class*=basic]'},{waitForVisible:'[data-project="mol-fe-cmp"] div[class*="tabContent"]'},{waitForThenClick:'[data-project="mol-fe-cmp"] div[class*="toggle"][class*="enabled"]',all:!0},{waitForThenClick:['[data-project="mol-fe-cmp"] [class*=footer]',"xpath///button[contains(., 'Save & Exit')]"]}]},{name:"dndbeyond",vendorUrl:"https://www.dndbeyond.com/",runContext:{urlPattern:"^https://(www\\.)?dndbeyond\\.com/"},prehideSelectors:["[id^=cookie-consent-banner]"],detectCmp:[{exists:"[id^=cookie-consent-banner]"}],detectPopup:[{visible:"[id^=cookie-consent-banner]"}],optIn:[{waitForThenClick:"#cookie-consent-granted"}],optOut:[{waitForThenClick:"#cookie-consent-denied"}],test:[{eval:"EVAL_DNDBEYOND_TEST"}]},{name:"dpgmedia-nl",prehideSelectors:["#pg-shadow-root-host"],detectCmp:[{exists:"#pg-shadow-root-host"}],detectPopup:[{visible:["#pg-shadow-root-host","#pg-modal"]}],optIn:[{waitForThenClick:["#pg-shadow-root-host","#pg-accept-btn"]}],optOut:[{waitForThenClick:["#pg-shadow-root-host","#pg-configure-btn"]},{waitForThenClick:["#pg-shadow-root-host","#pg-reject-btn"]}]},{name:"Drupal",detectCmp:[{exists:"#drupalorg-crosssite-gdpr"}],detectPopup:[{visible:"#drupalorg-crosssite-gdpr"}],optOut:[{click:".no"}],optIn:[{click:".yes"}]},{name:"WP DSGVO Tools",link:"https://wordpress.org/plugins/shapepress-dsgvo/",prehideSelectors:[".sp-dsgvo"],cosmetic:!0,detectCmp:[{exists:".sp-dsgvo.sp-dsgvo-popup-overlay"}],detectPopup:[{visible:".sp-dsgvo.sp-dsgvo-popup-overlay",check:"any"}],optIn:[{click:".sp-dsgvo-privacy-btn-accept-all",all:!0}],optOut:[{hide:".sp-dsgvo.sp-dsgvo-popup-overlay"}],test:[{eval:"EVAL_DSGVO_0"}]},{name:"dunelm.com",prehideSelectors:["div[data-testid=cookie-consent-modal-backdrop]"],detectCmp:[{exists:"div[data-testid=cookie-consent-message-contents]"}],detectPopup:[{visible:"div[data-testid=cookie-consent-message-contents]"}],optIn:[{click:'[data-testid="cookie-consent-allow-all"]'}],optOut:[{click:"button[data-testid=cookie-consent-adjust-settings]"},{click:"button[data-testid=cookie-consent-preferences-save]"}],test:[{eval:"EVAL_DUNELM_0"}]},{name:"ebay",vendorUrl:"https://ebay.com",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?ebay\\.([.a-z]+)/"},prehideSelectors:["#gdpr-banner"],detectCmp:[{exists:"#gdpr-banner"}],detectPopup:[{visible:"#gdpr-banner"}],optIn:[{waitForThenClick:"#gdpr-banner-accept"}],optOut:[{waitForThenClick:"#gdpr-banner-decline"}]},{name:"ecosia",vendorUrl:"https://www.ecosia.org/",runContext:{urlPattern:"^https://www\\.ecosia\\.org/"},prehideSelectors:[".cookie-wrapper"],detectCmp:[{exists:".cookie-wrapper > .cookie-notice"}],detectPopup:[{visible:".cookie-wrapper > .cookie-notice"}],optIn:[{waitForThenClick:"[data-test-id=cookie-notice-accept]"}],optOut:[{waitForThenClick:"[data-test-id=cookie-notice-reject]"}]},{name:"Ensighten ensModal",prehideSelectors:[".ensModal"],detectCmp:[{exists:".ensModal"},{visible:"#ensModalWrapper[style*=block]"}],detectPopup:[{visible:"#ensModalWrapper[style*=block]"}],optIn:[{waitForThenClick:"#modalAcceptButton"}],optOut:[{wait:500},{visible:"#ensModalWrapper[style*=block]"},{waitForThenClick:".ensCheckbox:checked",all:!0},{waitForThenClick:"#ensSave"}]},{name:"Ensighten ensNotifyBanner",prehideSelectors:["#ensNotifyBanner"],detectCmp:[{exists:"#ensNotifyBanner"}],detectPopup:[{visible:"#ensNotifyBanner[style*=block]"}],optIn:[{waitForThenClick:"#ensCloseBanner"}],optOut:[{wait:500},{visible:"#ensNotifyBanner[style*=block]"},{waitForThenClick:"#ensRejectAll,#rejectAll,#ensRejectBanner,.rejectAll,#ensCloseBanner",timeout:2e3}]},{name:"espace-personnel.agirc-arrco.fr",runContext:{urlPattern:"^https://espace-personnel\\.agirc-arrco\\.fr/"},prehideSelectors:[".cdk-overlay-container"],detectCmp:[{exists:".cdk-overlay-container app-esaa-cookie-component"}],detectPopup:[{visible:".cdk-overlay-container app-esaa-cookie-component"}],optIn:[{waitForThenClick:".btn-cookie-accepter"}],optOut:[{waitForThenClick:".btn-cookie-refuser"}]},{name:"etsy",prehideSelectors:["#gdpr-single-choice-overlay","#gdpr-privacy-settings"],detectCmp:[{exists:"#gdpr-single-choice-overlay"}],detectPopup:[{visible:"#gdpr-single-choice-overlay"}],optOut:[{click:"button[data-gdpr-open-full-settings]"},{waitForVisible:".gdpr-overlay-body input",timeout:3e3},{wait:1e3},{eval:"EVAL_ETSY_0"},{eval:"EVAL_ETSY_1"}],optIn:[{click:"button[data-gdpr-single-choice-accept]"}]},{name:"eu-cookie-compliance-banner",detectCmp:[{exists:"body.eu-cookie-compliance-popup-open"}],detectPopup:[{exists:"body.eu-cookie-compliance-popup-open"}],optIn:[{click:".agree-button"}],optOut:[{if:{visible:".decline-button,.eu-cookie-compliance-save-preferences-button"},then:[{click:".decline-button,.eu-cookie-compliance-save-preferences-button"}]},{hide:".eu-cookie-compliance-banner-info, #sliding-popup"}],test:[{eval:"EVAL_EU_COOKIE_COMPLIANCE_0"}]},{name:"EU Cookie Law",prehideSelectors:[".pea_cook_wrapper,.pea_cook_more_info_popover"],cosmetic:!0,detectCmp:[{exists:".pea_cook_wrapper"}],detectPopup:[{wait:500},{visible:".pea_cook_wrapper"}],optIn:[{click:"#pea_cook_btn"}],optOut:[{hide:".pea_cook_wrapper"}],test:[{eval:"EVAL_EU_COOKIE_LAW_0"}]},{name:"europa-eu",vendorUrl:"https://ec.europa.eu/",runContext:{urlPattern:"^https://[^/]*europa\\.eu/"},prehideSelectors:["#cookie-consent-banner"],detectCmp:[{exists:".cck-container"}],detectPopup:[{visible:".cck-container"}],optIn:[{waitForThenClick:'.cck-actions-button[href="#accept"]'}],optOut:[{waitForThenClick:'.cck-actions-button[href="#refuse"]',hide:".cck-container"}]},{name:"EZoic",prehideSelectors:["#ez-cookie-dialog-wrapper"],detectCmp:[{exists:"#ez-cookie-dialog-wrapper"}],detectPopup:[{visible:"#ez-cookie-dialog-wrapper"}],optIn:[{click:"#ez-accept-all",optional:!0},{eval:"EVAL_EZOIC_0",optional:!0}],optOut:[{wait:500},{click:"#ez-manage-settings"},{waitFor:"#ez-cookie-dialog input[type=checkbox]"},{click:"#ez-cookie-dialog input[type=checkbox]:checked",all:!0},{click:"#ez-save-settings"}],test:[{eval:"EVAL_EZOIC_1"}]},{name:"facebook",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?facebook\\.com/"},prehideSelectors:['div[data-testid="cookie-policy-manage-dialog"]'],detectCmp:[{exists:'div[data-testid="cookie-policy-manage-dialog"]'}],detectPopup:[{visible:'div[data-testid="cookie-policy-manage-dialog"]'}],optIn:[{waitForThenClick:'button[data-cookiebanner="accept_button"]'},{waitForVisible:'div[data-testid="cookie-policy-manage-dialog"]',check:"none"}],optOut:[{waitForThenClick:'button[data-cookiebanner="accept_only_essential_button"]'},{waitForVisible:'div[data-testid="cookie-policy-manage-dialog"]',check:"none"}]},{name:"fides",vendorUrl:"https://github.com/ethyca/fides",prehideSelectors:["#fides-overlay"],detectCmp:[{exists:"#fides-overlay #fides-banner"}],detectPopup:[{visible:"#fides-overlay #fides-banner"},{eval:"EVAL_FIDES_DETECT_POPUP"}],optIn:[{waitForThenClick:"#fides-banner .fides-accept-all-button"}],optOut:[{waitForThenClick:"#fides-banner .fides-reject-all-button"}]},{name:"funding-choices",prehideSelectors:[".fc-consent-root,.fc-dialog-container,.fc-dialog-overlay,.fc-dialog-content"],detectCmp:[{exists:".fc-consent-root"}],detectPopup:[{exists:".fc-dialog-container"}],optOut:[{click:".fc-cta-do-not-consent,.fc-cta-manage-options"},{click:".fc-preference-consent:checked,.fc-preference-legitimate-interest:checked",all:!0,optional:!0},{click:".fc-confirm-choices",optional:!0}],optIn:[{click:".fc-cta-consent"}]},{name:"geeks-for-geeks",runContext:{urlPattern:"^https://www\\.geeksforgeeks\\.org/"},cosmetic:!0,prehideSelectors:[".cookie-consent"],detectCmp:[{exists:".cookie-consent"}],detectPopup:[{visible:".cookie-consent"}],optIn:[{click:".cookie-consent button.consent-btn"}],optOut:[{hide:".cookie-consent"}]},{name:"google-consent-standalone",prehideSelectors:[],detectCmp:[{exists:'a[href^="https://policies.google.com/technologies/cookies"'},{exists:'form[action^="https://consent.google."][action$="/save"]'}],detectPopup:[{visible:'a[href^="https://policies.google.com/technologies/cookies"'}],optIn:[{waitForThenClick:'form[action^="https://consent.google."][action$="/save"]:has(input[name=set_eom][value=false]) button'}],optOut:[{waitForThenClick:'form[action^="https://consent.google."][action$="/save"]:has(input[name=set_eom][value=true]) button'}]},{name:"google-cookiebar",vendorUrl:"https://www.android.com/better-together/quick-share-app/",cosmetic:!1,prehideSelectors:[".glue-cookie-notification-bar"],detectCmp:[{exists:".glue-cookie-notification-bar"}],detectPopup:[{visible:".glue-cookie-notification-bar"}],optIn:[{waitForThenClick:".glue-cookie-notification-bar__accept"}],optOut:[{if:{exists:".glue-cookie-notification-bar__reject"},then:[{click:".glue-cookie-notification-bar__reject"}],else:[{hide:".glue-cookie-notification-bar"}]}],test:[]},{name:"google.com",prehideSelectors:[".HTjtHe#xe7COe"],detectCmp:[{exists:".HTjtHe#xe7COe"},{exists:'.HTjtHe#xe7COe a[href^="https://policies.google.com/technologies/cookies"]'}],detectPopup:[{visible:".HTjtHe#xe7COe button#W0wltc"}],optIn:[{waitForThenClick:".HTjtHe#xe7COe button#L2AGLb"}],optOut:[{waitForThenClick:".HTjtHe#xe7COe button#W0wltc"}],test:[{eval:"EVAL_GOOGLE_0"}]},{name:"gov.uk",detectCmp:[{exists:"#global-cookie-message"}],detectPopup:[{exists:"#global-cookie-message"}],optIn:[{click:"button[data-accept-cookies=true]"}],optOut:[{click:"button[data-reject-cookies=true],#reject-cookies"},{click:"button[data-hide-cookie-banner=true],#hide-cookie-decision"}]},{name:"hashicorp",vendorUrl:"https://hashicorp.com/",runContext:{urlPattern:"^https://[^.]*\\.hashicorp\\.com/"},prehideSelectors:["[data-testid=consent-banner]"],detectCmp:[{exists:"[data-testid=consent-banner]"}],detectPopup:[{visible:"[data-testid=consent-banner]"}],optIn:[{waitForThenClick:"[data-testid=accept]"}],optOut:[{waitForThenClick:"[data-testid=manage-preferences]"},{waitForThenClick:"[data-testid=consent-mgr-dialog] [data-ga-button=save-preferences]"}]},{name:"healthline-media",prehideSelectors:["#modal-host > div.no-hash > div.window-wrapper"],detectCmp:[{exists:"#modal-host > div.no-hash > div.window-wrapper, div[data-testid=qualtrics-container]"}],detectPopup:[{exists:"#modal-host > div.no-hash > div.window-wrapper, div[data-testid=qualtrics-container]"}],optIn:[{click:"#modal-host > div.no-hash > div.window-wrapper > div:last-child button"}],optOut:[{if:{exists:'#modal-host > div.no-hash > div.window-wrapper > div:last-child a[href="/privacy-settings"]'},then:[{click:'#modal-host > div.no-hash > div.window-wrapper > div:last-child a[href="/privacy-settings"]'}],else:[{waitForVisible:"div#__next"},{click:"#__next div:nth-child(1) > button:first-child"}]}]},{name:"hema",prehideSelectors:[".cookie-modal"],detectCmp:[{visible:".cookie-modal .cookie-accept-btn"}],detectPopup:[{visible:".cookie-modal .cookie-accept-btn"}],optIn:[{waitForThenClick:".cookie-modal .cookie-accept-btn"}],optOut:[{waitForThenClick:".cookie-modal .js-cookie-reject-btn"}],test:[{eval:"EVAL_HEMA_TEST_0"}]},{name:"hetzner.com",runContext:{urlPattern:"^https://www\\.hetzner\\.com/"},prehideSelectors:["#CookieConsent"],detectCmp:[{exists:"#CookieConsent"}],detectPopup:[{visible:"#CookieConsent"}],optIn:[{click:"#CookieConsentGiven"}],optOut:[{click:"#CookieConsentDeclined"}]},{name:"hl.co.uk",prehideSelectors:[".cookieModalContent","#cookie-banner-overlay"],detectCmp:[{exists:"#cookie-banner-overlay"}],detectPopup:[{exists:"#cookie-banner-overlay"}],optIn:[{click:"#acceptCookieButton"}],optOut:[{click:"#manageCookie"},{hide:".cookieSettingsModal"},{waitFor:"#AOCookieToggle"},{click:"#AOCookieToggle[aria-pressed=true]",optional:!0},{waitFor:"#TPCookieToggle"},{click:"#TPCookieToggle[aria-pressed=true]",optional:!0},{click:"#updateCookieButton"}]},{name:"holidaymedia",vendorUrl:"https://holidaymedia.nl/",prehideSelectors:["dialog[data-cookie-consent]"],detectCmp:[{exists:"dialog[data-cookie-consent]"}],detectPopup:[{visible:"dialog[data-cookie-consent]"}],optIn:[{waitForThenClick:"button.cookie-consent__button--accept-all"}],optOut:[{waitForThenClick:'a[data-cookie-accept="functional"]',timeout:2e3}]},{name:"hu-manity",vendorUrl:"https://hu-manity.co/",prehideSelectors:["#hu.hu-wrapper"],detectCmp:[{exists:"#hu.hu-visible"}],detectPopup:[{visible:"#hu.hu-visible"}],optIn:[{waitForThenClick:"[data-hu-action=cookies-notice-consent-choices-3]"},{waitForThenClick:"#hu-cookies-save"}],optOut:[{waitForThenClick:"#hu-cookies-save"}]},{name:"hubspot",detectCmp:[{exists:"#hs-eu-cookie-confirmation"}],detectPopup:[{visible:"#hs-eu-cookie-confirmation"}],optIn:[{click:"#hs-eu-confirmation-button"}],optOut:[{click:"#hs-eu-decline-button"}]},{name:"indeed.com",cosmetic:!0,prehideSelectors:["#CookiePrivacyNotice"],detectCmp:[{exists:"#CookiePrivacyNotice"}],detectPopup:[{visible:"#CookiePrivacyNotice"}],optIn:[{click:"#CookiePrivacyNotice button[data-gnav-element-name=CookiePrivacyNoticeOk]"}],optOut:[{hide:"#CookiePrivacyNotice"}]},{name:"ing.de",runContext:{urlPattern:"^https://www\\.ing\\.de/"},cosmetic:!0,prehideSelectors:['div[slot="backdrop"]'],detectCmp:[{exists:'[data-tag-name="ing-cc-dialog-frame"]'}],detectPopup:[{visible:'[data-tag-name="ing-cc-dialog-frame"]'}],optIn:[{click:['[data-tag-name="ing-cc-dialog-level0"]','[data-tag-name="ing-cc-button"][class*="accept"]']}],optOut:[{click:['[data-tag-name="ing-cc-dialog-level0"]','[data-tag-name="ing-cc-button"][class*="more"]']}]},{name:"instagram",vendorUrl:"https://instagram.com",runContext:{urlPattern:"^https://www\\.instagram\\.com/"},prehideSelectors:[],detectCmp:[{exists:'xpath///span[contains(., "Vill du tillåta användningen av cookies från Instagram i den här webbläsaren?") or contains(., "Allow the use of cookies from Instagram on this browser?") or contains(., "Povolit v prohlížeči použití souborů cookie z Instagramu?") or contains(., "Dopustiti upotrebu kolačića s Instagrama na ovom pregledniku?") or contains(., "Разрешить использование файлов cookie от Instagram в этом браузере?") or contains(., "Vuoi consentire l\'uso dei cookie di Instagram su questo browser?") or contains(., "Povoliť používanie cookies zo služby Instagram v tomto prehliadači?") or contains(., "Die Verwendung von Cookies durch Instagram in diesem Browser erlauben?") or contains(., "Sallitaanko Instagramin evästeiden käyttö tällä selaimella?") or contains(., "Engedélyezed az Instagram cookie-jainak használatát ebben a böngészőben?") or contains(., "Het gebruik van cookies van Instagram toestaan in deze browser?") or contains(., "Bu tarayıcıda Instagram\'dan çerez kullanımına izin verilsin mi?") or contains(., "Permitir o uso de cookies do Instagram neste navegador?") or contains(., "Permiţi folosirea modulelor cookie de la Instagram în acest browser?") or contains(., "Autoriser l’utilisation des cookies d’Instagram sur ce navigateur ?") or contains(., "¿Permitir el uso de cookies de Instagram en este navegador?") or contains(., "Zezwolić na użycie plików cookie z Instagramu w tej przeglądarce?") or contains(., "Να επιτρέπεται η χρήση cookies από τo Instagram σε αυτό το πρόγραμμα περιήγησης;") or contains(., "Разрешавате ли използването на бисквитки от Instagram на този браузър?") or contains(., "Vil du tillade brugen af cookies fra Instagram i denne browser?") or contains(., "Vil du tillate bruk av informasjonskapsler fra Instagram i denne nettleseren?")]'}],detectPopup:[{visible:'xpath///span[contains(., "Vill du tillåta användningen av cookies från Instagram i den här webbläsaren?") or contains(., "Allow the use of cookies from Instagram on this browser?") or contains(., "Povolit v prohlížeči použití souborů cookie z Instagramu?") or contains(., "Dopustiti upotrebu kolačića s Instagrama na ovom pregledniku?") or contains(., "Разрешить использование файлов cookie от Instagram в этом браузере?") or contains(., "Vuoi consentire l\'uso dei cookie di Instagram su questo browser?") or contains(., "Povoliť používanie cookies zo služby Instagram v tomto prehliadači?") or contains(., "Die Verwendung von Cookies durch Instagram in diesem Browser erlauben?") or contains(., "Sallitaanko Instagramin evästeiden käyttö tällä selaimella?") or contains(., "Engedélyezed az Instagram cookie-jainak használatát ebben a böngészőben?") or contains(., "Het gebruik van cookies van Instagram toestaan in deze browser?") or contains(., "Bu tarayıcıda Instagram\'dan çerez kullanımına izin verilsin mi?") or contains(., "Permitir o uso de cookies do Instagram neste navegador?") or contains(., "Permiţi folosirea modulelor cookie de la Instagram în acest browser?") or contains(., "Autoriser l’utilisation des cookies d’Instagram sur ce navigateur ?") or contains(., "¿Permitir el uso de cookies de Instagram en este navegador?") or contains(., "Zezwolić na użycie plików cookie z Instagramu w tej przeglądarce?") or contains(., "Να επιτρέπεται η χρήση cookies από τo Instagram σε αυτό το πρόγραμμα περιήγησης;") or contains(., "Разрешавате ли използването на бисквитки от Instagram на този браузър?") or contains(., "Vil du tillade brugen af cookies fra Instagram i denne browser?") or contains(., "Vil du tillate bruk av informasjonskapsler fra Instagram i denne nettleseren?")]'}],optIn:[{waitForThenClick:"xpath///button[contains(., 'Tillad alle cookies') or contains(., 'Alle Cookies erlauben') or contains(., 'Allow all cookies') or contains(., 'Разрешаване на всички бисквитки') or contains(., 'Tillåt alla cookies') or contains(., 'Povolit všechny soubory cookie') or contains(., 'Tüm çerezlere izin ver') or contains(., 'Permite toate modulele cookie') or contains(., 'Να επιτρέπονται όλα τα cookies') or contains(., 'Tillat alle informasjonskapsler') or contains(., 'Povoliť všetky cookies') or contains(., 'Permitir todas las cookies') or contains(., 'Permitir todos os cookies') or contains(., 'Alle cookies toestaan') or contains(., 'Salli kaikki evästeet') or contains(., 'Consenti tutti i cookie') or contains(., 'Az összes cookie engedélyezése') or contains(., 'Autoriser tous les cookies') or contains(., 'Zezwól na wszystkie pliki cookie') or contains(., 'Разрешить все cookie') or contains(., 'Dopusti sve kolačiće')]"}],optOut:[{waitForThenClick:"xpath///button[contains(., 'Отклонить необязательные файлы cookie') or contains(., 'Decline optional cookies') or contains(., 'Refuser les cookies optionnels') or contains(., 'Hylkää valinnaiset evästeet') or contains(., 'Afvis valgfrie cookies') or contains(., 'Odmietnuť nepovinné cookies') or contains(., 'Απόρριψη προαιρετικών cookies') or contains(., 'Neka valfria cookies') or contains(., 'Optionale Cookies ablehnen') or contains(., 'Rifiuta cookie facoltativi') or contains(., 'Odbij neobavezne kolačiće') or contains(., 'Avvis valgfrie informasjonskapsler') or contains(., 'İsteğe bağlı çerezleri reddet') or contains(., 'Recusar cookies opcionais') or contains(., 'Optionele cookies afwijzen') or contains(., 'Rechazar cookies opcionales') or contains(., 'Odrzuć opcjonalne pliki cookie') or contains(., 'Отхвърляне на бисквитките по избор') or contains(., 'Odmítnout volitelné soubory cookie') or contains(., 'Refuză modulele cookie opţionale') or contains(., 'A nem kötelező cookie-k elutasítása')]"},{wait:2e3}]},{name:"ionos.de",prehideSelectors:[".privacy-consent--backdrop",".privacy-consent--modal"],detectCmp:[{exists:".privacy-consent--modal"}],detectPopup:[{visible:".privacy-consent--modal"}],optIn:[{click:"#selectAll"}],optOut:[{click:".footer-config-link"},{click:"#confirmSelection"}]},{name:"itopvpn.com",cosmetic:!0,prehideSelectors:[".pop-cookie"],detectCmp:[{exists:".pop-cookie"}],detectPopup:[{exists:".pop-cookie"}],optIn:[{click:"#_pcookie"}],optOut:[{hide:".pop-cookie"}]},{name:"iubenda",prehideSelectors:["#iubenda-cs-banner"],detectCmp:[{exists:"#iubenda-cs-banner"}],detectPopup:[{visible:".iubenda-cs-accept-btn"}],optIn:[{waitForThenClick:".iubenda-cs-accept-btn"}],optOut:[{waitForThenClick:".iubenda-cs-customize-btn"},{eval:"EVAL_IUBENDA_0"},{waitForThenClick:"#iubFooterBtn"}],test:[{eval:"EVAL_IUBENDA_1"}]},{name:"iWink",prehideSelectors:["body.cookies-request #cookie-bar"],detectCmp:[{exists:"body.cookies-request #cookie-bar"}],detectPopup:[{visible:"body.cookies-request #cookie-bar"}],optIn:[{waitForThenClick:"body.cookies-request #cookie-bar .allow-cookies"}],optOut:[{waitForThenClick:"body.cookies-request #cookie-bar .disallow-cookies"}],test:[{eval:"EVAL_IWINK_TEST"}]},{name:"jdsports",vendorUrl:"https://www.jdsports.co.uk/",runContext:{urlPattern:"^https://(www|m)\\.jdsports\\."},prehideSelectors:[".miniConsent,#PrivacyPolicyBanner"],detectCmp:[{exists:".miniConsent,#PrivacyPolicyBanner"}],detectPopup:[{visible:".miniConsent,#PrivacyPolicyBanner"}],optIn:[{waitForThenClick:".miniConsent .accept-all-cookies"}],optOut:[{if:{exists:"#PrivacyPolicyBanner"},then:[{hide:"#PrivacyPolicyBanner"}],else:[{waitForThenClick:"#cookie-settings"},{waitForThenClick:"#reject-all-cookies"}]}]},{name:"johnlewis.com",prehideSelectors:["div[class^=pecr-cookie-banner-]"],detectCmp:[{exists:"div[class^=pecr-cookie-banner-]"}],detectPopup:[{exists:"div[class^=pecr-cookie-banner-]"}],optOut:[{click:"button[data-test^=manage-cookies]"},{wait:"500"},{click:"label[data-test^=toggle][class*=checked]:not([class*=disabled])",all:!0,optional:!0},{click:"button[data-test=save-preferences]"}],optIn:[{click:"button[data-test=allow-all]"}]},{name:"jquery.cookieBar",vendorUrl:"https://github.com/kovarp/jquery.cookieBar",prehideSelectors:[".cookie-bar"],cosmetic:!0,detectCmp:[{exists:".cookie-bar .cookie-bar__message,.cookie-bar .cookie-bar__buttons"}],detectPopup:[{visible:".cookie-bar .cookie-bar__message,.cookie-bar .cookie-bar__buttons",check:"any"}],optIn:[{click:".cookie-bar .cookie-bar__btn"}],optOut:[{hide:".cookie-bar"}],test:[{visible:".cookie-bar .cookie-bar__message,.cookie-bar .cookie-bar__buttons",check:"none"},{eval:"EVAL_JQUERY_COOKIEBAR_0"}]},{name:"justwatch.com",prehideSelectors:[".consent-banner"],detectCmp:[{exists:".consent-banner .consent-banner__actions"}],detectPopup:[{visible:".consent-banner .consent-banner__actions"}],optIn:[{click:".consent-banner__actions button.basic-button.primary"}],optOut:[{click:".consent-banner__actions button.basic-button.secondary"},{waitForThenClick:".consent-modal__footer button.basic-button.secondary"},{waitForThenClick:".consent-modal ion-content > div > a:nth-child(9)"},{click:"label.consent-switch input[type=checkbox]:checked",all:!0,optional:!0},{waitForVisible:".consent-modal__footer button.basic-button.primary"},{click:".consent-modal__footer button.basic-button.primary"}]},{name:"kconsent",cosmetic:!1,runContext:{main:!0,frame:!1},prehideSelectors:[".kc-overlay"],detectCmp:[{exists:"#kconsent"}],detectPopup:[{visible:".kc-dialog"}],optIn:[{waitForThenClick:"#kc-acceptAndHide"}],optOut:[{waitForThenClick:"#kc-denyAndHide"}]},{name:"ketch",vendorUrl:"https://www.ketch.com",runContext:{frame:!1,main:!0},intermediate:!1,prehideSelectors:["#lanyard_root div[role='dialog']"],detectCmp:[{exists:"#lanyard_root div[role='dialog']"}],detectPopup:[{visible:"#lanyard_root div[role='dialog']"}],optIn:[{if:{exists:"#lanyard_root button[class='confirmButton']"},then:[{waitForThenClick:"#lanyard_root div[class*=buttons] > :nth-child(2)"},{click:"#lanyard_root button[class='confirmButton']"}],else:[{waitForThenClick:"#lanyard_root div[class*=buttons] > :nth-child(2)"}]}],optOut:[{if:{exists:"#lanyard_root [aria-describedby=banner-description]"},then:[{waitForThenClick:"#lanyard_root div[class*=buttons] > button[class*=secondaryButton], #lanyard_root button[class*=buttons-secondary]",comment:"can be either settings or reject button"}]},{waitFor:"#lanyard_root [aria-describedby=preference-description],#lanyard_root [aria-describedby=modal-description], #ketch-preferences",timeout:1e3,optional:!0},{if:{exists:"#lanyard_root [aria-describedby=preference-description],#lanyard_root [aria-describedby=modal-description], #ketch-preferences"},then:[{waitForThenClick:"#lanyard_root button[class*=rejectButton], #lanyard_root button[class*=rejectAllButton]"},{click:"#lanyard_root button[class*=confirmButton],#lanyard_root div[class*=actions_] > button:nth-child(1), #lanyard_root button[class*=actionButton]"}]}],test:[{eval:"EVAL_KETCH_TEST"}]},{name:"kleinanzeigen-de",runContext:{urlPattern:"^https?://(www\\.)?kleinanzeigen\\.de"},prehideSelectors:["#gdpr-banner-container"],detectCmp:[{any:[{exists:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-cmp-button]"},{exists:"#ConsentManagementPage"}]}],detectPopup:[{any:[{visible:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-cmp-button]"},{visible:"#ConsentManagementPage"}]}],optIn:[{if:{exists:"#gdpr-banner-container #gdpr-banner"},then:[{click:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-accept]"}],else:[{click:"#ConsentManagementPage .Button-primary"}]}],optOut:[{if:{exists:"#gdpr-banner-container #gdpr-banner"},then:[{click:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-cmp-button]"}],else:[{click:"#ConsentManagementPage .Button-secondary"}]}]},{name:"lightbox",prehideSelectors:[".darken-layer.open,.lightbox.lightbox--cookie-consent"],detectCmp:[{exists:"body.cookie-consent-is-active div.lightbox--cookie-consent > div.lightbox__content > div.cookie-consent[data-jsb]"}],detectPopup:[{visible:"body.cookie-consent-is-active div.lightbox--cookie-consent > div.lightbox__content > div.cookie-consent[data-jsb]"}],optOut:[{click:".cookie-consent__footer > button[type='submit']:not([data-button='selectAll'])"}],optIn:[{click:".cookie-consent__footer > button[type='submit'][data-button='selectAll']"}]},{name:"lineagrafica",vendorUrl:"https://addons.prestashop.com/en/legal/8734-eu-cookie-law-gdpr-banner-blocker.html",cosmetic:!0,prehideSelectors:["#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"],detectCmp:[{exists:"#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"}],detectPopup:[{exists:"#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"}],optIn:[{waitForThenClick:"#lgcookieslaw_accept"}],optOut:[{hide:"#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"}]},{name:"linkedin.com",prehideSelectors:[".artdeco-global-alert[type=COOKIE_CONSENT]"],detectCmp:[{exists:".artdeco-global-alert[type=COOKIE_CONSENT]"}],detectPopup:[{visible:".artdeco-global-alert[type=COOKIE_CONSENT]"}],optIn:[{waitForVisible:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=ACCEPT]"},{wait:500},{waitForThenClick:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=ACCEPT]"}],optOut:[{waitForVisible:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=DENY]"},{wait:500},{waitForThenClick:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=DENY]"}],test:[{waitForVisible:".artdeco-global-alert[type=COOKIE_CONSENT]",check:"none"}]},{name:"livejasmin",vendorUrl:"https://www.livejasmin.com/",runContext:{urlPattern:"^https://(m|www)\\.livejasmin\\.com/"},prehideSelectors:["#consent_modal"],detectCmp:[{exists:"#consent_modal"}],detectPopup:[{visible:"#consent_modal"}],optIn:[{waitForThenClick:"#consent_modal button[data-testid=ButtonStyledButton]:first-of-type"}],optOut:[{waitForThenClick:"#consent_modal button[data-testid=ButtonStyledButton]:nth-of-type(2)"},{waitForVisible:"[data-testid=PrivacyPreferenceCenterWithConsentCookieContent]"},{click:"[data-testid=PrivacyPreferenceCenterWithConsentCookieContent] input[data-testid=PrivacyPreferenceCenterWithConsentCookieSwitch]:checked",optional:!0,all:!0},{waitForThenClick:"[data-testid=PrivacyPreferenceCenterWithConsentCookieContent] button[data-testid=ButtonStyledButton]:last-child"}]},{name:"macpaw.com",cosmetic:!0,prehideSelectors:['div[data-banner="cookies"]'],detectCmp:[{exists:'div[data-banner="cookies"]'}],detectPopup:[{exists:'div[data-banner="cookies"]'}],optIn:[{click:'button[data-banner-close="cookies"]'}],optOut:[{hide:'div[data-banner="cookies"]'}]},{name:"marksandspencer.com",cosmetic:!0,detectCmp:[{exists:".navigation-cookiebbanner"}],detectPopup:[{visible:".navigation-cookiebbanner"}],optOut:[{hide:".navigation-cookiebbanner"}],optIn:[{click:".navigation-cookiebbanner__submit"}]},{name:"mediamarkt.de",prehideSelectors:["div[aria-labelledby=pwa-consent-layer-title]","div[class^=StyledConsentLayerWrapper-]"],detectCmp:[{exists:"div[aria-labelledby^=pwa-consent-layer-title]"}],detectPopup:[{exists:"div[aria-labelledby^=pwa-consent-layer-title]"}],optOut:[{click:"button[data-test^=pwa-consent-layer-deny-all]"}],optIn:[{click:"button[data-test^=pwa-consent-layer-accept-all"}]},{name:"Mediavine",prehideSelectors:['[data-name="mediavine-gdpr-cmp"]'],detectCmp:[{exists:'[data-name="mediavine-gdpr-cmp"]'}],detectPopup:[{wait:500},{visible:'[data-name="mediavine-gdpr-cmp"]'}],optIn:[{waitForThenClick:'[data-name="mediavine-gdpr-cmp"] [format="primary"]'}],optOut:[{waitForThenClick:'[data-name="mediavine-gdpr-cmp"] [data-view="manageSettings"]'},{waitFor:'[data-name="mediavine-gdpr-cmp"] input[type=checkbox]'},{eval:"EVAL_MEDIAVINE_0",optional:!0},{click:'[data-name="mediavine-gdpr-cmp"] [format="secondary"]'}]},{name:"medium",vendorUrl:"https://medium.com",cosmetic:!0,runContext:{main:!0,frame:!1,urlPattern:"^https://([a-z0-9-]+\\.)?medium\\.com/"},prehideSelectors:[],detectCmp:[{exists:'div:has(> div > div > div[role=alert] > a[href^="https://policy.medium.com/medium-privacy-policy-"])'}],detectPopup:[{visible:'div:has(> div > div > div[role=alert] > a[href^="https://policy.medium.com/medium-privacy-policy-"])'}],optIn:[{waitForThenClick:"[data-testid=close-button]"}],optOut:[{hide:'div:has(> div > div > div[role=alert] > a[href^="https://policy.medium.com/medium-privacy-policy-"])'}]},{name:"microsoft.com",prehideSelectors:["#wcpConsentBannerCtrl"],detectCmp:[{exists:"#wcpConsentBannerCtrl"}],detectPopup:[{exists:"#wcpConsentBannerCtrl"}],optOut:[{eval:"EVAL_MICROSOFT_0"}],optIn:[{eval:"EVAL_MICROSOFT_1"}],test:[{eval:"EVAL_MICROSOFT_2"}]},{name:"midway-usa",runContext:{urlPattern:"^https://www\\.midwayusa\\.com/"},cosmetic:!0,prehideSelectors:["#cookie-container"],detectCmp:[{exists:['div[aria-label="Cookie Policy Banner"]']}],detectPopup:[{visible:"#cookie-container"}],optIn:[{click:"button#cookie-btn"}],optOut:[{hide:'div[aria-label="Cookie Policy Banner"]'}]},{name:"moneysavingexpert.com",detectCmp:[{exists:"dialog[data-testid=accept-our-cookies-dialog]"}],detectPopup:[{visible:"dialog[data-testid=accept-our-cookies-dialog]"}],optIn:[{click:"#banner-accept"}],optOut:[{click:"#banner-manage"},{click:"#pc-confirm"}]},{name:"monzo.com",prehideSelectors:[".cookie-alert, cookie-alert__content"],detectCmp:[{exists:'div.cookie-alert[role="dialog"]'},{exists:'a[href*="monzo"]'}],detectPopup:[{visible:".cookie-alert__content"}],optIn:[{click:".js-accept-cookie-policy"}],optOut:[{click:".js-decline-cookie-policy"}]},{name:"Moove",prehideSelectors:["#moove_gdpr_cookie_info_bar"],detectCmp:[{exists:"#moove_gdpr_cookie_info_bar"}],detectPopup:[{visible:"#moove_gdpr_cookie_info_bar:not(.moove-gdpr-info-bar-hidden)"}],optIn:[{waitForThenClick:".moove-gdpr-infobar-allow-all"}],optOut:[{if:{exists:"#moove_gdpr_cookie_info_bar .change-settings-button"},then:[{click:"#moove_gdpr_cookie_info_bar .change-settings-button"},{waitForVisible:"#moove_gdpr_cookie_modal"},{eval:"EVAL_MOOVE_0"},{click:".moove-gdpr-modal-save-settings"}],else:[{hide:"#moove_gdpr_cookie_info_bar"}]}],test:[{visible:"#moove_gdpr_cookie_info_bar",check:"none"}]},{name:"national-lottery.co.uk",detectCmp:[{exists:".cuk_cookie_consent"}],detectPopup:[{visible:".cuk_cookie_consent",check:"any"}],optOut:[{click:".cuk_cookie_consent_manage_pref"},{click:".cuk_cookie_consent_save_pref"},{click:".cuk_cookie_consent_close"}],optIn:[{click:".cuk_cookie_consent_accept_all"}]},{name:"nba.com",runContext:{urlPattern:"^https://(www\\.)?nba.com/"},cosmetic:!0,prehideSelectors:["#onetrust-banner-sdk"],detectCmp:[{exists:"#onetrust-banner-sdk"}],detectPopup:[{visible:"#onetrust-banner-sdk"}],optIn:[{click:"#onetrust-accept-btn-handler"}],optOut:[{hide:"#onetrust-banner-sdk"}]},{name:"netbeat.de",runContext:{urlPattern:"^https://(www\\.)?netbeat\\.de/"},prehideSelectors:["div#cookieWarning"],detectCmp:[{exists:"div#cookieWarning"}],detectPopup:[{visible:"div#cookieWarning"}],optIn:[{waitForThenClick:"a#btnCookiesAcceptAll"}],optOut:[{waitForThenClick:"a#btnCookiesDenyAll"}]},{name:"netflix.de",detectCmp:[{exists:"#cookie-disclosure"}],detectPopup:[{visible:".cookie-disclosure-message",check:"any"}],optIn:[{click:".btn-accept"}],optOut:[{hide:"#cookie-disclosure"},{click:".btn-reject"}]},{name:"nhs.uk",prehideSelectors:["#nhsuk-cookie-banner"],detectCmp:[{exists:"#nhsuk-cookie-banner"}],detectPopup:[{exists:"#nhsuk-cookie-banner"}],optOut:[{click:"#nhsuk-cookie-banner__link_accept"}],optIn:[{click:"#nhsuk-cookie-banner__link_accept_analytics"}]},{name:"nike",vendorUrl:"https://nike.com",runContext:{urlPattern:"^https://(www\\.)?nike\\.com/"},prehideSelectors:[],detectCmp:[{exists:"[data-testid=cookie-dialog-root]"}],detectPopup:[{visible:"[data-testid=cookie-dialog-root]"}],optIn:[{waitForThenClick:"[data-testid=dialog-accept-button]"}],optOut:[{waitForThenClick:"input[type=radio][id$=-declineLabel]",all:!0},{waitForThenClick:"[data-testid=confirm-choice-button]"}]},{name:"notice-cookie",prehideSelectors:[".button--notice"],cosmetic:!0,detectCmp:[{exists:".notice--cookie"}],detectPopup:[{visible:".notice--cookie"}],optIn:[{click:".button--notice"}],optOut:[{hide:".notice--cookie"}]},{name:"nrk.no",cosmetic:!0,prehideSelectors:[".nrk-masthead__info-banner--cookie"],detectCmp:[{exists:".nrk-masthead__info-banner--cookie"}],detectPopup:[{exists:".nrk-masthead__info-banner--cookie"}],optIn:[{click:"div.nrk-masthead__info-banner--cookie button > span:has(+ svg.nrk-close)"}],optOut:[{hide:".nrk-masthead__info-banner--cookie"}]},{name:"obi.de",prehideSelectors:[".disc-cp--active"],detectCmp:[{exists:".disc-cp-modal__modal"}],detectPopup:[{visible:".disc-cp-modal__modal"}],optIn:[{click:".js-disc-cp-accept-all"}],optOut:[{click:".js-disc-cp-deny-all"}]},{name:"om",vendorUrl:"https://olli-machts.de/en/extension/cookie-manager",prehideSelectors:[".tx-om-cookie-consent"],detectCmp:[{exists:".tx-om-cookie-consent .active[data-omcookie-panel]"}],detectPopup:[{exists:".tx-om-cookie-consent .active[data-omcookie-panel]"}],optIn:[{waitForThenClick:"[data-omcookie-panel-save=all]"}],optOut:[{if:{exists:"[data-omcookie-panel-save=min]"},then:[{waitForThenClick:"[data-omcookie-panel-save=min]"}],else:[{click:"input[data-omcookie-panel-grp]:checked:not(:disabled)",all:!0,optional:!0},{waitForThenClick:"[data-omcookie-panel-save=save]"}]}]},{name:"onlyFans.com",runContext:{urlPattern:"^https://onlyfans\\.com/"},prehideSelectors:["div.b-cookies-informer"],detectCmp:[{exists:"div.b-cookies-informer"}],detectPopup:[{exists:"div.b-cookies-informer"}],optIn:[{click:"div.b-cookies-informer__nav > button:nth-child(2)"}],optOut:[{click:"div.b-cookies-informer__nav > button:nth-child(1)"},{if:{exists:"div.b-cookies-informer__switchers"},then:[{click:"div.b-cookies-informer__switchers input:not([disabled])",all:!0},{click:"div.b-cookies-informer__nav > button"}]}]},{name:"openai",vendorUrl:"https://platform.openai.com/",cosmetic:!1,runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?openai\\.com/"},prehideSelectors:["[data-testid=cookie-consent-banner]"],detectCmp:[{exists:"[data-testid=cookie-consent-banner]"}],detectPopup:[{visible:"[data-testid=cookie-consent-banner]"}],optIn:[{waitForThenClick:"xpath///button[contains(., 'Accept all')]"}],optOut:[{waitForThenClick:"xpath///button[contains(., 'Reject all')]"}],test:[{wait:500},{eval:"EVAL_OPENAI_TEST"}]},{name:"openli",vendorUrl:"https://openli.com",prehideSelectors:[".legalmonster-cleanslate"],detectCmp:[{exists:".legalmonster-cleanslate"}],detectPopup:[{visible:".legalmonster-cleanslate #lm-cookie-wall-container",check:"any"}],optIn:[{waitForThenClick:"#lm-accept-all"}],optOut:[{waitForThenClick:"#lm-accept-necessary"}]},{name:"opera.com",vendorUrl:"https://unknown",cosmetic:!1,runContext:{main:!0,frame:!1},intermediate:!1,prehideSelectors:[],detectCmp:[{exists:"#cookie-consent .manage-cookies__btn"}],detectPopup:[{visible:"#cookie-consent .cookie-basic-consent__btn"}],optIn:[{waitForThenClick:"#cookie-consent .cookie-basic-consent__btn"}],optOut:[{waitForThenClick:"#cookie-consent .manage-cookies__btn"},{waitForThenClick:"#cookie-consent .active.marketing_option_switch.cookie-consent__switch",all:!0},{waitForThenClick:"#cookie-consent .cookie-selection__btn"}],test:[{eval:"EVAL_OPERA_0"}]},{name:"osano",prehideSelectors:[".osano-cm-window,.osano-cm-dialog"],detectCmp:[{exists:".osano-cm-window"}],detectPopup:[{visible:".osano-cm-dialog"}],optIn:[{click:".osano-cm-accept-all",optional:!0}],optOut:[{waitForThenClick:".osano-cm-denyAll"}]},{name:"otto.de",prehideSelectors:[".cookieBanner--visibility"],detectCmp:[{exists:".cookieBanner--visibility"}],detectPopup:[{visible:".cookieBanner__wrapper"}],optIn:[{click:".js_cookieBannerPermissionButton"}],optOut:[{click:".js_cookieBannerProhibitionButton"}]},{name:"ourworldindata",vendorUrl:"https://ourworldindata.org/",runContext:{urlPattern:"^https://ourworldindata\\.org/"},prehideSelectors:[".cookie-manager"],detectCmp:[{exists:".cookie-manager"}],detectPopup:[{visible:".cookie-manager .cookie-notice.open"}],optIn:[{waitForThenClick:".cookie-notice [data-test=accept]"}],optOut:[{waitForThenClick:".cookie-notice [data-test=reject]"}]},{name:"pabcogypsum",vendorUrl:"https://unknown",prehideSelectors:[".js-cookie-notice:has(#cookie_settings-form)"],detectCmp:[{exists:".js-cookie-notice #cookie_settings-form"}],detectPopup:[{visible:".js-cookie-notice #cookie_settings-form"}],optIn:[{waitForThenClick:".js-cookie-notice button[value=allow]"}],optOut:[{waitForThenClick:".js-cookie-notice button[value=disable]"}]},{name:"paypal-us",prehideSelectors:["#ccpaCookieContent_wrapper, article.ppvx_modal--overpanel"],detectCmp:[{exists:"#ccpaCookieBanner, .privacy-sheet-content"}],detectPopup:[{visible:"#ccpaCookieBanner, .privacy-sheet-content"}],optIn:[{click:"#acceptAllButton"}],optOut:[{if:{exists:"#bannerDeclineButton"},then:[{click:"#bannerDeclineButton"}],else:[{if:{exists:"a#manageCookiesLink"},then:[{click:"a#manageCookiesLink"}],else:[{waitForVisible:".privacy-sheet-content #formContent"},{click:"#formContent .cookiepref-11m2iee-checkbox_base input:checked",all:!0,optional:!0},{click:".cookieAction.saveCookie,.confirmCookie #submitCookiesBtn"}]}]}]},{name:"paypal.com",prehideSelectors:["#gdprCookieBanner"],detectCmp:[{exists:"#gdprCookieBanner"}],detectPopup:[{visible:"#gdprCookieContent_wrapper"}],optIn:[{click:"#acceptAllButton"}],optOut:[{wait:200},{click:".gdprCookieBanner_decline-button"}],test:[{wait:500},{eval:"EVAL_PAYPAL_0"}]},{name:"pinetools.com",cosmetic:!0,prehideSelectors:["#aviso_cookies"],detectCmp:[{exists:"#aviso_cookies"}],detectPopup:[{exists:".lang_en #aviso_cookies"}],optIn:[{click:"#aviso_cookies .a_boton_cerrar"}],optOut:[{hide:"#aviso_cookies"}]},{name:"pinterest-business",vendorUrl:"https://business.pinterest.com/",runContext:{urlPattern:"^https://.*\\.pinterest\\.com/"},prehideSelectors:[".BusinessCookieConsent"],detectCmp:[{exists:".BusinessCookieConsent"}],detectPopup:[{visible:".BusinessCookieConsent [data-id=cookie-consent-banner-buttons]"}],optIn:[{waitForThenClick:"[data-id=cookie-consent-banner-buttons] > div:nth-child(1) button"}],optOut:[{waitForThenClick:"[data-id=cookie-consent-banner-buttons] > div:nth-child(2) button"}]},{name:"pmc",cosmetic:!0,prehideSelectors:["#pmc-pp-tou--notice"],detectCmp:[{exists:"#pmc-pp-tou--notice"}],detectPopup:[{visible:"#pmc-pp-tou--notice"}],optIn:[{click:"span.pmc-pp-tou--notice-close-btn"}],optOut:[{hide:"#pmc-pp-tou--notice"}]},{name:"pornhub.com",runContext:{urlPattern:"^https://(www\\.)?pornhub\\.com/"},cosmetic:!1,prehideSelectors:["#cookieBanner #cookieBannerContent"],detectCmp:[{exists:"#cookieBanner #cookieBannerContent"}],detectPopup:[{visible:"#cookieBanner #cookieBannerContent"}],optIn:[{waitForThenClick:"#cookieBanner [data-label=accept_all]"}],optOut:[{waitForThenClick:"#cookieBanner [data-label=accept_essential]"}]},{name:"pornpics.com",cosmetic:!0,prehideSelectors:["#cookie-contract"],detectCmp:[{exists:"#cookie-contract"}],detectPopup:[{visible:"#cookie-contract"}],optIn:[{click:"#cookie-contract .icon-cross"}],optOut:[{hide:"#cookie-contract"}]},{name:"PrimeBox CookieBar",prehideSelectors:["#cookie-bar"],detectCmp:[{exists:"#cookie-bar .cb-enable,#cookie-bar .cb-disable,#cookie-bar .cb-policy"}],detectPopup:[{visible:"#cookie-bar .cb-enable,#cookie-bar .cb-disable,#cookie-bar .cb-policy",check:"any"}],optIn:[{waitForThenClick:"#cookie-bar .cb-enable"}],optOut:[{click:"#cookie-bar .cb-disable",optional:!0},{hide:"#cookie-bar"}],test:[{eval:"EVAL_PRIMEBOX_0"}]},{name:"privacymanager.io",prehideSelectors:["#gdpr-consent-tool-wrapper",'iframe[src^="https://cmp-consent-tool.privacymanager.io"]'],runContext:{urlPattern:"^https://cmp-consent-tool\\.privacymanager\\.io/",main:!1,frame:!0},detectCmp:[{exists:"button#save"}],detectPopup:[{visible:"button#save"}],optIn:[{click:"button#save"}],optOut:[{if:{exists:"#denyAll"},then:[{click:"#denyAll"},{waitForThenClick:".okButton"}],else:[{waitForThenClick:"#manageSettings"},{waitFor:".purposes-overview-list"},{waitFor:"button#saveAndExit"},{click:"span[role=checkbox][aria-checked=true]",all:!0,optional:!0},{click:"button#saveAndExit"}]}]},{name:"productz.com",vendorUrl:"https://productz.com/",runContext:{urlPattern:"^https://productz\\.com/"},prehideSelectors:[],detectCmp:[{exists:".c-modal.is-active"}],detectPopup:[{visible:".c-modal.is-active"}],optIn:[{waitForThenClick:".c-modal.is-active .is-accept"}],optOut:[{waitForThenClick:".c-modal.is-active .is-dismiss"}]},{name:"pubtech",prehideSelectors:["#pubtech-cmp"],detectCmp:[{exists:"#pubtech-cmp"}],detectPopup:[{visible:"#pubtech-cmp #pt-actions"}],optIn:[{if:{exists:"#pt-accept-all"},then:[{click:"#pubtech-cmp #pt-actions #pt-accept-all"}],else:[{click:"#pubtech-cmp #pt-actions button:nth-of-type(2)"}]}],optOut:[{click:"#pubtech-cmp #pt-close"}],test:[{eval:"EVAL_PUBTECH_0"}]},{name:"quantcast",prehideSelectors:["#qc-cmp2-main,#qc-cmp2-container"],detectCmp:[{exists:"#qc-cmp2-container"}],detectPopup:[{visible:"#qc-cmp2-ui"}],optOut:[{waitFor:'.qc-cmp2-summary-buttons > button[mode="secondary"]',timeout:2e3},{if:{exists:'.qc-cmp2-summary-buttons > button[mode="secondary"]:nth-of-type(2)'},then:[{click:'.qc-cmp2-summary-buttons > button[mode="secondary"]:nth-of-type(2)'}],else:[{click:'.qc-cmp2-summary-buttons > button[mode="secondary"]:nth-of-type(1)'},{waitFor:"#qc-cmp2-ui"},{click:'.qc-cmp2-toggle-switch > button[aria-checked="true"]',all:!0,optional:!0},{click:'.qc-cmp2-main button[aria-label="REJECT ALL"]',optional:!0},{waitForThenClick:'.qc-cmp2-main button[aria-label="SAVE & EXIT"],.qc-cmp2-buttons-desktop > button[mode="primary"]',timeout:5e3}]}],optIn:[{click:'.qc-cmp2-summary-buttons > button[mode="primary"]'}]},{name:"reddit.com",runContext:{urlPattern:"^https://www\\.reddit\\.com/"},prehideSelectors:["[bundlename=reddit_cookie_banner]"],detectCmp:[{exists:"reddit-cookie-banner"}],detectPopup:[{visible:"reddit-cookie-banner"}],optIn:[{waitForThenClick:["reddit-cookie-banner","#accept-all-cookies-button > button"]}],optOut:[{waitForThenClick:["reddit-cookie-banner","#reject-nonessential-cookies-button > button"]}],test:[{eval:"EVAL_REDDIT_0"}]},{name:"roblox",vendorUrl:"https://roblox.com",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?roblox\\.com/"},prehideSelectors:[],detectCmp:[{exists:".cookie-banner-wrapper"}],detectPopup:[{visible:".cookie-banner-wrapper .cookie-banner"}],optIn:[{waitForThenClick:".cookie-banner-wrapper button.btn-cta-lg"}],optOut:[{waitForThenClick:".cookie-banner-wrapper button.btn-secondary-lg"}],test:[{eval:"EVAL_ROBLOX_TEST"}]},{name:"rog-forum.asus.com",runContext:{urlPattern:"^https://rog-forum\\.asus\\.com/"},prehideSelectors:["#cookie-policy-info"],detectCmp:[{exists:"#cookie-policy-info"}],detectPopup:[{visible:"#cookie-policy-info"}],optIn:[{click:'div.cookie-btn-box > div[aria-label="Accept"]'}],optOut:[{click:'div.cookie-btn-box > div[aria-label="Reject"]'},{waitForThenClick:'.cookie-policy-lightbox-bottom > div[aria-label="Save Settings"]'}]},{name:"roofingmegastore.co.uk",runContext:{urlPattern:"^https://(www\\.)?roofingmegastore\\.co\\.uk"},prehideSelectors:["#m-cookienotice"],detectCmp:[{exists:"#m-cookienotice"}],detectPopup:[{visible:"#m-cookienotice"}],optIn:[{click:"#accept-cookies"}],optOut:[{click:"#manage-cookies"},{waitForThenClick:"#accept-selected"}]},{name:"samsung.com",runContext:{urlPattern:"^https://www\\.samsung\\.com/"},cosmetic:!0,prehideSelectors:["div.cookie-bar"],detectCmp:[{exists:"div.cookie-bar"}],detectPopup:[{visible:"div.cookie-bar"}],optIn:[{click:"div.cookie-bar__manage > a"}],optOut:[{hide:"div.cookie-bar"}]},{name:"setapp.com",vendorUrl:"https://setapp.com/",cosmetic:!0,runContext:{urlPattern:"^https://setapp\\.com/"},prehideSelectors:[],detectCmp:[{exists:".cookie-banner.js-cookie-banner"}],detectPopup:[{visible:".cookie-banner.js-cookie-banner"}],optIn:[{waitForThenClick:".cookie-banner.js-cookie-banner button"}],optOut:[{hide:".cookie-banner.js-cookie-banner"}]},{name:"sibbo",prehideSelectors:["sibbo-cmp-layout"],detectCmp:[{exists:"sibbo-cmp-layout"}],detectPopup:[{visible:"#rejectAllMain"}],optIn:[{click:"#acceptAllMain"}],optOut:[{click:"#rejectAllMain"}]},{name:"similarweb.com",cosmetic:!0,prehideSelectors:[".app-cookies-notification"],detectCmp:[{exists:".app-cookies-notification"}],detectPopup:[{exists:".app-layout .app-cookies-notification"}],optIn:[{click:"button.app-cookies-notification__dismiss"}],optOut:[{hide:".app-layout .app-cookies-notification"}]},{name:"Sirdata",cosmetic:!1,prehideSelectors:["#sd-cmp"],detectCmp:[{exists:"#sd-cmp"}],detectPopup:[{visible:"#sd-cmp"}],optIn:[{waitForThenClick:"#sd-cmp .sd-cmp-3cRQ2"}],optOut:[{waitForThenClick:["#sd-cmp","xpath///span[contains(., 'Do not accept') or contains(., 'Acceptera inte') or contains(., 'No aceptar') or contains(., 'Ikke acceptere') or contains(., 'Nicht akzeptieren') or contains(., 'Не приемам') or contains(., 'Να μην γίνει αποδοχή') or contains(., 'Niet accepteren') or contains(., 'Nepřijímat') or contains(., 'Nie akceptuj') or contains(., 'Nu acceptați') or contains(., 'Não aceitar') or contains(., 'Continuer sans accepter') or contains(., 'Non accettare') or contains(., 'Nem fogad el')]"]}]},{name:"skyscanner",vendorUrl:"https://skyscanner.com",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?skyscanner[\\.a-z]+/"},prehideSelectors:[".cookie-banner-wrapper"],detectCmp:[{exists:"#cookieBannerContent"}],detectPopup:[{visible:"#cookieBannerContent"}],optIn:[{waitForThenClick:"[data-tracking-element-id=cookie_banner_accept_all]"}],optOut:[{waitForThenClick:"[data-tracking-element-id=cookie_banner_essential_only]"},{waitForVisible:"#cookieBannerContent",check:"none"}],test:[{eval:"EVAL_SKYSCANNER_TEST"}]},{name:"snigel",detectCmp:[{exists:".snigel-cmp-framework"}],detectPopup:[{visible:".snigel-cmp-framework"}],optOut:[{click:"#sn-b-custom"},{click:"#sn-b-save"}],test:[{eval:"EVAL_SNIGEL_0"}],optIn:[{click:".snigel-cmp-framework #accept-choices"}]},{name:"steampowered.com",detectCmp:[{exists:".cookiepreferences_popup"},{visible:".cookiepreferences_popup"}],detectPopup:[{visible:".cookiepreferences_popup"}],optOut:[{click:"#rejectAllButton"}],optIn:[{click:"#acceptAllButton"}],test:[{wait:1e3},{eval:"EVAL_STEAMPOWERED_0"}]},{name:"strato.de",prehideSelectors:[".consent__wrapper"],runContext:{urlPattern:"^https://www\\.strato\\.de/"},detectCmp:[{exists:".consent"}],detectPopup:[{visible:".consent"}],optIn:[{click:"button.consentAgree"}],optOut:[{click:"button.consentSettings"},{waitForThenClick:"button#consentSubmit"}]},{name:"svt.se",vendorUrl:"https://www.svt.se/",runContext:{urlPattern:"^https://www\\.svt\\.se/"},prehideSelectors:["[class*=CookieConsent__root___]"],detectCmp:[{exists:"[class*=CookieConsent__root___]"}],detectPopup:[{visible:"[class*=CookieConsent__modal___]"}],optIn:[{waitForThenClick:"[class*=CookieConsent__modal___] > div > button[class*=primary]"}],optOut:[{waitForThenClick:"[class*=CookieConsent__modal___] > div > button[class*=secondary]:nth-child(2)"}],test:[{eval:"EVAL_SVT_TEST"}]},{name:"takealot.com",cosmetic:!0,prehideSelectors:['div[class^="cookies-banner-module_"]'],detectCmp:[{exists:'div[class^="cookies-banner-module_cookie-banner_"]'}],detectPopup:[{exists:'div[class^="cookies-banner-module_cookie-banner_"]'}],optIn:[{click:'button[class*="cookies-banner-module_dismiss-button_"]'}],optOut:[{hide:'div[class^="cookies-banner-module_"]'},{if:{exists:'div[class^="cookies-banner-module_small-cookie-banner_"]'},then:[{eval:"EVAL_TAKEALOT_0"}],else:[]}]},{name:"tarteaucitron.js",prehideSelectors:["#tarteaucitronRoot"],detectCmp:[{exists:"#tarteaucitronRoot"}],detectPopup:[{visible:"#tarteaucitronRoot #tarteaucitronAlertBig",check:"any"}],optIn:[{eval:"EVAL_TARTEAUCITRON_1"}],optOut:[{eval:"EVAL_TARTEAUCITRON_0"}],test:[{eval:"EVAL_TARTEAUCITRON_2",comment:"sometimes there are required categories, so we check that at least something is false"}]},{name:"taunton",vendorUrl:"https://www.taunton.com/",prehideSelectors:["#taunton-user-consent__overlay"],detectCmp:[{exists:"#taunton-user-consent__overlay"}],detectPopup:[{exists:"#taunton-user-consent__overlay:not([aria-hidden=true])"}],optIn:[{click:"#taunton-user-consent__toolbar input[type=checkbox]:not(:checked)"},{click:"#taunton-user-consent__toolbar button[type=submit]"}],optOut:[{click:"#taunton-user-consent__toolbar input[type=checkbox]:checked",optional:!0,all:!0},{click:"#taunton-user-consent__toolbar button[type=submit]"}],test:[{eval:"EVAL_TAUNTON_TEST"}]},{name:"Tealium",prehideSelectors:["#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs,#__tealiumImplicitmodal,#consent-layer"],detectCmp:[{exists:"#__tealiumGDPRecModal *,#__tealiumGDPRcpPrefs *,#__tealiumImplicitmodal *"},{eval:"EVAL_TEALIUM_0"}],detectPopup:[{visible:"#__tealiumGDPRecModal *,#__tealiumGDPRcpPrefs *,#__tealiumImplicitmodal *",check:"any"}],optOut:[{eval:"EVAL_TEALIUM_1"},{eval:"EVAL_TEALIUM_DONOTSELL"},{hide:"#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs,#__tealiumImplicitmodal"},{waitForThenClick:"#cm-acceptNone,.js-accept-essential-cookies,#continueWithoutAccepting",timeout:1e3,optional:!0}],optIn:[{hide:"#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs"},{eval:"EVAL_TEALIUM_2"}],test:[{eval:"EVAL_TEALIUM_3"},{eval:"EVAL_TEALIUM_DONOTSELL_CHECK"},{visible:"#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs",check:"none"}]},{name:"temu",vendorUrl:"https://temu.com",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?temu\\.com/"},prehideSelectors:[],detectCmp:[{exists:'div > div > div > div > span[href*="/cookie-and-similar-technologies-policy.html"]'}],detectPopup:[{visible:'div > div > div > div > span[href*="/cookie-and-similar-technologies-policy.html"]'}],optIn:[{waitForThenClick:'div > div > div:has(> div > span[href*="/cookie-and-similar-technologies-policy.html"]) > [role=button]:nth-child(3)'}],optOut:[{if:{exists:"xpath///span[contains(., 'Alle afwijzen') or contains(., 'Reject all') or contains(., 'Tümünü reddet') or contains(., 'Odrzuć wszystko')]"},then:[{waitForThenClick:"xpath///span[contains(., 'Alle afwijzen') or contains(., 'Reject all') or contains(., 'Tümünü reddet') or contains(., 'Odrzuć wszystko')]"}],else:[{waitForThenClick:'div > div > div:has(> div > span[href*="/cookie-and-similar-technologies-policy.html"]) > [role=button]:nth-child(2)'}]}]},{name:"Termly",prehideSelectors:["#termly-code-snippet-support"],detectCmp:[{exists:"#termly-code-snippet-support"}],detectPopup:[{visible:"#termly-code-snippet-support div"}],optIn:[{waitForThenClick:'[data-tid="banner-accept"]'}],optOut:[{if:{exists:'[data-tid="banner-decline"]'},then:[{click:'[data-tid="banner-decline"]'}],else:[{click:".t-preference-button"},{wait:500},{if:{exists:".t-declineAllButton"},then:[{click:".t-declineAllButton"}],else:[{waitForThenClick:".t-preference-modal input[type=checkbox][checked]:not([disabled])",all:!0},{waitForThenClick:".t-saveButton"}]}]}]},{name:"termsfeed",vendorUrl:"https://termsfeed.com",comment:"v4.x.x",prehideSelectors:[".termsfeed-com---nb"],detectCmp:[{exists:".termsfeed-com---nb"}],detectPopup:[{visible:".termsfeed-com---nb"}],optIn:[{waitForThenClick:".cc-nb-okagree"}],optOut:[{waitForThenClick:".cc-nb-reject"}]},{name:"termsfeed3",vendorUrl:"https://termsfeed.com",comment:"v3.x.x",prehideSelectors:[".cc_dialog.cc_css_reboot,.cc_overlay_lock"],detectCmp:[{exists:".cc_dialog.cc_css_reboot"}],detectPopup:[{visible:".cc_dialog.cc_css_reboot"}],optIn:[{waitForThenClick:".cc_dialog.cc_css_reboot .cc_b_ok"}],optOut:[{if:{exists:".cc_dialog.cc_css_reboot .cc_b_cp"},then:[{click:".cc_dialog.cc_css_reboot .cc_b_cp"},{waitForVisible:".cookie-consent-preferences-dialog .cc_cp_f_save button"},{waitForThenClick:".cookie-consent-preferences-dialog .cc_cp_f_save button"}],else:[{hide:".cc_dialog.cc_css_reboot,.cc_overlay_lock"}]}]},{name:"tesco",vendorUrl:"https://www.tesco.com",cosmetic:!1,runContext:{urlPattern:"^https://(www\\.)?tesco\\.com/"},prehideSelectors:["[class*=CookieBanner__Sizer]"],detectCmp:[{exists:"[aria-label=consent-banner]"}],detectPopup:[{visible:"[aria-label=consent-banner]"}],optIn:[{wait:1e3},{waitForThenClick:"xpath///button[contains(., 'Accept all')]"}],optOut:[{wait:1e3},{waitForThenClick:"xpath///button[contains(., 'Reject all')]"}]},{name:"tesla",vendorUrl:"https://tesla.com/",runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?tesla\\.com/"},prehideSelectors:[],detectCmp:[{exists:"#cookie_banner"}],detectPopup:[{visible:"#cookie_banner"}],optIn:[{waitForThenClick:"#tsla-accept-cookie"}],optOut:[{waitForThenClick:"#tsla-reject-cookie"}],test:[{eval:"EVAL_TESLA_TEST"}]},{name:"Test page cosmetic CMP",cosmetic:!0,prehideSelectors:["#privacy-test-page-cmp-test-prehide"],detectCmp:[{exists:"#privacy-test-page-cmp-test-banner"}],detectPopup:[{visible:"#privacy-test-page-cmp-test-banner"}],optIn:[{waitFor:"#accept-all"},{click:"#accept-all"}],optOut:[{hide:"#privacy-test-page-cmp-test-banner"}],test:[{wait:500},{eval:"EVAL_TESTCMP_COSMETIC_0"}]},{name:"Test page CMP",prehideSelectors:["#reject-all"],detectCmp:[{exists:"#privacy-test-page-cmp-test"}],detectPopup:[{visible:"#privacy-test-page-cmp-test"}],optIn:[{waitFor:"#accept-all"},{click:"#accept-all"}],optOut:[{waitFor:"#reject-all"},{eval:"EVAL_TESTCMP_STEP"},{click:"#reject-all"}],test:[{eval:"EVAL_TESTCMP_0"}]},{name:"thalia.de",prehideSelectors:[".consent-banner-box"],detectCmp:[{exists:"consent-banner[component=consent-banner]"}],detectPopup:[{visible:".consent-banner-box"}],optIn:[{click:".button-zustimmen"}],optOut:[{click:"button[data-consent=disagree]"}]},{name:"thefreedictionary.com",prehideSelectors:["#cmpBanner"],detectCmp:[{exists:"#cmpBanner"}],detectPopup:[{visible:"#cmpBanner"}],optIn:[{eval:"EVAL_THEFREEDICTIONARY_1"}],optOut:[{eval:"EVAL_THEFREEDICTIONARY_0"}]},{name:"theverge",runContext:{frame:!1,main:!0,urlPattern:"^https://(www)?\\.theverge\\.com"},intermediate:!1,prehideSelectors:[".duet--cta--cookie-banner"],detectCmp:[{exists:".duet--cta--cookie-banner"}],detectPopup:[{visible:".duet--cta--cookie-banner"}],optIn:[{click:".duet--cta--cookie-banner button.tracking-12",all:!1}],optOut:[{click:".duet--cta--cookie-banner button.tracking-12 > span"}],test:[{eval:"EVAL_THEVERGE_0"}]},{name:"tidbits-com",cosmetic:!0,prehideSelectors:["#eu_cookie_law_widget-2"],detectCmp:[{exists:"#eu_cookie_law_widget-2"}],detectPopup:[{visible:"#eu_cookie_law_widget-2"}],optIn:[{click:"#eu-cookie-law form > input.accept"}],optOut:[{hide:"#eu_cookie_law_widget-2"}]},{name:"tractor-supply",runContext:{urlPattern:"^https://www\\.tractorsupply\\.com/"},cosmetic:!0,prehideSelectors:[".tsc-cookie-banner"],detectCmp:[{exists:".tsc-cookie-banner"}],detectPopup:[{visible:".tsc-cookie-banner"}],optIn:[{click:"#cookie-banner-cancel"}],optOut:[{hide:".tsc-cookie-banner"}]},{name:"trader-joes-com",cosmetic:!0,prehideSelectors:['div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'],detectCmp:[{exists:'div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'}],detectPopup:[{visible:'div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'}],optIn:[{click:'div[class^="CookiesAlert_cookiesAlert__container__"] button'}],optOut:[{hide:'div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'}]},{name:"transcend",vendorUrl:"https://unknown",cosmetic:!0,prehideSelectors:["#transcend-consent-manager"],detectCmp:[{exists:"#transcend-consent-manager"}],detectPopup:[{visible:"#transcend-consent-manager"}],optIn:[{waitForThenClick:["#transcend-consent-manager","#consentManagerMainDialog .inner-container button"]}],optOut:[{hide:"#transcend-consent-manager"}]},{name:"transip-nl",runContext:{urlPattern:"^https://www\\.transip\\.nl/"},prehideSelectors:["#consent-modal"],detectCmp:[{any:[{exists:"#consent-modal"},{exists:"#privacy-settings-content"}]}],detectPopup:[{any:[{visible:"#consent-modal"},{visible:"#privacy-settings-content"}]}],optIn:[{click:'button[type="submit"]'}],optOut:[{if:{exists:"#privacy-settings-content"},then:[{click:'button[type="submit"]'}],else:[{click:"div.one-modal__action-footer-column--secondary > a"}]}]},{name:"tropicfeel-com",prehideSelectors:["#shopify-section-cookies-controller"],detectCmp:[{exists:"#shopify-section-cookies-controller"}],detectPopup:[{visible:"#shopify-section-cookies-controller #cookies-controller-main-pane",check:"any"}],optIn:[{waitForThenClick:"#cookies-controller-main-pane form[data-form-allow-all] button"}],optOut:[{click:"#cookies-controller-main-pane a[data-tab-target=manage-cookies]"},{waitFor:"#manage-cookies-pane.active"},{click:"#manage-cookies-pane.active input[type=checkbox][checked]:not([disabled])",all:!0},{click:"#manage-cookies-pane.active button[type=submit]"}],test:[]},{name:"true-car",runContext:{urlPattern:"^https://www\\.truecar\\.com/"},cosmetic:!0,prehideSelectors:[['div[aria-labelledby="cookie-banner-heading"]']],detectCmp:[{exists:'div[aria-labelledby="cookie-banner-heading"]'}],detectPopup:[{visible:'div[aria-labelledby="cookie-banner-heading"]'}],optIn:[{click:'div[aria-labelledby="cookie-banner-heading"] > button[aria-label="Close"]'}],optOut:[{hide:'div[aria-labelledby="cookie-banner-heading"]'}]},{name:"truyo",prehideSelectors:["#truyo-consent-module"],detectCmp:[{exists:"#truyo-cookieBarContent"}],detectPopup:[{visible:"#truyo-consent-module"}],optIn:[{click:"button#acceptAllCookieButton"}],optOut:[{click:"button#declineAllCookieButton"}]},{name:"twcc",vendorUrl:"https://unknown",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:""},prehideSelectors:["#twcc__mechanism"],detectCmp:[{exists:"#twcc__mechanism .twcc__notice"}],detectPopup:[{visible:"#twcc__mechanism .twcc__notice"}],optIn:[{waitForThenClick:"#twcc__accept-button"}],optOut:[{waitForThenClick:"#twcc__decline-button"}],test:[{eval:"EVAL_TWCC_TEST"}]},{name:"twitch-mobile",vendorUrl:"https://m.twitch.tv/",cosmetic:!0,runContext:{urlPattern:"^https?://m\\.twitch\\.tv"},prehideSelectors:[],detectCmp:[{exists:'.ReactModal__Overlay [href="https://www.twitch.tv/p/cookie-policy"]'}],detectPopup:[{visible:'.ReactModal__Overlay [href="https://www.twitch.tv/p/cookie-policy"]'}],optIn:[{waitForThenClick:'.ReactModal__Overlay:has([href="https://www.twitch.tv/p/cookie-policy"]) button'}],optOut:[{hide:'.ReactModal__Overlay:has([href="https://www.twitch.tv/p/cookie-policy"])'}]},{name:"twitch.tv",runContext:{urlPattern:"^https?://(www\\.)?twitch\\.tv"},prehideSelectors:["div:has(> .consent-banner .consent-banner__content--gdpr-v2),.ReactModalPortal:has([data-a-target=consent-modal-save])"],detectCmp:[{exists:".consent-banner .consent-banner__content--gdpr-v2"}],detectPopup:[{visible:".consent-banner .consent-banner__content--gdpr-v2"}],optIn:[{click:'button[data-a-target="consent-banner-accept"]'}],optOut:[{hide:"div:has(> .consent-banner .consent-banner__content--gdpr-v2)"},{click:'button[data-a-target="consent-banner-manage-preferences"]'},{waitFor:"input[type=checkbox][data-a-target=tw-checkbox]"},{click:"input[type=checkbox][data-a-target=tw-checkbox][checked]:not([disabled])",all:!0,optional:!0},{waitForThenClick:"[data-a-target=consent-modal-save]"},{waitForVisible:".ReactModalPortal:has([data-a-target=consent-modal-save])",check:"none"}]},{name:"twitter",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?(twitter|x)\\.com/"},prehideSelectors:['[data-testid="BottomBar"]'],detectCmp:[{exists:'[data-testid="BottomBar"] div'}],detectPopup:[{visible:'[data-testid="BottomBar"] div'}],optIn:[{waitForThenClick:'[data-testid="BottomBar"] > div:has(>div:first-child>div:last-child>button[role=button]>span) > div:last-child > button[role=button]:first-child'}],optOut:[{waitForThenClick:'[data-testid="BottomBar"] > div:has(>div:first-child>div:last-child>button[role=button]>span) > div:last-child > button[role=button]:last-child'}],TODOtest:[{eval:"EVAL_document.cookie.includes('d_prefs=MjoxLGNvbnNlbnRfdmVyc2lvbjoy')"}]},{name:"ubuntu.com",prehideSelectors:["dialog.cookie-policy"],detectCmp:[{any:[{exists:"dialog.cookie-policy header"},{exists:'xpath///*[@id="modal"]/div/header'}]}],detectPopup:[{any:[{visible:"dialog header"},{visible:'xpath///*[@id="modal"]/div/header'}]}],optIn:[{any:[{waitForThenClick:"#cookie-policy-button-accept"},{waitForThenClick:'xpath///*[@id="cookie-policy-button-accept"]'}]}],optOut:[{any:[{waitForThenClick:"button.js-manage"},{waitForThenClick:'xpath///*[@id="cookie-policy-content"]/p[4]/button[2]'}]},{waitForThenClick:"dialog.cookie-policy .p-switch__input:checked",optional:!0,all:!0,timeout:500},{any:[{waitForThenClick:"dialog.cookie-policy .js-save-preferences"},{waitForThenClick:'xpath///*[@id="modal"]/div/button'}]}],test:[{eval:"EVAL_UBUNTU_COM_0"}]},{name:"UK Cookie Consent",prehideSelectors:["#catapult-cookie-bar"],cosmetic:!0,detectCmp:[{exists:"#catapult-cookie-bar"}],detectPopup:[{exists:".has-cookie-bar #catapult-cookie-bar"}],optIn:[{click:"#catapultCookie"}],optOut:[{hide:"#catapult-cookie-bar"}],test:[{eval:"EVAL_UK_COOKIE_CONSENT_0"}]},{name:"urbanarmorgear-com",cosmetic:!0,prehideSelectors:['div[class^="Layout__CookieBannerContainer-"]'],detectCmp:[{exists:'div[class^="Layout__CookieBannerContainer-"]'}],detectPopup:[{visible:'div[class^="Layout__CookieBannerContainer-"]'}],optIn:[{click:'button[class^="CookieBanner__AcceptButton"]'}],optOut:[{hide:'div[class^="Layout__CookieBannerContainer-"]'}]},{name:"usercentrics-api",detectCmp:[{exists:"#usercentrics-root,#usercentrics-cmp-ui"}],detectPopup:[{eval:"EVAL_USERCENTRICS_API_0"},{if:{exists:"#usercentrics-cmp-ui"},then:[{waitForVisible:"#usercentrics-cmp-ui",timeout:2e3}],else:[{exists:["#usercentrics-root","[data-testid=uc-container]"]},{waitForVisible:"#usercentrics-root",timeout:2e3}]}],optIn:[{eval:"EVAL_USERCENTRICS_API_3"},{eval:"EVAL_USERCENTRICS_API_1"},{eval:"EVAL_USERCENTRICS_API_5"}],optOut:[{eval:"EVAL_USERCENTRICS_API_1"},{eval:"EVAL_USERCENTRICS_API_2"}],test:[{eval:"EVAL_USERCENTRICS_API_6"}]},{name:"usercentrics-button",detectCmp:[{exists:"#usercentrics-button"}],detectPopup:[{visible:"#usercentrics-button #uc-btn-accept-banner"}],optIn:[{click:"#usercentrics-button #uc-btn-accept-banner"}],optOut:[{click:"#usercentrics-button #uc-btn-deny-banner"}],test:[{eval:"EVAL_USERCENTRICS_BUTTON_0"}]},{name:"uswitch.com",runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?uswitch\\.com/"},prehideSelectors:[".ucb"],detectCmp:[{exists:".ucb-banner"}],detectPopup:[{visible:".ucb-banner"}],optIn:[{waitForThenClick:".ucb-banner .ucb-btn-accept"}],optOut:[{waitForThenClick:".ucb-banner .ucb-btn-save"}]},{name:"vodafone.de",runContext:{urlPattern:"^https://www\\.vodafone\\.de/"},prehideSelectors:[".dip-consent,.dip-consent-container"],detectCmp:[{exists:".dip-consent-container"}],detectPopup:[{visible:".dip-consent-content"}],optOut:[{click:'.dip-consent-btn[tabindex="2"]'}],optIn:[{click:'.dip-consent-btn[tabindex="1"]'}]},{name:"waitrose.com",prehideSelectors:["div[aria-labelledby=CookieAlertModalHeading]","section[data-test=initial-waitrose-cookie-consent-banner]","section[data-test=cookie-consent-modal]"],detectCmp:[{exists:"section[data-test=initial-waitrose-cookie-consent-banner]"}],detectPopup:[{visible:"section[data-test=initial-waitrose-cookie-consent-banner]"}],optIn:[{click:"button[data-test=accept-all]"}],optOut:[{click:"button[data-test=manage-cookies]"},{wait:200},{eval:"EVAL_WAITROSE_0"},{click:"button[data-test=submit]"}],test:[{eval:"EVAL_WAITROSE_1"}]},{name:"webflow",vendorUrl:"https://webflow.com/",prehideSelectors:[".fs-cc-components"],detectCmp:[{exists:".fs-cc-components"}],detectPopup:[{visible:".fs-cc-components"},{visible:"[fs-cc=banner]"}],optIn:[{wait:500},{waitForThenClick:"[fs-cc=banner] [fs-cc=allow]"}],optOut:[{wait:500},{waitForThenClick:"[fs-cc=banner] [fs-cc=deny]"}]},{name:"wetransfer.com",detectCmp:[{exists:".welcome__cookie-notice"}],detectPopup:[{visible:".welcome__cookie-notice"}],optIn:[{click:".welcome__button--accept"}],optOut:[{click:".welcome__button--decline"}]},{name:"whitepages.com",runContext:{urlPattern:"^https://www\\.whitepages\\.com/"},cosmetic:!0,prehideSelectors:[".cookie-wrapper, .cookie-overlay"],detectCmp:[{exists:".cookie-wrapper"}],detectPopup:[{visible:".cookie-overlay"}],optIn:[{click:'button[aria-label="Got it"]'}],optOut:[{hide:".cookie-wrapper"}]},{name:"wolframalpha",vendorUrl:"https://www.wolframalpha.com",prehideSelectors:[],cosmetic:!0,runContext:{urlPattern:"^https://www\\.wolframalpha\\.com/"},detectCmp:[{exists:"section._a_yb"}],detectPopup:[{visible:"section._a_yb"}],optIn:[{waitForThenClick:"section._a_yb button"}],optOut:[{hide:"section._a_yb"}]},{name:"woo-commerce-com",prehideSelectors:[".wccom-comp-privacy-banner .wccom-privacy-banner"],detectCmp:[{exists:".wccom-comp-privacy-banner .wccom-privacy-banner"}],detectPopup:[{exists:".wccom-comp-privacy-banner .wccom-privacy-banner"}],optIn:[{click:".wccom-privacy-banner__content-buttons button.is-primary"}],optOut:[{click:".wccom-privacy-banner__content-buttons button.is-secondary"},{waitForThenClick:"input[type=checkbox][checked]:not([disabled])",all:!0},{click:"div.wccom-modal__footer > button"}]},{name:"WP Cookie Notice for GDPR",vendorUrl:"https://wordpress.org/plugins/gdpr-cookie-consent/",prehideSelectors:["#gdpr-cookie-consent-bar"],detectCmp:[{exists:"#gdpr-cookie-consent-bar"}],detectPopup:[{visible:"#gdpr-cookie-consent-bar"}],optIn:[{waitForThenClick:"#gdpr-cookie-consent-bar #cookie_action_accept"}],optOut:[{waitForThenClick:"#gdpr-cookie-consent-bar #cookie_action_reject"}],test:[{eval:"EVAL_WP_COOKIE_NOTICE_0"}]},{name:"wpcc",cosmetic:!0,prehideSelectors:[".wpcc-container"],detectCmp:[{exists:".wpcc-container"}],detectPopup:[{exists:".wpcc-container .wpcc-message"}],optIn:[{click:".wpcc-compliance .wpcc-btn"}],optOut:[{hide:".wpcc-container"}]},{name:"xe.com",vendorUrl:"https://www.xe.com/",runContext:{urlPattern:"^https://www\\.xe\\.com/"},prehideSelectors:["[class*=ConsentBanner]"],detectCmp:[{exists:"[class*=ConsentBanner]"}],detectPopup:[{visible:"[class*=ConsentBanner]"}],optIn:[{waitForThenClick:"[class*=ConsentBanner] .egnScw"}],optOut:[{wait:1e3},{waitForThenClick:"[class*=ConsentBanner] .frDWEu"},{waitForThenClick:"[class*=ConsentBanner] .hXIpFU"}],test:[{eval:"EVAL_XE_TEST"}]},{name:"xhamster-eu",prehideSelectors:[".cookies-modal"],detectCmp:[{exists:".cookies-modal"}],detectPopup:[{exists:".cookies-modal"}],optIn:[{click:"button.cmd-button-accept-all"}],optOut:[{click:"button.cmd-button-reject-all"}]},{name:"xhamster-us",runContext:{urlPattern:"^https://(www\\.)?xhamster\\d?\\.com"},cosmetic:!0,prehideSelectors:[".cookie-announce"],detectCmp:[{exists:".cookie-announce"}],detectPopup:[{visible:".cookie-announce .announce-text"}],optIn:[{click:".cookie-announce button.xh-button"}],optOut:[{hide:".cookie-announce"}]},{name:"xing.com",detectCmp:[{exists:"div[class^=cookie-consent-CookieConsent]"}],detectPopup:[{exists:"div[class^=cookie-consent-CookieConsent]"}],optIn:[{click:"#consent-accept-button"}],optOut:[{click:"#consent-settings-button"},{click:".consent-banner-button-accept-overlay"}],test:[{eval:"EVAL_XING_0"}]},{name:"xnxx-com",cosmetic:!0,prehideSelectors:["#cookies-use-alert"],detectCmp:[{exists:"#cookies-use-alert"}],detectPopup:[{visible:"#cookies-use-alert"}],optIn:[{click:"#cookies-use-alert .close"}],optOut:[{hide:"#cookies-use-alert"}]},{name:"xvideos",vendorUrl:"https://xvideos.com",runContext:{urlPattern:"^https://[^/]*xvideos\\.com/"},prehideSelectors:[],detectCmp:[{exists:".disclaimer-opened #disclaimer-cookies"}],detectPopup:[{visible:".disclaimer-opened #disclaimer-cookies"}],optIn:[{waitForThenClick:"#disclaimer-accept_cookies"}],optOut:[{waitForThenClick:"#disclaimer-reject_cookies"}]},{name:"Yahoo",runContext:{urlPattern:"^https://consent\\.yahoo\\.com/v2/"},prehideSelectors:["#reject-all"],detectCmp:[{exists:"#consent-page"}],detectPopup:[{visible:"#consent-page"}],optIn:[{waitForThenClick:"#consent-page button[value=agree]"}],optOut:[{waitForThenClick:"#consent-page button[value=reject]"}]},{name:"youporn.com",cosmetic:!0,prehideSelectors:[".euCookieModal, #js_euCookieModal"],detectCmp:[{exists:".euCookieModal"}],detectPopup:[{exists:".euCookieModal, #js_euCookieModal"}],optIn:[{click:'button[name="user_acceptCookie"]'}],optOut:[{hide:".euCookieModal"}]},{name:"youtube-desktop",prehideSelectors:["tp-yt-iron-overlay-backdrop.opened","ytd-consent-bump-v2-lightbox"],detectCmp:[{exists:"ytd-consent-bump-v2-lightbox tp-yt-paper-dialog"},{exists:'ytd-consent-bump-v2-lightbox tp-yt-paper-dialog a[href^="https://consent.youtube.com/"]'}],detectPopup:[{visible:"ytd-consent-bump-v2-lightbox tp-yt-paper-dialog"}],optIn:[{waitForThenClick:"ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:last-child #button,ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:last-child button"},{wait:500}],optOut:[{waitForThenClick:"ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:first-child #button,ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:first-child button"},{wait:500}],test:[{wait:500},{eval:"EVAL_YOUTUBE_DESKTOP_0"}]},{name:"youtube-mobile",prehideSelectors:[".consent-bump-v2-lightbox"],detectCmp:[{exists:"ytm-consent-bump-v2-renderer"}],detectPopup:[{visible:"ytm-consent-bump-v2-renderer"}],optIn:[{waitForThenClick:"ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons c3-material-button:first-child button, ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons ytm-button-renderer:first-child button"},{wait:500}],optOut:[{waitForThenClick:"ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons c3-material-button:nth-child(2) button, ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons ytm-button-renderer:nth-child(2) button"},{wait:500}],test:[{wait:500},{eval:"EVAL_YOUTUBE_MOBILE_0"}]},{name:"zdf",prehideSelectors:["#zdf-cmp-banner-sdk"],detectCmp:[{exists:"#zdf-cmp-banner-sdk"}],detectPopup:[{visible:"#zdf-cmp-main.zdf-cmp-show"}],optIn:[{waitForThenClick:"#zdf-cmp-main #zdf-cmp-accept-btn"}],optOut:[{waitForThenClick:"#zdf-cmp-main #zdf-cmp-deny-btn"}],test:[]},{name:"zentralruf-de",runContext:{urlPattern:"^https://(www\\.)?zentralruf\\.de"},prehideSelectors:["#cookie_modal_wrapper"],detectCmp:[{exists:"#cookie_modal_wrapper"}],detectPopup:[{visible:"#cookie_modal_wrapper"}],optIn:[{waitForThenClick:"#cookie_modal_wrapper #cookie_modal_button_consent_all"}],optOut:[{waitForThenClick:"#cookie_modal_wrapper #cookie_modal_button_choose"}]}],pn={"didomi.io":{detectors:[{presentMatcher:{target:{selector:"#didomi-host, #didomi-notice"},type:"css"},showingMatcher:{target:{selector:"body.didomi-popup-open, .didomi-notice-banner"},type:"css"}}],methods:[{action:{target:{selector:".didomi-popup-notice-buttons .didomi-button:not(.didomi-button-highlight), .didomi-notice-banner .didomi-learn-more-button"},type:"click"},name:"OPEN_OPTIONS"},{action:{actions:[{retries:50,target:{selector:"#didomi-purpose-cookies"},type:"waitcss",waitTime:50},{consents:[{description:"Share (everything) with others",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-share_whith_others]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-share_whith_others]:last-child"},type:"click"},type:"X"},{description:"Information storage and access",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-cookies]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-cookies]:last-child"},type:"click"},type:"D"},{description:"Content selection, offers and marketing",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-CL-T1Rgm7]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-CL-T1Rgm7]:last-child"},type:"click"},type:"E"},{description:"Analytics",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-analytics]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-analytics]:last-child"},type:"click"},type:"B"},{description:"Analytics",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-M9NRHJe3G]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-M9NRHJe3G]:last-child"},type:"click"},type:"B"},{description:"Ad and content selection",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-advertising_personalization]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-advertising_personalization]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection",falseAction:{parent:{childFilter:{target:{selector:"#didomi-purpose-pub-ciblee"}},selector:".didomi-consent-popup-data-processing, .didomi-components-accordion-label-container"},target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-pub-ciblee]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-pub-ciblee]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - basics",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-q4zlJqdcD]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-q4zlJqdcD]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - partners and subsidiaries",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-partenaire-cAsDe8jC]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-partenaire-cAsDe8jC]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - social networks",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-p4em9a8m]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-p4em9a8m]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - others",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-autres-pub]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-autres-pub]:last-child"},type:"click"},type:"F"},{description:"Social networks",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-reseauxsociaux]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-reseauxsociaux]:last-child"},type:"click"},type:"A"},{description:"Social networks",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-social_media]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-social_media]:last-child"},type:"click"},type:"A"},{description:"Content selection",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-content_personalization]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-content_personalization]:last-child"},type:"click"},type:"E"},{description:"Ad delivery",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-ad_delivery]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-ad_delivery]:last-child"},type:"click"},type:"F"}],type:"consent"},{action:{consents:[{matcher:{childFilter:{target:{selector:":not(.didomi-components-radio__option--selected)"}},type:"css"},trueAction:{target:{selector:":nth-child(2)"},type:"click"},falseAction:{target:{selector:":first-child"},type:"click"},type:"X"}],type:"consent"},target:{selector:".didomi-components-radio"},type:"foreach"}],type:"list"},name:"DO_CONSENT"},{action:{parent:{selector:".didomi-consent-popup-footer .didomi-consent-popup-actions"},target:{selector:".didomi-components-button:first-child"},type:"click"},name:"SAVE_CONSENT"}]},oil:{detectors:[{presentMatcher:{target:{selector:".as-oil-content-overlay"},type:"css"},showingMatcher:{target:{selector:".as-oil-content-overlay"},type:"css"}}],methods:[{action:{actions:[{target:{selector:".as-js-advanced-settings"},type:"click"},{retries:"10",target:{selector:".as-oil-cpc__purpose-container"},type:"waitcss",waitTime:"250"}],type:"list"},name:"OPEN_OPTIONS"},{action:{actions:[{consents:[{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Information storage and access","Opbevaring af og adgang til oplysninger på din enhed"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Information storage and access","Opbevaring af og adgang til oplysninger på din enhed"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"D"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personlige annoncer","Personalisation"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personlige annoncer","Personalisation"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"E"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Annoncevalg, levering og rapportering","Ad selection, delivery, reporting"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Annoncevalg, levering og rapportering","Ad selection, delivery, reporting"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"F"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personalisering af indhold","Content selection, delivery, reporting"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personalisering af indhold","Content selection, delivery, reporting"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"E"},{matcher:{parent:{childFilter:{target:{selector:".as-oil-cpc__purpose-header",textFilter:["Måling","Measurement"]}},selector:".as-oil-cpc__purpose-container"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{childFilter:{target:{selector:".as-oil-cpc__purpose-header",textFilter:["Måling","Measurement"]}},selector:".as-oil-cpc__purpose-container"},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"B"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:"Google"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:"Google"},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"F"}],type:"consent"}],type:"list"},name:"DO_CONSENT"},{action:{target:{selector:".as-oil__btn-optin"},type:"click"},name:"SAVE_CONSENT"},{action:{target:{selector:"div.as-oil"},type:"hide"},name:"HIDE_CMP"}]},optanon:{detectors:[{presentMatcher:{target:{selector:"#optanon-menu, .optanon-alert-box-wrapper"},type:"css"},showingMatcher:{target:{displayFilter:!0,selector:".optanon-alert-box-wrapper"},type:"css"}}],methods:[{action:{actions:[{target:{selector:".optanon-alert-box-wrapper .optanon-toggle-display, a[onclick*='OneTrust.ToggleInfoDisplay()'], a[onclick*='Optanon.ToggleInfoDisplay()']"},type:"click"}],type:"list"},name:"OPEN_OPTIONS"},{action:{actions:[{target:{selector:".preference-menu-item #Your-privacy"},type:"click"},{target:{selector:"#optanon-vendor-consent-text"},type:"click"},{action:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"X"}],type:"consent"},target:{selector:"#optanon-vendor-consent-list .vendor-item"},type:"foreach"},{target:{selector:".vendor-consent-back-link"},type:"click"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-performance"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-performance"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-functional"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-functional"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-advertising"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-advertising"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-social"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-social"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Social Media Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Social Media Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalisation"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalisation"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Site monitoring cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Site monitoring cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Third party privacy-enhanced content"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Third party privacy-enhanced content"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"X"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Performance & Advertising Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Performance & Advertising Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Information storage and access"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Information storage and access"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"D"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad selection, delivery, reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad selection, delivery, reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content selection, delivery, reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content selection, delivery, reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Measurement"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Measurement"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Recommended Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Recommended Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"X"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Unclassified Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Unclassified Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"X"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Analytical Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Analytical Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Marketing Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Marketing Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalization"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalization"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad Selection, Delivery & Reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad Selection, Delivery & Reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content Selection, Delivery & Reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content Selection, Delivery & Reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"}],type:"list"},name:"DO_CONSENT"},{action:{parent:{selector:".optanon-save-settings-button"},target:{selector:".optanon-white-button-middle"},type:"click"},name:"SAVE_CONSENT"},{action:{actions:[{target:{selector:"#optanon-popup-wrapper"},type:"hide"},{target:{selector:"#optanon-popup-bg"},type:"hide"},{target:{selector:".optanon-alert-box-wrapper"},type:"hide"}],type:"list"},name:"HIDE_CMP"}]},quantcast2:{detectors:[{presentMatcher:{target:{selector:"[data-tracking-opt-in-overlay]"},type:"css"},showingMatcher:{target:{selector:"[data-tracking-opt-in-overlay] [data-tracking-opt-in-learn-more]"},type:"css"}}],methods:[{action:{target:{selector:"[data-tracking-opt-in-overlay] [data-tracking-opt-in-learn-more]"},type:"click"},name:"OPEN_OPTIONS"},{action:{actions:[{type:"wait",waitTime:500},{action:{actions:[{target:{selector:"div",textFilter:["Information storage and access"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"D"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Personalization"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"F"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Ad selection, delivery, reporting"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"F"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Content selection, delivery, reporting"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"E"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Measurement"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"B"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Other Partners"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"X"}],type:"consent"},type:"ifcss"}],type:"list"},parent:{childFilter:{target:{selector:"input"}},selector:"[data-tracking-opt-in-overlay] > div > div"},target:{childFilter:{target:{selector:"input"}},selector:":scope > div"},type:"foreach"}],type:"list"},name:"DO_CONSENT"},{action:{target:{selector:"[data-tracking-opt-in-overlay] [data-tracking-opt-in-save]"},type:"click"},name:"SAVE_CONSENT"}]},springer:{detectors:[{presentMatcher:{parent:null,target:{selector:".cmp-app_gdpr"},type:"css"},showingMatcher:{parent:null,target:{displayFilter:!0,selector:".cmp-popup_popup"},type:"css"}}],methods:[{action:{actions:[{target:{selector:".cmp-intro_rejectAll"},type:"click"},{type:"wait",waitTime:250},{target:{selector:".cmp-purposes_purposeItem:not(.cmp-purposes_selectedPurpose)"},type:"click"}],type:"list"},name:"OPEN_OPTIONS"},{action:{consents:[{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Przechowywanie informacji na urządzeniu lub dostęp do nich",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Przechowywanie informacji na urządzeniu lub dostęp do nich",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"D"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór podstawowych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór podstawowych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"F"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"F"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"E"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"E"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"B"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"B"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"B"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Stosowanie badań rynkowych w celu generowania opinii odbiorców",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Stosowanie badań rynkowych w celu generowania opinii odbiorców",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"X"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Opracowywanie i ulepszanie produktów",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Opracowywanie i ulepszanie produktów",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"X"}],type:"consent"},name:"DO_CONSENT"},{action:{target:{selector:".cmp-details_save"},type:"click"},name:"SAVE_CONSENT"}]},wordpressgdpr:{detectors:[{presentMatcher:{parent:null,target:{selector:".wpgdprc-consent-bar"},type:"css"},showingMatcher:{parent:null,target:{displayFilter:!0,selector:".wpgdprc-consent-bar"},type:"css"}}],methods:[{action:{parent:null,target:{selector:".wpgdprc-consent-bar .wpgdprc-consent-bar__settings",textFilter:null},type:"click"},name:"OPEN_OPTIONS"},{action:{actions:[{target:{selector:".wpgdprc-consent-modal .wpgdprc-button",textFilter:"Eyeota"},type:"click"},{consents:[{description:"Eyeota Cookies",matcher:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Eyeota"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Eyeota"},target:{selector:"label"},type:"click"},type:"X"}],type:"consent"},{target:{selector:".wpgdprc-consent-modal .wpgdprc-button",textFilter:"Advertising"},type:"click"},{consents:[{description:"Advertising Cookies",matcher:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Advertising"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Advertising"},target:{selector:"label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},name:"DO_CONSENT"},{action:{parent:null,target:{selector:".wpgdprc-button",textFilter:"Save my settings"},type:"click"},name:"SAVE_CONSENT"}]}},dn={autoconsent:ln,consentomatic:pn},un=Object.freeze({__proto__:null,autoconsent:ln,consentomatic:pn,default:dn}); +!function(){"use strict";var e=class e{static setBase(t){e.base=t}static findElement(t,o=null,i=!1){let c=null;return c=null!=o?Array.from(o.querySelectorAll(t.selector)):null!=e.base?Array.from(e.base.querySelectorAll(t.selector)):Array.from(document.querySelectorAll(t.selector)),null!=t.textFilter&&(c=c.filter((e=>{const o=e.textContent.toLowerCase();if(Array.isArray(t.textFilter)){let e=!1;for(const i of t.textFilter)if(-1!==o.indexOf(i.toLowerCase())){e=!0;break}return e}return null!=t.textFilter&&-1!==o.indexOf(t.textFilter.toLowerCase())}))),null!=t.styleFilters&&(c=c.filter((e=>{const o=window.getComputedStyle(e);let i=!0;for(const e of t.styleFilters){const t=o[e.option];i=e.negated?i&&t!==e.value:i&&t===e.value}return i}))),null!=t.displayFilter&&(c=c.filter((e=>t.displayFilter?0!==e.offsetHeight:0===e.offsetHeight))),null!=t.iframeFilter&&(c=c.filter((()=>t.iframeFilter?window.location!==window.parent.location:window.location===window.parent.location))),null!=t.childFilter&&(c=c.filter((o=>{const i=e.base;e.setBase(o);const c=e.find(t.childFilter);return e.setBase(i),null!=c.target}))),i?c:(c.length>1&&console.warn("Multiple possible targets: ",c,t,o),c[0])}static find(t,o=!1){const i=[];if(null!=t.parent){const c=e.findElement(t.parent,null,o);if(null!=c){if(c instanceof Array)return c.forEach((c=>{const n=e.findElement(t.target,c,o);n instanceof Array?n.forEach((e=>{i.push({parent:c,target:e})})):i.push({parent:c,target:n})})),i;{const n=e.findElement(t.target,c,o);n instanceof Array?n.forEach((e=>{i.push({parent:c,target:e})})):i.push({parent:c,target:n})}}}else{const c=e.findElement(t.target,null,o);c instanceof Array?c.forEach((e=>{i.push({parent:null,target:e})})):i.push({parent:null,target:c})}return 0===i.length&&i.push({parent:null,target:null}),o?i:(1!==i.length&&console.warn("Multiple results found, even though multiple false",i),i[0])}};e.base=null;var t=e;function o(e){const o=t.find(e);return"css"===e.type?!!o.target:"checkbox"===e.type?!!o.target&&o.target.checked:void 0}async function i(e,a){switch(e.type){case"click":return async function(e){const o=t.find(e);null!=o.target&&o.target.click();return n(c)}(e);case"list":return async function(e,t){for(const o of e.actions)await i(o,t)}(e,a);case"consent":return async function(e,t){for(const c of e.consents){const e=-1!==t.indexOf(c.type);if(c.matcher&&c.toggleAction){o(c.matcher)!==e&&await i(c.toggleAction)}else e?await i(c.trueAction):await i(c.falseAction)}}(e,a);case"ifcss":return async function(e,o){const c=t.find(e);c.target?e.falseAction&&await i(e.falseAction,o):e.trueAction&&await i(e.trueAction,o)}(e,a);case"waitcss":return async function(e){await new Promise((o=>{let i=e.retries||10;const c=e.waitTime||250,n=()=>{const a=t.find(e);(e.negated&&a.target||!e.negated&&!a.target)&&i>0?(i-=1,setTimeout(n,c)):o()};n()}))}(e);case"foreach":return async function(e,o){const c=t.find(e,!0),n=t.base;for(const n of c)n.target&&(t.setBase(n.target),await i(e.action,o));t.setBase(n)}(e,a);case"hide":return async function(e){const o=t.find(e);o.target&&o.target.classList.add("Autoconsent-Hidden")}(e);case"slide":return async function(e){const o=t.find(e),i=t.find(e.dragTarget);if(o.target){const e=o.target.getBoundingClientRect(),t=i.target.getBoundingClientRect();let c=t.top-e.top,n=t.left-e.left;"y"===this.config.axis.toLowerCase()&&(n=0),"x"===this.config.axis.toLowerCase()&&(c=0);const a=window.screenX+e.left+e.width/2,s=window.screenY+e.top+e.height/2,r=e.left+e.width/2,l=e.top+e.height/2,p=document.createEvent("MouseEvents");p.initMouseEvent("mousedown",!0,!0,window,0,a,s,r,l,!1,!1,!1,!1,0,o.target);const d=document.createEvent("MouseEvents");d.initMouseEvent("mousemove",!0,!0,window,0,a+n,s+c,r+n,l+c,!1,!1,!1,!1,0,o.target);const u=document.createEvent("MouseEvents");u.initMouseEvent("mouseup",!0,!0,window,0,a+n,s+c,r+n,l+c,!1,!1,!1,!1,0,o.target),o.target.dispatchEvent(p),await this.waitTimeout(10),o.target.dispatchEvent(d),await this.waitTimeout(10),o.target.dispatchEvent(u)}}(e);case"close":return async function(){window.close()}();case"wait":return async function(e){await n(e.waitTime)}(e);case"eval":return async function(e){return console.log("eval!",e.code),new Promise((t=>{try{e.async?(window.eval(e.code),setTimeout((()=>{t(window.eval("window.__consentCheckResult"))}),e.timeout||250)):t(window.eval(e.code))}catch(o){console.warn("eval error",o,e.code),t(!1)}}))}(e);default:throw new Error("Unknown action type: "+e.type)}}var c=0;function n(e){return new Promise((t=>{setTimeout((()=>{t()}),e)}))}function a(){return crypto&&void 0!==crypto.randomUUID?crypto.randomUUID():Math.random().toString()}var s=class{constructor(e,t=1e3){this.id=e,this.promise=new Promise(((e,t)=>{this.resolve=e,this.reject=t})),this.timer=window.setTimeout((()=>{this.reject(new Error("timeout"))}),t)}},r={pending:new Map,sendContentMessage:null};var l={EVAL_0:()=>console.log(1),EVAL_CONSENTMANAGER_1:()=>window.__cmp&&"object"==typeof __cmp("getCMPData"),EVAL_CONSENTMANAGER_2:()=>!__cmp("consentStatus").userChoiceExists,EVAL_CONSENTMANAGER_3:()=>__cmp("setConsent",0),EVAL_CONSENTMANAGER_4:()=>__cmp("setConsent",1),EVAL_CONSENTMANAGER_5:()=>__cmp("consentStatus").userChoiceExists,EVAL_COOKIEBOT_1:()=>!!window.Cookiebot,EVAL_COOKIEBOT_2:()=>!window.Cookiebot.hasResponse&&!0===window.Cookiebot.dialog?.visible,EVAL_COOKIEBOT_3:()=>window.Cookiebot.withdraw()||!0,EVAL_COOKIEBOT_4:()=>window.Cookiebot.hide()||!0,EVAL_COOKIEBOT_5:()=>!0===window.Cookiebot.declined,EVAL_KLARO_1:()=>{const e=globalThis.klaroConfig||globalThis.klaro?.getManager&&globalThis.klaro.getManager().config;if(!e)return!0;const t=(e.services||e.apps).filter((e=>!e.required)).map((e=>e.name));if(klaro&&klaro.getManager){const e=klaro.getManager();return t.every((t=>!e.consents[t]))}if(klaroConfig&&"cookie"===klaroConfig.storageMethod){const e=klaroConfig.cookieName||klaroConfig.storageName,o=JSON.parse(decodeURIComponent(document.cookie.split(";").find((t=>t.trim().startsWith(e))).split("=")[1]));return Object.keys(o).filter((e=>t.includes(e))).every((e=>!1===o[e]))}},EVAL_KLARO_OPEN_POPUP:()=>{klaro.show(void 0,!0)},EVAL_KLARO_TRY_API_OPT_OUT:()=>{if(window.klaro&&"function"==typeof klaro.show&&"function"==typeof klaro.getManager)try{return klaro.getManager().changeAll(!1),klaro.getManager().saveAndApplyConsents(),!0}catch(e){return console.warn(e),!1}return!1},EVAL_ONETRUST_1:()=>window.OnetrustActiveGroups.split(",").filter((e=>e.length>0)).length<=1,EVAL_TRUSTARC_TOP:()=>window&&window.truste&&"0"===window.truste.eu.bindMap.prefCookie,EVAL_TRUSTARC_FRAME_TEST:()=>window&&window.QueryString&&"0"===window.QueryString.preferences,EVAL_TRUSTARC_FRAME_GTM:()=>window&&window.QueryString&&"1"===window.QueryString.gtm,EVAL_ABC_TEST:()=>document.cookie.includes("trackingconsent"),EVAL_ADROLL_0:()=>!document.cookie.includes("__adroll_fpc"),EVAL_ALMACMP_0:()=>document.cookie.includes('"name":"Google","consent":false'),EVAL_AFFINITY_SERIF_COM_0:()=>document.cookie.includes("serif_manage_cookies_viewed")&&!document.cookie.includes("serif_allow_analytics"),EVAL_ARBEITSAGENTUR_TEST:()=>document.cookie.includes("cookie_consent=denied"),EVAL_AXEPTIO_0:()=>document.cookie.includes("axeptio_authorized_vendors=%2C%2C"),EVAL_BAHN_TEST:()=>1===utag.gdpr.getSelectedCategories().length,EVAL_BING_0:()=>document.cookie.includes("AD=0"),EVAL_BLOCKSY_0:()=>document.cookie.includes("blocksy_cookies_consent_accepted=no"),EVAL_BORLABS_0:()=>!JSON.parse(decodeURIComponent(document.cookie.split(";").find((e=>-1!==e.indexOf("borlabs-cookie"))).split("=",2)[1])).consents.statistics,EVAL_BUNDESREGIERUNG_DE_0:()=>document.cookie.match("cookie-allow-tracking=0"),EVAL_CANVA_0:()=>!document.cookie.includes("gtm_fpc_engagement_event"),EVAL_CC_BANNER2_0:()=>!!document.cookie.match(/sncc=[^;]+D%3Dtrue/),EVAL_CLICKIO_0:()=>document.cookie.includes("__lxG__consent__v2_daisybit="),EVAL_CLINCH_0:()=>document.cookie.includes("ctc_rejected=1"),EVAL_COOKIECONSENT2_TEST:()=>document.cookie.includes("cc_cookie="),EVAL_COOKIECONSENT3_TEST:()=>document.cookie.includes("cc_cookie="),EVAL_COINBASE_0:()=>JSON.parse(decodeURIComponent(document.cookie.match(/cm_(eu|default)_preferences=([0-9a-zA-Z\\{\\}\\[\\]%:]*);?/)[2])).consent.length<=1,EVAL_COMPLIANZ_BANNER_0:()=>document.cookie.includes("cmplz_banner-status=dismissed"),EVAL_COOKIE_LAW_INFO_0:()=>CLI.disableAllCookies()||CLI.reject_close()||!0,EVAL_COOKIE_LAW_INFO_1:()=>-1===document.cookie.indexOf("cookielawinfo-checkbox-non-necessary=yes"),EVAL_COOKIE_LAW_INFO_DETECT:()=>!!window.CLI,EVAL_COOKIE_MANAGER_POPUP_0:()=>!1===JSON.parse(document.cookie.split(";").find((e=>e.trim().startsWith("CookieLevel"))).split("=")[1]).social,EVAL_COOKIEALERT_0:()=>document.querySelector("body").removeAttribute("style")||!0,EVAL_COOKIEALERT_1:()=>document.querySelector("body").removeAttribute("style")||!0,EVAL_COOKIEALERT_2:()=>!0===window.CookieConsent.declined,EVAL_COOKIEFIRST_0:()=>{return!1===(e=JSON.parse(decodeURIComponent(document.cookie.split(";").find((e=>-1!==e.indexOf("cookiefirst"))).trim()).split("=")[1])).performance&&!1===e.functional&&!1===e.advertising;var e},EVAL_COOKIEFIRST_1:()=>document.querySelectorAll("button[data-cookiefirst-accent-color=true][role=checkbox]:not([disabled])").forEach((e=>"true"===e.getAttribute("aria-checked")&&e.click()))||!0,EVAL_COOKIEINFORMATION_0:()=>CookieInformation.declineAllCategories()||!0,EVAL_COOKIEINFORMATION_1:()=>CookieInformation.submitAllCategories()||!0,EVAL_COOKIEINFORMATION_2:()=>document.cookie.includes("CookieInformationConsent="),EVAL_COOKIEYES_0:()=>document.cookie.includes("advertisement:no"),EVAL_DAILYMOTION_0:()=>!!document.cookie.match("dm-euconsent-v2"),EVAL_DNDBEYOND_TEST:()=>document.cookie.includes("cookie-consent=denied"),EVAL_DSGVO_0:()=>!document.cookie.includes("sp_dsgvo_cookie_settings"),EVAL_DUNELM_0:()=>document.cookie.includes("cc_functional=0")&&document.cookie.includes("cc_targeting=0"),EVAL_ETSY_0:()=>document.querySelectorAll(".gdpr-overlay-body input").forEach((e=>{e.checked=!1}))||!0,EVAL_ETSY_1:()=>document.querySelector(".gdpr-overlay-view button[data-wt-overlay-close]").click()||!0,EVAL_EU_COOKIE_COMPLIANCE_0:()=>-1===document.cookie.indexOf("cookie-agreed=2"),EVAL_EU_COOKIE_LAW_0:()=>!document.cookie.includes("euCookie"),EVAL_EZOIC_0:()=>ezCMP.handleAcceptAllClick(),EVAL_EZOIC_1:()=>!!document.cookie.match(/ez-consent-tcf/),EVAL_FIDES_DETECT_POPUP:()=>window.Fides?.initialized,EVAL_GOOGLE_0:()=>!!document.cookie.match(/SOCS=CAE/),EVAL_HEMA_TEST_0:()=>document.cookie.includes("cookies_rejected=1"),EVAL_IUBENDA_0:()=>document.querySelectorAll(".purposes-item input[type=checkbox]:not([disabled])").forEach((e=>{e.checked&&e.click()}))||!0,EVAL_IUBENDA_1:()=>!!document.cookie.match(/_iub_cs-\d+=/),EVAL_IWINK_TEST:()=>document.cookie.includes("cookie_permission_granted=no"),EVAL_JQUERY_COOKIEBAR_0:()=>!document.cookie.includes("cookies-state=accepted"),EVAL_KETCH_TEST:()=>document.cookie.includes("_ketch_consent_v1_"),EVAL_MEDIAVINE_0:()=>document.querySelectorAll('[data-name="mediavine-gdpr-cmp"] input[type=checkbox]').forEach((e=>e.checked&&e.click()))||!0,EVAL_MICROSOFT_0:()=>Array.from(document.querySelectorAll("div > button")).filter((e=>e.innerText.match("Reject|Ablehnen")))[0].click()||!0,EVAL_MICROSOFT_1:()=>Array.from(document.querySelectorAll("div > button")).filter((e=>e.innerText.match("Accept|Annehmen")))[0].click()||!0,EVAL_MICROSOFT_2:()=>!!document.cookie.match("MSCC|GHCC"),EVAL_MOOVE_0:()=>document.querySelectorAll("#moove_gdpr_cookie_modal input").forEach((e=>{e.disabled||(e.checked="moove_gdpr_strict_cookies"===e.name||"moove_gdpr_strict_cookies"===e.id)}))||!0,EVAL_ONENINETWO_0:()=>document.cookie.includes("CC_ADVERTISING=NO")&&document.cookie.includes("CC_ANALYTICS=NO"),EVAL_OPENAI_TEST:()=>document.cookie.includes("oai-allow-ne=false"),EVAL_OPERA_0:()=>document.cookie.includes("cookie_consent_essential=true")&&!document.cookie.includes("cookie_consent_marketing=true"),EVAL_PAYPAL_0:()=>!0===document.cookie.includes("cookie_prefs"),EVAL_PRIMEBOX_0:()=>!document.cookie.includes("cb-enabled=accepted"),EVAL_PUBTECH_0:()=>document.cookie.includes("euconsent-v2")&&(document.cookie.match(/.YAAAAAAAAAAA/)||document.cookie.match(/.aAAAAAAAAAAA/)||document.cookie.match(/.YAAACFgAAAAA/)),EVAL_REDDIT_0:()=>document.cookie.includes("eu_cookie={%22opted%22:true%2C%22nonessential%22:false}"),EVAL_ROBLOX_TEST:()=>document.cookie.includes("RBXcb"),EVAL_SKYSCANNER_TEST:()=>document.cookie.match(/gdpr=[^;]*adverts:::false/)&&!document.cookie.match(/gdpr=[^;]*init:::true/),EVAL_SIRDATA_UNBLOCK_SCROLL:()=>(document.documentElement.classList.forEach((e=>{e.startsWith("sd-cmp-")&&document.documentElement.classList.remove(e)})),!0),EVAL_SNIGEL_0:()=>!!document.cookie.match("snconsent"),EVAL_STEAMPOWERED_0:()=>2===JSON.parse(decodeURIComponent(document.cookie.split(";").find((e=>e.trim().startsWith("cookieSettings"))).split("=")[1])).preference_state,EVAL_SVT_TEST:()=>document.cookie.includes('cookie-consent-1={"optedIn":true,"functionality":false,"statistics":false}'),EVAL_TAKEALOT_0:()=>document.body.classList.remove("freeze")||(document.body.style="")||!0,EVAL_TARTEAUCITRON_0:()=>tarteaucitron.userInterface.respondAll(!1)||!0,EVAL_TARTEAUCITRON_1:()=>tarteaucitron.userInterface.respondAll(!0)||!0,EVAL_TARTEAUCITRON_2:()=>document.cookie.match(/tarteaucitron=[^;]*/)?.[0].includes("false"),EVAL_TAUNTON_TEST:()=>document.cookie.includes("taunton_user_consent_submitted=true"),EVAL_TEALIUM_0:()=>void 0!==window.utag&&"object"==typeof utag.gdpr,EVAL_TEALIUM_1:()=>utag.gdpr.setConsentValue(!1)||!0,EVAL_TEALIUM_DONOTSELL:()=>utag.gdpr.dns?.setDnsState(!1)||!0,EVAL_TEALIUM_2:()=>utag.gdpr.setConsentValue(!0)||!0,EVAL_TEALIUM_3:()=>1!==utag.gdpr.getConsentState(),EVAL_TEALIUM_DONOTSELL_CHECK:()=>1!==utag.gdpr.dns?.getDnsState(),EVAL_TESLA_TEST:()=>document.cookie.includes("tsla-cookie-consent=rejected"),EVAL_TESTCMP_STEP:()=>!!document.querySelector("#reject-all"),EVAL_TESTCMP_0:()=>"button_clicked"===window.results.results[0],EVAL_TESTCMP_COSMETIC_0:()=>"banner_hidden"===window.results.results[0],EVAL_THEFREEDICTIONARY_0:()=>cmpUi.showPurposes()||cmpUi.rejectAll()||!0,EVAL_THEFREEDICTIONARY_1:()=>cmpUi.allowAll()||!0,EVAL_THEVERGE_0:()=>document.cookie.includes("_duet_gdpr_acknowledged=1"),EVAL_TWCC_TEST:()=>document.cookie.includes("twCookieConsent="),EVAL_UBUNTU_COM_0:()=>document.cookie.includes("_cookies_accepted=essential"),EVAL_UK_COOKIE_CONSENT_0:()=>!document.cookie.includes("catAccCookies"),EVAL_USERCENTRICS_API_0:()=>"object"==typeof UC_UI,EVAL_USERCENTRICS_API_1:()=>!!UC_UI.closeCMP(),EVAL_USERCENTRICS_API_2:()=>!!UC_UI.denyAllConsents(),EVAL_USERCENTRICS_API_3:()=>!!UC_UI.acceptAllConsents(),EVAL_USERCENTRICS_API_4:()=>!!UC_UI.closeCMP(),EVAL_USERCENTRICS_API_5:()=>!0===UC_UI.areAllConsentsAccepted(),EVAL_USERCENTRICS_API_6:()=>!1===UC_UI.areAllConsentsAccepted(),EVAL_USERCENTRICS_BUTTON_0:()=>JSON.parse(localStorage.getItem("usercentrics")).consents.every((e=>e.isEssential||!e.consentStatus)),EVAL_WAITROSE_0:()=>Array.from(document.querySelectorAll("label[id$=cookies-deny-label]")).forEach((e=>e.click()))||!0,EVAL_WAITROSE_1:()=>document.cookie.includes("wtr_cookies_advertising=0")&&document.cookie.includes("wtr_cookies_analytics=0"),EVAL_WP_COOKIE_NOTICE_0:()=>document.cookie.includes("wpl_viewed_cookie=no"),EVAL_XE_TEST:()=>document.cookie.includes("xeConsentState={%22performance%22:false%2C%22marketing%22:false%2C%22compliance%22:false}"),EVAL_XING_0:()=>document.cookie.includes("userConsent=%7B%22marketing%22%3Afalse"),EVAL_YOUTUBE_DESKTOP_0:()=>!!document.cookie.match(/SOCS=CAE/),EVAL_YOUTUBE_MOBILE_0:()=>!!document.cookie.match(/SOCS=CAE/)};var p={main:!0,frame:!1,urlPattern:""},d=class{constructor(e){this.runContext=p,this.autoconsent=e}get hasSelfTest(){throw new Error("Not Implemented")}get isIntermediate(){throw new Error("Not Implemented")}get isCosmetic(){throw new Error("Not Implemented")}mainWorldEval(e){const t=l[e];if(!t)return console.warn("Snippet not found",e),Promise.resolve(!1);const o=this.autoconsent.config.logs;if(this.autoconsent.config.isMainWorld){o.evals&&console.log("inline eval:",e,t);let i=!1;try{i=!!t.call(globalThis)}catch(t){o.evals&&console.error("error evaluating rule",e,t)}return Promise.resolve(i)}const i=`(${t.toString()})()`;return o.evals&&console.log("async eval:",e,i),function(e,t){const o=a();r.sendContentMessage({type:"eval",id:o,code:e,snippetId:t});const i=new s(o);return r.pending.set(i.id,i),i.promise}(i,e).catch((t=>(o.evals&&console.error("error evaluating rule",e,t),!1)))}checkRunContext(){const e={...p,...this.runContext},t=window.top===window;return!(t&&!e.main)&&(!(!t&&!e.frame)&&!(e.urlPattern&&!window.location.href.match(e.urlPattern)))}detectCmp(){throw new Error("Not Implemented")}async detectPopup(){return!1}optOut(){throw new Error("Not Implemented")}optIn(){throw new Error("Not Implemented")}openCmp(){throw new Error("Not Implemented")}async test(){return Promise.resolve(!0)}click(e,t=!1){return this.autoconsent.domActions.click(e,t)}elementExists(e){return this.autoconsent.domActions.elementExists(e)}elementVisible(e,t){return this.autoconsent.domActions.elementVisible(e,t)}waitForElement(e,t){return this.autoconsent.domActions.waitForElement(e,t)}waitForVisible(e,t,o){return this.autoconsent.domActions.waitForVisible(e,t,o)}waitForThenClick(e,t,o){return this.autoconsent.domActions.waitForThenClick(e,t,o)}wait(e){return this.autoconsent.domActions.wait(e)}hide(e,t){return this.autoconsent.domActions.hide(e,t)}prehide(e){return this.autoconsent.domActions.prehide(e)}undoPrehide(){return this.autoconsent.domActions.undoPrehide()}querySingleReplySelector(e,t){return this.autoconsent.domActions.querySingleReplySelector(e,t)}querySelectorChain(e){return this.autoconsent.domActions.querySelectorChain(e)}elementSelector(e){return this.autoconsent.domActions.elementSelector(e)}},u=class extends d{constructor(e,t){super(t),this.rule=e,this.name=e.name,this.runContext=e.runContext||p}get hasSelfTest(){return!!this.rule.test}get isIntermediate(){return!!this.rule.intermediate}get isCosmetic(){return!!this.rule.cosmetic}get prehideSelectors(){return this.rule.prehideSelectors}async detectCmp(){return!!this.rule.detectCmp&&this._runRulesParallel(this.rule.detectCmp)}async detectPopup(){return!!this.rule.detectPopup&&this._runRulesSequentially(this.rule.detectPopup)}async optOut(){const e=this.autoconsent.config.logs;return!!this.rule.optOut&&(e.lifecycle&&console.log("Initiated optOut()",this.rule.optOut),this._runRulesSequentially(this.rule.optOut))}async optIn(){const e=this.autoconsent.config.logs;return!!this.rule.optIn&&(e.lifecycle&&console.log("Initiated optIn()",this.rule.optIn),this._runRulesSequentially(this.rule.optIn))}async openCmp(){return!!this.rule.openCmp&&this._runRulesSequentially(this.rule.openCmp)}async test(){return this.hasSelfTest?this._runRulesSequentially(this.rule.test):super.test()}async evaluateRuleStep(e){const t=[],o=this.autoconsent.config.logs;if(e.exists&&t.push(this.elementExists(e.exists)),e.visible&&t.push(this.elementVisible(e.visible,e.check)),e.eval){const o=this.mainWorldEval(e.eval);t.push(o)}if(e.waitFor&&t.push(this.waitForElement(e.waitFor,e.timeout)),e.waitForVisible&&t.push(this.waitForVisible(e.waitForVisible,e.timeout,e.check)),e.click&&t.push(this.click(e.click,e.all)),e.waitForThenClick&&t.push(this.waitForThenClick(e.waitForThenClick,e.timeout,e.all)),e.wait&&t.push(this.wait(e.wait)),e.hide&&t.push(this.hide(e.hide,e.method)),e.if){if(!e.if.exists&&!e.if.visible)return console.error("invalid conditional rule",e.if),!1;const i=await this.evaluateRuleStep(e.if);o.rulesteps&&console.log("Condition is",i),i?t.push(this._runRulesSequentially(e.then)):e.else?t.push(this._runRulesSequentially(e.else)):t.push(!0)}if(e.any){for(const t of e.any)if(await this.evaluateRuleStep(t))return!0;return!1}if(0===t.length)return o.errors&&console.warn("Unrecognized rule",e),!1;return(await Promise.all(t)).reduce(((e,t)=>e&&t),!0)}async _runRulesParallel(e){const t=e.map((e=>this.evaluateRuleStep(e)));return(await Promise.all(t)).every((e=>!!e))}async _runRulesSequentially(e){const t=this.autoconsent.config.logs;for(const o of e){t.rulesteps&&console.log("Running rule...",o);const e=await this.evaluateRuleStep(o);if(t.rulesteps&&console.log("...rule result",e),!e&&!o.optional)return!1}return!0}},m=class{constructor(e,t){this.name=e,this.config=t,this.methods=new Map,this.runContext=p,this.isCosmetic=!1,t.methods.forEach((e=>{e.action&&this.methods.set(e.name,e.action)})),this.hasSelfTest=!1}get isIntermediate(){return!1}checkRunContext(){return!0}async detectCmp(){return this.config.detectors.map((e=>o(e.presentMatcher))).some((e=>!!e))}async detectPopup(){return this.config.detectors.map((e=>o(e.showingMatcher))).some((e=>!!e))}async executeAction(e,t){return!this.methods.has(e)||i(this.methods.get(e),t)}async optOut(){return await this.executeAction("HIDE_CMP"),await this.executeAction("OPEN_OPTIONS"),await this.executeAction("HIDE_CMP"),await this.executeAction("DO_CONSENT",[]),await this.executeAction("SAVE_CONSENT"),!0}async optIn(){return await this.executeAction("HIDE_CMP"),await this.executeAction("OPEN_OPTIONS"),await this.executeAction("HIDE_CMP"),await this.executeAction("DO_CONSENT",["D","A","B","E","F","X"]),await this.executeAction("SAVE_CONSENT"),!0}async openCmp(){return await this.executeAction("HIDE_CMP"),await this.executeAction("OPEN_OPTIONS"),!0}async test(){return!0}};function A(e="autoconsent-css-rules"){const t=`style#${e}`,o=document.querySelector(t);if(o&&o instanceof HTMLStyleElement)return o;{const t=document.head||document.getElementsByTagName("head")[0]||document.documentElement,o=document.createElement("style");return o.id=e,t.appendChild(o),o}}function h(e,t,o="display"){const i=`${t} { ${function(e){return("opacity"===e?"opacity: 0":"display: none")+" !important; z-index: -1 !important; pointer-events: none !important;"}(o)} } `;return e instanceof HTMLStyleElement&&(e.innerText+=i,t.length>0)}async function k(e,t,o){const i=await e();return!i&&t>0?new Promise((i=>{setTimeout((async()=>{i(k(e,t-1,o))}),o)})):Promise.resolve(i)}function b(e){if(!e)return!1;if(null!==e.offsetParent)return!0;{const t=window.getComputedStyle(e);if("fixed"===t.position&&"none"!==t.display)return!0}return!1}function g(e){const t={enabled:!0,autoAction:"optOut",disabledCmps:[],enablePrehide:!0,enableCosmeticRules:!0,enableHeuristicDetection:!1,detectRetries:20,isMainWorld:!1,prehideTimeout:2e3,enableFilterList:!1,logs:{lifecycle:!1,rulesteps:!1,evals:!1,errors:!0,messages:!1,waits:!1}},o=(i=t,globalThis.structuredClone?structuredClone(i):JSON.parse(JSON.stringify(i)));var i;for(const i of Object.keys(t))void 0!==e[i]&&(o[i]=e[i]);return o}var _="#truste-show-consent",y="#truste-consent-track",w=[class extends d{constructor(e){super(e),this.name="TrustArc-top",this.prehideSelectors=[".trustarc-banner-container",`.truste_popframe,.truste_overlay,.truste_box_overlay,${y}`],this.runContext={main:!0,frame:!1},this._shortcutButton=null,this._optInDone=!1}get hasSelfTest(){return!0}get isIntermediate(){return!this._optInDone&&!this._shortcutButton}get isCosmetic(){return!1}async detectCmp(){const e=this.elementExists(`${_},${y}`);return e&&(this._shortcutButton=document.querySelector("#truste-consent-required")),e}async detectPopup(){return this.elementVisible(`#truste-consent-content,#trustarc-banner-overlay,${y}`,"any")}openFrame(){this.click(_)}async optOut(){return this._shortcutButton?(this._shortcutButton.click(),!0):(h(A(),`.truste_popframe, .truste_overlay, .truste_box_overlay, ${y}`),this.click(_),setTimeout((()=>{A().remove()}),1e4),!0)}async optIn(){return this._optInDone=!0,this.click("#truste-consent-button")}async openCmp(){return!0}async test(){return await this.wait(500),await this.mainWorldEval("EVAL_TRUSTARC_TOP")}},class extends d{constructor(){super(...arguments),this.name="TrustArc-frame",this.runContext={main:!1,frame:!0,urlPattern:"^https://consent-pref\\.trustarc\\.com/\\?"}}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return!0}async detectPopup(){return this.elementVisible("#defaultpreferencemanager","any")&&this.elementVisible(".mainContent","any")}async navigateToSettings(){return await k((async()=>this.elementExists(".shp")||this.elementVisible(".advance","any")||this.elementExists(".switch span:first-child")),10,500),this.elementExists(".shp")&&this.click(".shp"),await this.waitForElement(".prefPanel",5e3),this.elementVisible(".advance","any")&&this.click(".advance"),await k((()=>this.elementVisible(".switch span:first-child","any")),5,1e3)}async optOut(){if(await this.mainWorldEval("EVAL_TRUSTARC_FRAME_TEST"))return!0;let e=3e3;return await this.mainWorldEval("EVAL_TRUSTARC_FRAME_GTM")&&(e=1500),await k((()=>"complete"===document.readyState),20,100),await this.waitForElement(".mainContent[aria-hidden=false]",e),!!this.click(".rejectAll")||(this.elementExists(".prefPanel")&&await this.waitForElement('.prefPanel[style="visibility: visible;"]',e),this.click("#catDetails0")?(this.click(".submit"),this.waitForThenClick("#gwt-debug-close_id",e),!0):this.click(".required")?(this.waitForThenClick("#gwt-debug-close_id",e),!0):(await this.navigateToSettings(),this.click(".switch span:nth-child(1):not(.active)",!0),this.click(".submit"),this.waitForThenClick("#gwt-debug-close_id",10*e),!0))}async optIn(){return this.click(".call")||(await this.navigateToSettings(),this.click(".switch span:nth-child(2)",!0),this.click(".submit"),this.waitForElement("#gwt-debug-close_id",3e5).then((()=>{this.click("#gwt-debug-close_id")}))),!0}async test(){return await this.wait(500),await this.mainWorldEval("EVAL_TRUSTARC_FRAME_TEST")}},class extends d{constructor(){super(...arguments),this.name="Cybotcookiebot",this.prehideSelectors=["#CybotCookiebotDialog,#CybotCookiebotDialogBodyUnderlay,#dtcookie-container,#cookiebanner,#cb-cookieoverlay,.modal--cookie-banner,#cookiebanner_outer,#CookieBanner"]}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return await this.mainWorldEval("EVAL_COOKIEBOT_1")}async detectPopup(){return this.mainWorldEval("EVAL_COOKIEBOT_2")}async optOut(){await this.wait(500);let e=await this.mainWorldEval("EVAL_COOKIEBOT_3");return await this.wait(500),e=e&&await this.mainWorldEval("EVAL_COOKIEBOT_4"),e}async optIn(){return this.elementExists("#dtcookie-container")?this.click(".h-dtcookie-accept"):(this.click(".CybotCookiebotDialogBodyLevelButton:not(:checked):enabled",!0),this.click("#CybotCookiebotDialogBodyLevelButtonAccept"),this.click("#CybotCookiebotDialogBodyButtonAccept"),!0)}async test(){return await this.wait(500),await this.mainWorldEval("EVAL_COOKIEBOT_5")}},class extends d{constructor(){super(...arguments),this.name="Sourcepoint-frame",this.prehideSelectors=["div[id^='sp_message_container_'],.message-overlay","#sp_privacy_manager_container"],this.ccpaNotice=!1,this.ccpaPopup=!1,this.runContext={main:!0,frame:!0}}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){const e=new URL(location.href);return e.searchParams.has("message_id")&&"ccpa-notice.sp-prod.net"===e.hostname?(this.ccpaNotice=!0,!0):"ccpa-pm.sp-prod.net"===e.hostname?(this.ccpaPopup=!0,!0):("/index.html"===e.pathname||"/privacy-manager/index.html"===e.pathname||"/ccpa_pm/index.html"===e.pathname)&&(e.searchParams.has("message_id")||e.searchParams.has("requestUUID")||e.searchParams.has("consentUUID"))}async detectPopup(){return!!this.ccpaNotice||(this.ccpaPopup?await this.waitForElement(".priv-save-btn",2e3):(await this.waitForElement(".sp_choice_type_11,.sp_choice_type_12,.sp_choice_type_13,.sp_choice_type_ACCEPT_ALL,.sp_choice_type_SAVE_AND_EXIT",2e3),!this.elementExists(".sp_choice_type_9")))}async optIn(){return await this.waitForElement(".sp_choice_type_11,.sp_choice_type_ACCEPT_ALL",2e3),!!this.click(".sp_choice_type_11")||!!this.click(".sp_choice_type_ACCEPT_ALL")}isManagerOpen(){return"/privacy-manager/index.html"===location.pathname||"/ccpa_pm/index.html"===location.pathname}async optOut(){const e=this.autoconsent.config.logs;if(this.ccpaPopup){const e=document.querySelectorAll(".priv-purpose-container .sp-switch-arrow-block a.neutral.on .right");for(const t of e)t.click();const t=document.querySelectorAll(".priv-purpose-container .sp-switch-arrow-block a.switch-bg.on");for(const e of t)e.click();return this.click(".priv-save-btn")}if(!this.isManagerOpen()){if(!await this.waitForElement(".sp_choice_type_12,.sp_choice_type_13"))return!1;if(!this.elementExists(".sp_choice_type_12"))return this.click(".sp_choice_type_13");this.click(".sp_choice_type_12"),await k((()=>this.isManagerOpen()),200,100)}await this.waitForElement(".type-modal",2e4),this.waitForThenClick(".ccpa-stack .pm-switch[aria-checked=true] .slider",500,!0);try{const e=".sp_choice_type_REJECT_ALL",t=".reject-toggle",o=await Promise.race([this.waitForElement(e,2e3).then((e=>e?0:-1)),this.waitForElement(t,2e3).then((e=>e?1:-1)),this.waitForElement(".pm-features",2e3).then((e=>e?2:-1))]);if(0===o)return await this.waitForVisible(e),this.click(e);1===o?this.click(t):2===o&&(await this.waitForElement(".pm-features",1e4),this.click(".checked > span",!0),this.click(".chevron"))}catch(t){e.errors&&console.warn(t)}return this.click(".sp_choice_type_SAVE_AND_EXIT")}},class extends d{constructor(){super(...arguments),this.name="consentmanager.net",this.prehideSelectors=["#cmpbox,#cmpbox2"],this.apiAvailable=!1}get hasSelfTest(){return this.apiAvailable}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.apiAvailable=await this.mainWorldEval("EVAL_CONSENTMANAGER_1"),!!this.apiAvailable||this.elementExists("#cmpbox")}async detectPopup(){return this.apiAvailable?(await this.wait(500),await this.mainWorldEval("EVAL_CONSENTMANAGER_2")):this.elementVisible("#cmpbox .cmpmore","any")}async optOut(){return await this.wait(500),this.apiAvailable?await this.mainWorldEval("EVAL_CONSENTMANAGER_3"):!!this.click(".cmpboxbtnno")||(this.elementExists(".cmpwelcomeprpsbtn")?(this.click(".cmpwelcomeprpsbtn > a[aria-checked=true]",!0),this.click(".cmpboxbtnsave"),!0):(this.click(".cmpboxbtncustom"),await this.waitForElement(".cmptblbox",2e3),this.click(".cmptdchoice > a[aria-checked=true]",!0),this.click(".cmpboxbtnyescustomchoices"),this.hide("#cmpwrapper,#cmpbox","display"),!0))}async optIn(){return this.apiAvailable?await this.mainWorldEval("EVAL_CONSENTMANAGER_4"):this.click(".cmpboxbtnyes")}async test(){if(this.apiAvailable)return await this.mainWorldEval("EVAL_CONSENTMANAGER_5")}},class extends d{constructor(){super(...arguments),this.name="Evidon"}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("#_evidon_banner")}async detectPopup(){return this.elementVisible("#_evidon_banner","any")}async optOut(){return this.click("#_evidon-decline-button")||(h(A(),"#evidon-prefdiag-overlay,#evidon-prefdiag-background,#_evidon-background"),await this.waitForThenClick("#_evidon-option-button"),await this.waitForElement("#evidon-prefdiag-overlay",5e3),await this.wait(500),await this.waitForThenClick("#evidon-prefdiag-decline")),!0}async optIn(){return this.click("#_evidon-accept-button")}},class extends d{constructor(){super(...arguments),this.name="Onetrust",this.prehideSelectors=["#onetrust-banner-sdk,#onetrust-consent-sdk,.onetrust-pc-dark-filter,.js-consent-banner"],this.runContext={urlPattern:"^(?!.*https://www\\.nba\\.com/)"}}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("#onetrust-banner-sdk,#onetrust-pc-sdk")}async detectPopup(){return this.elementVisible("#onetrust-banner-sdk,#onetrust-pc-sdk","any")}async optOut(){return this.elementVisible("#onetrust-reject-all-handler,.ot-pc-refuse-all-handler,.js-reject-cookies","any")?this.click("#onetrust-reject-all-handler,.ot-pc-refuse-all-handler,.js-reject-cookies"):(this.elementExists("#onetrust-pc-btn-handler")?this.click("#onetrust-pc-btn-handler"):this.click(".ot-sdk-show-settings,button.js-cookie-settings"),await this.waitForElement("#onetrust-consent-sdk",2e3),await this.wait(1e3),this.click("#onetrust-consent-sdk input.category-switch-handler:checked,.js-editor-toggle-state:checked",!0),await this.wait(1e3),await this.waitForElement(".save-preference-btn-handler,.js-consent-save",2e3),this.click(".save-preference-btn-handler,.js-consent-save"),await this.waitForVisible("#onetrust-banner-sdk",5e3,"none"),!0)}async optIn(){return this.click("#onetrust-accept-btn-handler,#accept-recommended-btn-handler,.js-accept-cookies")}async test(){return await k((()=>this.mainWorldEval("EVAL_ONETRUST_1")),10,500)}},class extends d{constructor(){super(...arguments),this.name="Klaro",this.prehideSelectors=[".klaro"],this.settingsOpen=!1}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists(".klaro > .cookie-modal")?(this.settingsOpen=!0,!0):this.elementExists(".klaro > .cookie-notice")}async detectPopup(){return this.elementVisible(".klaro > .cookie-notice,.klaro > .cookie-modal","any")}async optOut(){return!!await this.mainWorldEval("EVAL_KLARO_TRY_API_OPT_OUT")||(!!this.click(".klaro .cn-decline")||(await this.mainWorldEval("EVAL_KLARO_OPEN_POPUP"),!!this.click(".klaro .cn-decline")||(this.click(".cm-purpose:not(.cm-toggle-all) > input:not(.half-checked,.required,.only-required),.cm-purpose:not(.cm-toggle-all) > div > input:not(.half-checked,.required,.only-required)",!0),this.click(".cm-btn-accept,.cm-button"))))}async optIn(){return!!this.click(".klaro .cm-btn-accept-all")||(this.settingsOpen?(this.click(".cm-purpose:not(.cm-toggle-all) > input.half-checked",!0),this.click(".cm-btn-accept")):this.click(".klaro .cookie-notice .cm-btn-success"))}async test(){return await this.mainWorldEval("EVAL_KLARO_1")}},class extends d{constructor(){super(...arguments),this.name="Uniconsent"}get prehideSelectors(){return[".unic",".modal:has(.unic)"]}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists(".unic .unic-box,.unic .unic-bar,.unic .unic-modal")}async detectPopup(){return this.elementVisible(".unic .unic-box,.unic .unic-bar,.unic .unic-modal","any")}async optOut(){if(await this.waitForElement(".unic button",1e3),document.querySelectorAll(".unic button").forEach((e=>{const t=e.textContent;(t.includes("Manage Options")||t.includes("Optionen verwalten"))&&e.click()})),await this.waitForElement(".unic input[type=checkbox]",1e3)){await this.waitForElement(".unic button",1e3),document.querySelectorAll(".unic input[type=checkbox]").forEach((e=>{e.checked&&e.click()}));for(const e of document.querySelectorAll(".unic button")){const t=e.textContent;for(const o of["Confirm Choices","Save Choices","Auswahl speichern"])if(t.includes(o))return e.click(),await this.wait(500),!0}}return!1}async optIn(){return this.waitForThenClick(".unic #unic-agree")}async test(){await this.wait(1e3);return!this.elementExists(".unic .unic-box,.unic .unic-bar")}},class extends d{constructor(){super(...arguments),this.prehideSelectors=[".cmp-root"],this.name="Conversant"}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists(".cmp-root .cmp-receptacle")}async detectPopup(){return this.elementVisible(".cmp-root .cmp-receptacle","any")}async optOut(){if(!await this.waitForThenClick(".cmp-main-button:not(.cmp-main-button--primary)"))return!1;if(!await this.waitForElement(".cmp-view-tab-tabs"))return!1;await this.waitForThenClick(".cmp-view-tab-tabs > :first-child"),await this.waitForThenClick(".cmp-view-tab-tabs > .cmp-view-tab--active:first-child");for(const e of Array.from(document.querySelectorAll(".cmp-accordion-item"))){e.querySelector(".cmp-accordion-item-title").click(),await k((()=>!!e.querySelector(".cmp-accordion-item-content.cmp-active")),10,50);const t=e.querySelector(".cmp-accordion-item-content.cmp-active");t.querySelectorAll(".cmp-toggle-actions .cmp-toggle-deny:not(.cmp-toggle-deny--active)").forEach((e=>e.click())),t.querySelectorAll(".cmp-toggle-actions .cmp-toggle-checkbox:not(.cmp-toggle-checkbox--active)").forEach((e=>e.click()))}return await this.click(".cmp-main-button:not(.cmp-main-button--primary)"),!0}async optIn(){return this.waitForThenClick(".cmp-main-button.cmp-main-button--primary")}async test(){return document.cookie.includes("cmp-data=0")}},class extends d{constructor(){super(...arguments),this.name="tiktok.com",this.runContext={urlPattern:"tiktok"}}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}getShadowRoot(){const e=document.querySelector("tiktok-cookie-banner");return e?e.shadowRoot:null}async detectCmp(){return this.elementExists("tiktok-cookie-banner")}async detectPopup(){return b(this.getShadowRoot().querySelector(".tiktok-cookie-banner"))}async optOut(){const e=this.autoconsent.config.logs,t=this.getShadowRoot().querySelector(".button-wrapper button:first-child");return t?(e.rulesteps&&console.log("[clicking]",t),t.click(),!0):(e.errors&&console.log("no decline button found"),!1)}async optIn(){const e=this.autoconsent.config.logs,t=this.getShadowRoot().querySelector(".button-wrapper button:last-child");return t?(e.rulesteps&&console.log("[clicking]",t),t.click(),!0):(e.errors&&console.log("no accept button found"),!1)}async test(){const e=document.cookie.match(/cookie-consent=([^;]+)/);if(!e)return!1;const t=JSON.parse(decodeURIComponent(e[1]));return Object.values(t).every((e=>"boolean"!=typeof e||!1===e))}},class extends d{constructor(){super(...arguments),this.name="airbnb",this.runContext={urlPattern:"^https://(www\\.)?airbnb\\.[^/]+/"},this.prehideSelectors=["div[data-testid=main-cookies-banner-container]",'div:has(> div:first-child):has(> div:last-child):has(> section [data-testid="strictly-necessary-cookies"])']}get hasSelfTest(){return!0}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("div[data-testid=main-cookies-banner-container]")}async detectPopup(){return this.elementVisible("div[data-testid=main-cookies-banner-container","any")}async optOut(){let e;for(await this.waitForThenClick("div[data-testid=main-cookies-banner-container] button._snbhip0");e=document.querySelector("[data-testid=modal-container] button[aria-checked=true]:not([disabled])");)e.click();return this.waitForThenClick("button[data-testid=save-btn]")}async optIn(){return this.waitForThenClick("div[data-testid=main-cookies-banner-container] button._148dgdpk")}async test(){return await k((()=>!!document.cookie.match("OptanonAlertBoxClosed")),20,200)}},class extends d{constructor(){super(...arguments),this.name="tumblr-com",this.runContext={urlPattern:"^https://(www\\.)?tumblr\\.com/"}}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}get prehideSelectors(){return["#cmp-app-container"]}async detectCmp(){return this.elementExists("#cmp-app-container")}async detectPopup(){return this.elementVisible("#cmp-app-container","any")}async optOut(){let e=document.querySelector("#cmp-app-container iframe"),t=e.contentDocument?.querySelector(".cmp-components-button.is-secondary");return!!t&&(t.click(),await k((()=>{const e=document.querySelector("#cmp-app-container iframe");return!!e.contentDocument?.querySelector(".cmp__dialog input")}),5,500),e=document.querySelector("#cmp-app-container iframe"),t=e.contentDocument?.querySelector(".cmp-components-button.is-secondary"),!!t&&(t.click(),!0))}async optIn(){const e=document.querySelector("#cmp-app-container iframe").contentDocument.querySelector(".cmp-components-button.is-primary");return!!e&&(e.click(),!0)}},class extends d{constructor(){super(...arguments),this.name="Admiral"}get hasSelfTest(){return!1}get isIntermediate(){return!1}get isCosmetic(){return!1}async detectCmp(){return this.elementExists("div > div[class*=Card] > div[class*=Frame] > div[class*=Pills] > button[class*=Pills__StyledPill]")}async detectPopup(){return this.elementVisible("div > div[class*=Card] > div[class*=Frame] > div[class*=Pills] > button[class*=Pills__StyledPill]","any")}async optOut(){const e="xpath///button[contains(., 'Afvis alle') or contains(., 'Reject all') or contains(., 'Odbaci sve') or contains(., 'Rechazar todo') or contains(., 'Atmesti visus') or contains(., 'Odmítnout vše') or contains(., 'Απόρριψη όλων') or contains(., 'Rejeitar tudo') or contains(., 'Tümünü reddet') or contains(., 'Отклонить все') or contains(., 'Noraidīt visu') or contains(., 'Avvisa alla') or contains(., 'Odrzuć wszystkie') or contains(., 'Alles afwijzen') or contains(., 'Отхвърляне на всички') or contains(., 'Rifiuta tutto') or contains(., 'Zavrni vse') or contains(., 'Az összes elutasítása') or contains(., 'Respingeți tot') or contains(., 'Alles ablehnen') or contains(., 'Tout rejeter') or contains(., 'Odmietnuť všetko') or contains(., 'Lükka kõik tagasi') or contains(., 'Hylkää kaikki')]";if(await this.waitForElement(e,500))return this.click(e);const t="xpath///button[contains(., 'Spara & avsluta') or contains(., 'Save & exit') or contains(., 'Uložit a ukončit') or contains(., 'Enregistrer et quitter') or contains(., 'Speichern & Verlassen') or contains(., 'Tallenna ja poistu') or contains(., 'Išsaugoti ir išeiti') or contains(., 'Opslaan & afsluiten') or contains(., 'Guardar y salir') or contains(., 'Shrani in zapri') or contains(., 'Uložiť a ukončiť') or contains(., 'Kaydet ve çıkış yap') or contains(., 'Сохранить и выйти') or contains(., 'Salvesta ja välju') or contains(., 'Salva ed esci') or contains(., 'Gem & afslut') or contains(., 'Αποθήκευση και έξοδος') or contains(., 'Saglabāt un iziet') or contains(., 'Mentés és kilépés') or contains(., 'Guardar e sair') or contains(., 'Zapisz & zakończ') or contains(., 'Salvare și ieșire') or contains(., 'Spremi i izađi') or contains(., 'Запазване и изход')]";if(await this.waitForThenClick("xpath///button[contains(., 'Zwecke') or contains(., 'Σκοποί') or contains(., 'Purposes') or contains(., 'Цели') or contains(., 'Eesmärgid') or contains(., 'Tikslai') or contains(., 'Svrhe') or contains(., 'Cele') or contains(., 'Účely') or contains(., 'Finalidades') or contains(., 'Mērķi') or contains(., 'Scopuri') or contains(., 'Fines') or contains(., 'Ändamål') or contains(., 'Finalités') or contains(., 'Doeleinden') or contains(., 'Tarkoitukset') or contains(., 'Scopi') or contains(., 'Amaçlar') or contains(., 'Nameni') or contains(., 'Célok') or contains(., 'Formål')]")&&await this.waitForVisible(t)){return this.elementSelector(t)[0].parentElement.parentElement.querySelectorAll("input[type=checkbox]:checked").forEach((e=>e.click())),this.click(t)}return!1}async optIn(){return this.click("xpath///button[contains(., 'Sprejmi vse') or contains(., 'Prihvati sve') or contains(., 'Godkänn alla') or contains(., 'Prijať všetko') or contains(., 'Принять все') or contains(., 'Aceptar todo') or contains(., 'Αποδοχή όλων') or contains(., 'Zaakceptuj wszystkie') or contains(., 'Accetta tutto') or contains(., 'Priimti visus') or contains(., 'Pieņemt visu') or contains(., 'Tümünü kabul et') or contains(., 'Az összes elfogadása') or contains(., 'Accept all') or contains(., 'Приемане на всички') or contains(., 'Accepter alle') or contains(., 'Hyväksy kaikki') or contains(., 'Tout accepter') or contains(., 'Alles accepteren') or contains(., 'Aktsepteeri kõik') or contains(., 'Přijmout vše') or contains(., 'Alles akzeptieren') or contains(., 'Aceitar tudo') or contains(., 'Acceptați tot')]")}}],C=class{constructor(e){this.autoconsentInstance=e}click(e,t=!1){const o=this.elementSelector(e);return this.autoconsentInstance.config.logs.rulesteps&&console.log("[click]",e,t,o),o.length>0&&(t?o.forEach((e=>e.click())):o[0].click()),o.length>0}elementExists(e){return this.elementSelector(e).length>0}elementVisible(e,t){const o=this.elementSelector(e),i=new Array(o.length);return o.forEach(((e,t)=>{i[t]=b(e)})),"none"===t?i.every((e=>!e)):0!==i.length&&("any"===t?i.some((e=>e)):i.every((e=>e)))}waitForElement(e,t=1e4){const o=Math.ceil(t/200);return this.autoconsentInstance.config.logs.rulesteps&&console.log("[waitForElement]",e),k((()=>this.elementSelector(e).length>0),o,200)}waitForVisible(e,t=1e4,o="any"){const i=Math.ceil(t/200);return this.autoconsentInstance.config.logs.rulesteps&&console.log("[waitForVisible]",e),k((()=>this.elementVisible(e,o)),i,200)}async waitForThenClick(e,t=1e4,o=!1){return await this.waitForElement(e,t),this.click(e,o)}wait(e){return this.autoconsentInstance.config.logs.rulesteps&&this.autoconsentInstance.config.logs.waits&&console.log("[wait]",e),new Promise((t=>{setTimeout((()=>{t(!0)}),e)}))}hide(e,t){this.autoconsentInstance.config.logs.rulesteps&&console.log("[hide]",e);return h(A(),e,t)}prehide(e){const t=A("autoconsent-prehide");return this.autoconsentInstance.config.logs.lifecycle&&console.log("[prehide]",t,location.href),h(t,e,"opacity")}undoPrehide(){const e=A("autoconsent-prehide");return this.autoconsentInstance.config.logs.lifecycle&&console.log("[undoprehide]",e,location.href),e&&e.remove(),!!e}async createOrUpdateStyleSheet(e,t){return t||(t=new CSSStyleSheet),t=await t.replace(e)}removeStyleSheet(e){return!!e&&(e.replace(""),!0)}querySingleReplySelector(e,t=document){if(e.startsWith("aria/"))return[];if(e.startsWith("xpath/")){const o=e.slice(6),i=document.evaluate(o,t,null,XPathResult.ANY_TYPE,null);let c=null;const n=[];for(;c=i.iterateNext();)n.push(c);return n}return e.startsWith("text/")||e.startsWith("pierce/")?[]:t.shadowRoot?Array.from(t.shadowRoot.querySelectorAll(e)):Array.from(t.querySelectorAll(e))}querySelectorChain(e){let t,o=document;for(const i of e){if(t=this.querySingleReplySelector(i,o),0===t.length)return[];o=t[0]}return t}elementSelector(e){return"string"==typeof e?this.querySingleReplySelector(e):this.querySelectorChain(e)}};(()=>{let e=0;const t=new Int32Array(256);for(let o=0;256!==o;o+=1)e=o,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,e=1&e?-306674912^e>>>1:e>>>1,t[o]=e})(),new Int8Array(new Int16Array([1]).buffer)[0];var v,f,E={attribute:/\[\s*(?:(?\*|[-\w]*)\|)?(?[-\w\u{0080}-\u{FFFF}]+)\s*(?:(?\W?=)\s*(?.+?)\s*(?[iIsS])?\s*)?\]/gu,id:/#(?(?:[-\w\u{0080}-\u{FFFF}]|\\.)+)/gu,class:/\.(?(?:[-\w\u{0080}-\u{FFFF}]|\\.)+)/gu,comma:/\s*,\s*/g,combinator:/\s*[\s>+~]\s*/g,"pseudo-element":/::(?[-\w\u{0080}-\u{FFFF}]+)(?:\((?:¶*)\))?/gu,"pseudo-class":/:(?[-\w\u{0080}-\u{FFFF}]+)(?:\((?¶*)\))?/gu,type:/(?:(?\*|[-\w]*)\|)?(?[-\w\u{0080}-\u{FFFF}]+)|\*/gu},x=Object.assign({},E);x["pseudo-element"]=RegExp(E["pseudo-element"].source.replace("(?¶*)","(?.*?)"),"gu"),x["pseudo-class"]=RegExp(E["pseudo-class"].source.replace("(?¶*)","(?.*)"),"gu"),(f=v||(v={}))[f.Normal=0]="Normal",f[f.Extended=1]="Extended",f[f.Invalid=2]="Invalid";var O,S,T,I,P,F,L,V,R=5011;function B(e){return"string"!=typeof e||0===e.length?R:function(e,t,o){let i=R;for(let c=t;c>>0}(e,0,e.length)}B("type:beacon"),B("type:csp"),B("type:csp"),B("type:cspviolationreport"),B("type:document"),B("type:other"),B("type:xhr"),B("type:font"),B("type:image"),B("type:image"),B("type:document"),B("type:document"),B("type:other"),B("type:media"),B("type:object"),B("type:object"),B("type:other"),B("type:ping"),B("type:other"),B("type:preflight"),B("type:script"),B("type:signedexchange"),B("type:other"),B("type:stylesheet"),B("type:subdocument"),B("type:subdocument"),B("type:other"),B("type:websocket"),B("type:other"),B("type:websocket"),B("type:xhr"),B("type:other"),B("type:xhr"),B("type:other"),(()=>{const e="undefined"!=typeof document?document.createElement("div"):{matches:()=>{}},t=/^[#.]?[\w-.]+$/})(),(S=O||(O={}))[S.unhide=1]="unhide",S[S.scriptInject=2]="scriptInject",S[S.isUnicode=4]="isUnicode",S[S.isClassSelector=8]="isClassSelector",S[S.isIdSelector=16]="isIdSelector",S[S.isHrefSelector=32]="isHrefSelector",S[S.remove=64]="remove",S[S.extended=128]="extended",S[S.isPureHasSelector=256]="isPureHasSelector",B("http"),B("https"),(I=T||(T={}))[I.fromDocument=1]="fromDocument",I[I.fromFont=2]="fromFont",I[I.fromHttp=4]="fromHttp",I[I.fromHttps=8]="fromHttps",I[I.fromImage=16]="fromImage",I[I.fromMedia=32]="fromMedia",I[I.fromObject=64]="fromObject",I[I.fromOther=128]="fromOther",I[I.fromPing=256]="fromPing",I[I.fromScript=512]="fromScript",I[I.fromStylesheet=1024]="fromStylesheet",I[I.fromSubdocument=2048]="fromSubdocument",I[I.fromWebsocket=4096]="fromWebsocket",I[I.fromXmlHttpRequest=8192]="fromXmlHttpRequest",I[I.firstParty=16384]="firstParty",I[I.thirdParty=32768]="thirdParty",I[I.isReplace=65536]="isReplace",I[I.isBadFilter=131072]="isBadFilter",I[I.isCSP=262144]="isCSP",I[I.isGenericHide=524288]="isGenericHide",I[I.isImportant=1048576]="isImportant",I[I.isSpecificHide=2097152]="isSpecificHide",I[I.isFullRegex=4194304]="isFullRegex",I[I.isRegex=8388608]="isRegex",I[I.isUnicode=16777216]="isUnicode",I[I.isLeftAnchor=33554432]="isLeftAnchor",I[I.isRightAnchor=67108864]="isRightAnchor",I[I.isException=134217728]="isException",I[I.isHostnameAnchor=268435456]="isHostnameAnchor",I[I.isRedirectRule=536870912]="isRedirectRule",I[I.isRedirect=1073741824]="isRedirect",T.fromDocument,T.fromFont,T.fromImage,T.fromMedia,T.fromObject,T.fromOther,T.fromPing,T.fromScript,T.fromStylesheet,T.fromSubdocument,T.fromWebsocket,T.fromXmlHttpRequest,T.fromPing,T.fromDocument,T.fromOther,T.fromXmlHttpRequest,T.fromFont,T.fromImage,T.fromImage,T.fromDocument,T.fromDocument,T.fromMedia,T.fromObject,T.fromObject,T.fromPing,T.fromScript,T.fromStylesheet,T.fromSubdocument,T.fromSubdocument,T.fromWebsocket,T.fromWebsocket,T.fromXmlHttpRequest,T.fromXmlHttpRequest,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,T.fromOther,(F=P||(P={}))[F.INVALID=0]="INVALID",F[F.BEGIF=1]="BEGIF",F[F.ELSE=2]="ELSE",F[F.ENDIF=3]="ENDIF",(V=L||(L={}))[V.NOT_SUPPORTED=0]="NOT_SUPPORTED",V[V.NETWORK=1]="NETWORK",V[V.COSMETIC=2]="COSMETIC",V[V.NOT_SUPPORTED_EMPTY=100]="NOT_SUPPORTED_EMPTY",V[V.NOT_SUPPORTED_COMMENT=101]="NOT_SUPPORTED_COMMENT",V[V.NOT_SUPPORTED_ADGUARD=102]="NOT_SUPPORTED_ADGUARD";var N="video/flv",M={contentType:`${N};base64`,aliases:[N,".flv","flv"],body:"RkxWAQEAAAAJAAAAABIAALgAAAAAAAAAAgAKb25NZXRhRGF0YQgAAAAIAAhkdXJhdGlvbgAAAAAAAAAAAAAFd2lkdGgAP/AAAAAAAAAABmhlaWdodAA/8AAAAAAAAAANdmlkZW9kYXRhcmF0ZQBAaGoAAAAAAAAJZnJhbWVyYXRlAEBZAAAAAAAAAAx2aWRlb2NvZGVjaWQAQAAAAAAAAAAAB2VuY29kZXICAA1MYXZmNTcuNDEuMTAwAAhmaWxlc2l6ZQBAaoAAAAAAAAAACQAAAMM="},j="image/gif",U={contentType:`${j};base64`,aliases:[j,".gif","gif"],body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},D="text/html",z={contentType:D,aliases:[D,".html","html",".htm","htm","noopframe","noop.html"],body:""},G="image/vnd.microsoft.icon",q={contentType:`${G};base64`,aliases:[G,".ico","ico"],body:"AAABAAEAAQEAAAEAGAAwAAAAFgAAACgAAAABAAAAAgAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAAAAA=="},W="image/jpeg",H={contentType:`${W};base64`,aliases:[W,".jpg","jpg",".jpeg","jpeg"],body:"/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k="},K="application/javascript",Q={contentType:K,aliases:[K,".js","js","javascript",".jsx","jsx","typescript",".ts","ts","noop.js","noopjs"],body:""},Y="application/json",X={contentType:Y,aliases:[Y,".json","json"],body:"0"},Z="audio/mpeg",$={contentType:`${Z};base64`,aliases:[Z,".mp3","mp3","noop-0.1s.mp3","noopmp3-0.1s"],body:"/+MYxAAAAANIAAAAAExBTUUzLjk4LjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},J="video/mp4",ee={contentType:`${J};base64`,aliases:[J,".mp4","mp4",".m4a","m4a",".m4p","m4p",".m4b","m4b",".m4r","m4r",".m4v","m4v","noop-1s.mp4","noopmp4-1s"],body:"AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAC721kYXQhEAUgpBv/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3pwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcCEQBSCkG//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADengAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAsJtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAALwABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAB7HRyYWsAAABcdGtoZAAAAAMAAAAAAAAAAAAAAAIAAAAAAAAALwAAAAAAAAAAAAAAAQEAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAAC8AAAAAAAEAAAAAAWRtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAKxEAAAIAFXEAAAAAAAtaGRscgAAAAAAAAAAc291bgAAAAAAAAAAAAAAAFNvdW5kSGFuZGxlcgAAAAEPbWluZgAAABBzbWhkAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAADTc3RibAAAAGdzdHNkAAAAAAAAAAEAAABXbXA0YQAAAAAAAAABAAAAAAAAAAAAAgAQAAAAAKxEAAAAAAAzZXNkcwAAAAADgICAIgACAASAgIAUQBUAAAAAAfQAAAHz+QWAgIACEhAGgICAAQIAAAAYc3R0cwAAAAAAAAABAAAAAgAABAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAIAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAFzAAABdAAAABRzdGNvAAAAAAAAAAEAAAAsAAAAYnVkdGEAAABabWV0YQAAAAAAAAAhaGRscgAAAAAAAAAAbWRpcmFwcGwAAAAAAAAAAAAAAAAtaWxzdAAAACWpdG9vAAAAHWRhdGEAAAABAAAAAExhdmY1Ni40MC4xMDE="},te="application/pdf",oe={contentType:`${te};base64`,aliases:[te,".pdf","pdf"],body:"JVBERi0xLgoxIDAgb2JqPDwvUGFnZXMgMiAwIFI+PmVuZG9iagoyIDAgb2JqPDwvS2lkc1szIDAgUl0vQ291bnQgMT4+ZW5kb2JqCjMgMCBvYmo8PC9QYXJlbnQgMiAwIFI+PmVuZG9iagp0cmFpbGVyIDw8L1Jvb3QgMSAwIFI+Pg=="},ie="image/png",ce={contentType:`${ie};base64`,aliases:[ie,".png","png"],body:"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="},ne="image/svg+xml",ae={contentType:ne,aliases:[ne,".svg","svg"],body:"https://raw.githubusercontent.com/mathiasbynens/small/master/svg.svg"},se="text/plain",re={contentType:se,aliases:[se,".txt","txt","text","nooptext","noop.txt"],body:""},le="audio/wav",pe={contentType:`${le};base64`,aliases:[le,".wav","wav"],body:"UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA="},de="video/webm",ue={contentType:`${de};base64`,aliases:[de,".webm","webm"],body:"GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA="},me="image/webp",Ae={contentType:`${me};base64`,aliases:[me,".webp","webp"],body:"UklGRhIAAABXRUJQVlA4TAYAAAAvQWxvAGs="},he="video/wmv",ke={contentType:`${he};base64`,aliases:[he,".wmv","wmv"],body:"MCaydY5mzxGm2QCqAGLObOUBAAAAAAAABQAAAAECodyrjEepzxGO5ADADCBTZWgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcCAAAAAAAAAIA+1d6xnQEAAAAAAAAAAMAF2QEAAAAAAAAAAAAAAAAcDAAAAAAAAAIAAACADAAAgAwAAEANAwC1A79fLqnPEY7jAMAMIFNlLgAAAAAAAAAR0tOruqnPEY7mAMAMIFNlBgAAAAAAQKTQ0gfj0hGX8ACgyV6oUGQAAAAAAAAAAQAoAFcATQAvAEUAbgBjAG8AZABpAG4AZwBTAGUAdAB0AGkAbgBnAHMAAAAAABwATABhAHYAZgA1ADcALgA0ADEALgAxADAAMAAAAJEH3Le3qc8RjuYAwAwgU2WBAAAAAAAAAMDvGbxNW88RqP0AgF9cRCsAV/sgVVvPEaj9AIBfXEQrAAAAAAAAAAAzAAAAAAAAAAEAAAAAAAEAAAABAAAAAigAKAAAAAEAAAABAAAAAQAYAE1QNDMDAAAAAAAAAAAAAAAAAAAAAAAAAEBS0YYdMdARo6QAoMkDSPZMAAAAAAAAAEFS0YYdMdARo6QAoMkDSPYBAAAAAQAKAG0AcwBtAHAAZQBnADQAdgAzAAAAAAAEAE1QNDM2JrJ1jmbPEabZAKoAYs5sMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQ=="};(()=>{const e={};for(const t of[M,U,z,q,H,Q,X,$,ee,oe,ce,ae,re,pe,ue,Ae,ke])for(const o of t.aliases)e[o]=t})();var be=[/accept cookies/gi,/accept all/gi,/reject all/gi,/only necessary cookies/gi,/by clicking.*(accept|agree|allow)/gi,/by continuing/gi,/we (use|serve)( optional)? cookies/gi,/we are using cookies/gi,/use of cookies/gi,/(this|our) (web)?site.*cookies/gi,/cookies (and|or) .* technologies/gi,/such as cookies/gi,/read more about.*cookies/gi,/consent to.*cookies/gi,/we and our partners.*cookies/gi,/we.*store.*information.*such as.*cookies/gi,/store and\/or access information.*on a device/gi,/personalised ads and content, ad and content measurement/gi];var ge=[{name:"192.com",detectCmp:[{exists:".ont-cookies"}],detectPopup:[{visible:".ont-cookies"}],optIn:[{click:".ont-btn-main.ont-cookies-btn.js-ont-btn-ok2"}],optOut:[{click:".ont-cookes-btn-manage"},{click:".ont-btn-main.ont-cookies-btn.js-ont-btn-choose"}],test:[{eval:"EVAL_ONENINETWO_0"}]},{name:"1password-com",cosmetic:!0,prehideSelectors:['footer #footer-root [aria-label="Cookie Consent"]'],detectCmp:[{exists:'footer #footer-root [aria-label="Cookie Consent"]'}],detectPopup:[{visible:'footer #footer-root [aria-label="Cookie Consent"]'}],optIn:[{click:'footer #footer-root [aria-label="Cookie Consent"] button'}],optOut:[{hide:'footer #footer-root [aria-label="Cookie Consent"]'}]},{name:"aa",vendorUrl:"https://aa.com",prehideSelectors:[],cosmetic:!0,detectCmp:[{exists:"#aa_optoutmulti-Modal,#cookieBannerMessage"}],detectPopup:[{visible:"#aa_optoutmulti-Modal,#cookieBannerMessage"}],optIn:[{hide:"#aa_optoutmulti-Modal,#cookieBannerMessage"},{waitForThenClick:"#aa_optoutmulti_checkBox"},{waitForThenClick:"#aa_optoutmulti-Modal button.optoutmulti_button"}],optOut:[{hide:"#aa_optoutmulti-Modal,#cookieBannerMessage"}]},{name:"abc",vendorUrl:"https://abc.net.au",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?abc\\.net\\.au/"},prehideSelectors:[],detectCmp:[{exists:"[data-component=CookieBanner]"}],detectPopup:[{visible:"[data-component=CookieBanner] [data-component=CookieBanner_AcceptAll]"}],optIn:[{waitForThenClick:"[data-component=CookieBanner] [data-component=CookieBanner_AcceptAll]"}],optOut:[{waitForThenClick:"[data-component=CookieBanner] [data-component=CookieBanner_AcceptABCRequired]"}],test:[{eval:"EVAL_ABC_TEST"}]},{name:"abconcerts.be",vendorUrl:"https://unknown",intermediate:!1,prehideSelectors:["dialog.cookie-consent"],detectCmp:[{exists:"dialog.cookie-consent form.cookie-consent__form"}],detectPopup:[{visible:"dialog.cookie-consent form.cookie-consent__form"}],optIn:[{waitForThenClick:"dialog.cookie-consent form.cookie-consent__form button[value=yes]"}],optOut:[{if:{exists:"dialog.cookie-consent form.cookie-consent__form button[value=no]"},then:[{click:"dialog.cookie-consent form.cookie-consent__form button[value=no]"}],else:[{click:"dialog.cookie-consent form.cookie-consent__form button.cookie-consent__options-toggle"},{waitForThenClick:'dialog.cookie-consent form.cookie-consent__form button[value="save_options"]'}]}]},{name:"acris",prehideSelectors:["div.acris-cookie-consent"],detectCmp:[{exists:"[data-acris-cookie-consent]"}],detectPopup:[{visible:".acris-cookie-consent.is--modal"}],optIn:[{waitForVisible:"#ccConsentAcceptAllButton",check:"any"},{wait:500},{waitForThenClick:"#ccConsentAcceptAllButton"}],optOut:[{waitForVisible:"#ccAcceptOnlyFunctional",check:"any"},{wait:500},{waitForThenClick:"#ccAcceptOnlyFunctional"}]},{name:"activobank.pt",runContext:{urlPattern:"^https://(www\\.)?activobank\\.pt"},prehideSelectors:["aside#cookies,.overlay-cookies"],detectCmp:[{exists:"#cookies .cookies-btn"}],detectPopup:[{visible:"#cookies #submitCookies"}],optIn:[{waitForThenClick:"#cookies #submitCookies"}],optOut:[{waitForThenClick:"#cookies #rejectCookies"}]},{name:"Adroll",prehideSelectors:["#adroll_consent_container"],detectCmp:[{exists:"#adroll_consent_container"}],detectPopup:[{visible:"#adroll_consent_container"}],optIn:[{waitForThenClick:"#adroll_consent_accept"}],optOut:[{waitForThenClick:"#adroll_consent_reject"}],test:[{eval:"EVAL_ADROLL_0"}]},{name:"affinity.serif.com",detectCmp:[{exists:".c-cookie-banner button[data-qa='allow-all-cookies']"}],detectPopup:[{visible:".c-cookie-banner"}],optIn:[{click:'button[data-qa="allow-all-cookies"]'}],optOut:[{click:'button[data-qa="manage-cookies"]'},{waitFor:'.c-cookie-banner ~ [role="dialog"]'},{waitForThenClick:'.c-cookie-banner ~ [role="dialog"] input[type="checkbox"][value="true"]',all:!0},{click:'.c-cookie-banner ~ [role="dialog"] .c-modal__action button'}],test:[{wait:500},{eval:"EVAL_AFFINITY_SERIF_COM_0"}]},{name:"agolde.com",cosmetic:!0,prehideSelectors:["#modal-1 div[data-micromodal-close]"],detectCmp:[{exists:"#modal-1 div[aria-labelledby=modal-1-title]"}],detectPopup:[{exists:"#modal-1 div[data-micromodal-close]"}],optIn:[{click:'button[aria-label="Close modal"]'}],optOut:[{hide:"#modal-1 div[data-micromodal-close]"}]},{name:"aliexpress",vendorUrl:"https://aliexpress.com/",runContext:{urlPattern:"^https://.*\\.aliexpress\\.com/"},prehideSelectors:["#gdpr-new-container"],detectCmp:[{exists:"#gdpr-new-container,#voyager-gdpr > div"}],detectPopup:[{visible:"#gdpr-new-container,#voyager-gdpr > div"}],optIn:[{waitForThenClick:"#gdpr-new-container .btn-accept,#voyager-gdpr > div > div > button:nth-child(1)"}],optOut:[{if:{exists:"#voyager-gdpr > div"},then:[{waitForThenClick:"#voyager-gdpr > div > div > button:nth-child(2)"}],else:[{waitForThenClick:"#gdpr-new-container .btn-more"},{waitFor:"#gdpr-new-container .gdpr-dialog-switcher"},{click:"#gdpr-new-container .switcher-on",all:!0,optional:!0},{click:"#gdpr-new-container .btn-save"}]}]},{name:"almacmp",prehideSelectors:["#alma-cmpv2-container"],detectCmp:[{exists:"#alma-cmpv2-container"}],detectPopup:[{visible:"#alma-cmpv2-container #almacmp-modal-layer1"}],optIn:[{waitForThenClick:"#alma-cmpv2-container #almacmp-modal-layer1 #almacmp-modalConfirmBtn"}],optOut:[{waitForThenClick:"#alma-cmpv2-container #almacmp-modal-layer1 #almacmp-modalSettingBtn"},{waitFor:"#alma-cmpv2-container #almacmp-modal-layer2"},{waitForThenClick:"#alma-cmpv2-container #almacmp-modal-layer2 #almacmp-reject-all-layer2"}],test:[{eval:"EVAL_ALMACMP_0"}]},{name:"altium.com",cosmetic:!0,prehideSelectors:[".altium-privacy-bar"],detectCmp:[{exists:".altium-privacy-bar"}],detectPopup:[{exists:".altium-privacy-bar"}],optIn:[{click:"a.altium-privacy-bar__btn"}],optOut:[{hide:".altium-privacy-bar"}]},{name:"amazon.com",prehideSelectors:['span[data-action="sp-cc"][data-sp-cc*="rejectAllAction"]'],detectCmp:[{exists:'span[data-action="sp-cc"][data-sp-cc*="rejectAllAction"]'}],detectPopup:[{visible:'span[data-action="sp-cc"][data-sp-cc*="rejectAllAction"]'}],optIn:[{waitForVisible:"#sp-cc-accept"},{wait:500},{click:"#sp-cc-accept"}],optOut:[{waitForVisible:"#sp-cc-rejectall-link"},{wait:500},{click:"#sp-cc-rejectall-link"}]},{name:"amex",vendorUrl:"https://www.americanexpress.com/",cosmetic:!1,prehideSelectors:["#user-consent-management-granular-banner-overlay"],detectCmp:[{exists:"#user-consent-management-granular-banner-overlay"}],detectPopup:[{visible:"#user-consent-management-granular-banner-overlay"}],optIn:[{waitForThenClick:"[data-testid=granular-banner-button-accept-all]"}],optOut:[{waitForThenClick:"[data-testid=granular-banner-button-decline-all]"}]},{name:"aquasana.com",prehideSelectors:["#consent-tracking"],detectCmp:[{exists:"#consent-tracking"}],detectPopup:[{exists:"#consent-tracking"}],optIn:[{waitForThenClick:"#consent-tracking .affirm.btn"}],optOut:[{if:{exists:"#consent-tracking .decline.btn"},then:[{click:"#consent-tracking .decline.btn"}],else:[{hide:"#consent-tracking"}]}]},{name:"arbeitsagentur",vendorUrl:"https://www.arbeitsagentur.de/",prehideSelectors:[".modal-open bahf-cookie-disclaimer-dpl3"],detectCmp:[{exists:"bahf-cookie-disclaimer-dpl3"}],detectPopup:[{visible:"bahf-cookie-disclaimer-dpl3"}],optIn:[{waitForThenClick:["bahf-cookie-disclaimer-dpl3","#bahf-cookie-disclaimer-modal .ba-btn-primary"]}],optOut:[{waitForThenClick:["bahf-cookie-disclaimer-dpl3","#bahf-cookie-disclaimer-modal .ba-btn-contrast"]}],test:[{eval:"EVAL_ARBEITSAGENTUR_TEST"}]},{name:"asus",vendorUrl:"https://www.asus.com/",runContext:{urlPattern:"^https://www\\.asus\\.com/"},prehideSelectors:["#cookie-policy-info,#cookie-policy-info-bg"],detectCmp:[{exists:"#cookie-policy-info"}],detectPopup:[{visible:"#cookie-policy-info"}],optIn:[{waitForThenClick:'#cookie-policy-info [data-agree="Accept Cookies"]'}],optOut:[{if:{exists:"#cookie-policy-info .btn-reject"},then:[{waitForThenClick:"#cookie-policy-info .btn-reject"}],else:[{waitForThenClick:"#cookie-policy-info .btn-setting"},{waitForThenClick:'#cookie-policy-lightbox-wrapper [data-agree="Save Settings"]'}]}]},{name:"athlinks-com",runContext:{urlPattern:"^https://(www\\.)?athlinks\\.com/"},cosmetic:!0,prehideSelectors:["#footer-container ~ div"],detectCmp:[{exists:"#footer-container ~ div"}],detectPopup:[{visible:"#footer-container > div"}],optIn:[{click:"#footer-container ~ div button"}],optOut:[{hide:"#footer-container ~ div"}]},{name:"ausopen.com",cosmetic:!0,detectCmp:[{exists:".gdpr-popup__message"}],detectPopup:[{visible:".gdpr-popup__message"}],optOut:[{hide:".gdpr-popup__message"}],optIn:[{click:".gdpr-popup__message button"}]},{name:"automattic-cmp-optout",prehideSelectors:['form[class*="cookie-banner"][method="post"]'],detectCmp:[{exists:'form[class*="cookie-banner"][method="post"]'}],detectPopup:[{visible:'form[class*="cookie-banner"][method="post"]'}],optIn:[{click:'a[class*="accept-all-button"]'}],optOut:[{click:'form[class*="cookie-banner"] div[class*="simple-options"] a[class*="customize-button"]'},{waitForThenClick:"input[type=checkbox][checked]:not([disabled])",all:!0},{click:'a[class*="accept-selection-button"]'}]},{name:"aws.amazon.com",prehideSelectors:["#awsccc-cb-content","#awsccc-cs-container","#awsccc-cs-modalOverlay","#awsccc-cs-container-inner"],detectCmp:[{exists:"#awsccc-cb-content"}],detectPopup:[{visible:"#awsccc-cb-content"}],optIn:[{click:"button[data-id=awsccc-cb-btn-accept"}],optOut:[{click:"button[data-id=awsccc-cb-btn-customize]"},{waitFor:"input[aria-checked]"},{click:"input[aria-checked=true]",all:!0,optional:!0},{click:"button[data-id=awsccc-cs-btn-save]"}]},{name:"axeptio",prehideSelectors:[".axeptio_widget"],detectCmp:[{exists:".axeptio_widget"}],detectPopup:[{visible:".axeptio_widget"}],optIn:[{waitFor:".axeptio-widget--open"},{click:"button#axeptio_btn_acceptAll"}],optOut:[{waitFor:".axeptio-widget--open"},{click:"button#axeptio_btn_dismiss"}],test:[{eval:"EVAL_AXEPTIO_0"}]},{name:"baden-wuerttemberg.de",prehideSelectors:[".cookie-alert.t-dark"],cosmetic:!0,detectCmp:[{exists:".cookie-alert.t-dark"}],detectPopup:[{visible:".cookie-alert.t-dark"}],optIn:[{click:".cookie-alert__form input:not([disabled]):not([checked])"},{click:".cookie-alert__button button"}],optOut:[{hide:".cookie-alert.t-dark"}]},{name:"bahn-de",vendorUrl:"https://www.bahn.de/",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?bahn\\.de/"},intermediate:!1,prehideSelectors:[],detectCmp:[{exists:["body > div:first-child","#consent-layer"]}],detectPopup:[{visible:["body > div:first-child","#consent-layer"]}],optIn:[{waitForThenClick:["body > div:first-child","#consent-layer .js-accept-all-cookies"]}],optOut:[{waitForThenClick:["body > div:first-child","#consent-layer .js-accept-essential-cookies"]}],test:[{eval:"EVAL_BAHN_TEST"}]},{name:"bbb.org",runContext:{urlPattern:"^https://www\\.bbb\\.org/"},cosmetic:!0,prehideSelectors:['div[aria-label="use of cookies on bbb.org"]'],detectCmp:[{exists:'div[aria-label="use of cookies on bbb.org"]'}],detectPopup:[{visible:'div[aria-label="use of cookies on bbb.org"]'}],optIn:[{click:'div[aria-label="use of cookies on bbb.org"] button.bds-button-unstyled span.visually-hidden'}],optOut:[{hide:'div[aria-label="use of cookies on bbb.org"]'}]},{name:"bing.com",prehideSelectors:["#bnp_container"],detectCmp:[{exists:"#bnp_cookie_banner"}],detectPopup:[{visible:"#bnp_cookie_banner"},{visible:"#bnp_btn_accept,#bnp_btn_reject"}],optIn:[{waitForThenClick:"#bnp_btn_accept"}],optOut:[{wait:500},{waitForThenClick:"#bnp_btn_reject"}],test:[{eval:"EVAL_BING_0"}]},{name:"blocksy",vendorUrl:"https://creativethemes.com/blocksy/docs/extensions/cookies-consent/",cosmetic:!1,runContext:{main:!0,frame:!1},intermediate:!1,prehideSelectors:[".cookie-notification"],detectCmp:[{exists:"#blocksy-ext-cookies-consent-styles-css"}],detectPopup:[{visible:".cookie-notification"}],optIn:[{click:".cookie-notification .ct-cookies-decline-button"}],optOut:[{waitForThenClick:".cookie-notification .ct-cookies-decline-button"}],test:[{eval:"EVAL_BLOCKSY_0"}]},{name:"borlabs",detectCmp:[{exists:"._brlbs-block-content"}],detectPopup:[{visible:"._brlbs-bar-wrap,._brlbs-box-wrap"}],optIn:[{click:"a[data-cookie-accept-all]"}],optOut:[{click:"a[data-cookie-individual]"},{waitForVisible:".cookie-preference"},{click:"input[data-borlabs-cookie-checkbox]:checked",all:!0,optional:!0},{click:"#CookiePrefSave"},{wait:500}],prehideSelectors:["#BorlabsCookieBox"],test:[{eval:"EVAL_BORLABS_0"}]},{name:"bundesregierung.de",prehideSelectors:[".bpa-cookie-banner"],detectCmp:[{exists:".bpa-cookie-banner"}],detectPopup:[{visible:".bpa-cookie-banner .bpa-module-full-hero"}],optIn:[{click:".bpa-accept-all-button"}],optOut:[{wait:500,comment:"click is not immediately recognized"},{waitForThenClick:".bpa-close-button"}],test:[{eval:"EVAL_BUNDESREGIERUNG_DE_0"}]},{name:"burpee.com",cosmetic:!0,prehideSelectors:["#notice-cookie-block"],detectCmp:[{exists:"#notice-cookie-block"}],detectPopup:[{exists:"#html-body #notice-cookie-block"}],optIn:[{click:"#btn-cookie-allow"}],optOut:[{hide:"#html-body #notice-cookie-block, #notice-cookie"}]},{name:"canva.com",prehideSelectors:['div[role="dialog"] a[data-anchor-id="cookie-policy"]'],detectCmp:[{exists:'div[role="dialog"] a[data-anchor-id="cookie-policy"]'}],detectPopup:[{exists:'div[role="dialog"] a[data-anchor-id="cookie-policy"]'}],optIn:[{click:'div[role="dialog"] button:nth-child(1)'}],optOut:[{if:{exists:'div[role="dialog"] button:nth-child(3)'},then:[{click:'div[role="dialog"] button:nth-child(2)'}],else:[{click:'div[role="dialog"] button:nth-child(2)'},{waitFor:'div[role="dialog"] a[data-anchor-id="cookie-policy"]'},{waitFor:'div[role="dialog"] button[role=switch]'},{click:'div[role="dialog"] button:nth-child(2):not([role])'},{click:'div[role="dialog"] div:last-child button:only-child'}]}],test:[{eval:"EVAL_CANVA_0"}]},{name:"canyon.com",runContext:{urlPattern:"^https://www\\.canyon\\.com/"},prehideSelectors:["div.modal.cookiesModal.is-open"],detectCmp:[{exists:"div.modal.cookiesModal.is-open"}],detectPopup:[{visible:"div.modal.cookiesModal.is-open"}],optIn:[{click:'div.cookiesModal__buttonWrapper > button[data-closecause="close-by-submit"]'}],optOut:[{click:'div.cookiesModal__buttonWrapper > button[data-closecause="close-by-manage-cookies"]'},{waitForThenClick:"button#js-manage-data-privacy-save-button"}]},{name:"cassie",vendorUrl:"https://trustcassie.com",cosmetic:!1,runContext:{main:!0,frame:!1},prehideSelectors:[".cassie-cookie-module"],detectCmp:[{exists:".cassie-pre-banner"}],detectPopup:[{visible:"#cassie_pre_banner_text"}],optIn:[{waitForThenClick:".cassie-accept-all"}],optOut:[{waitForThenClick:".cassie-reject-all"}]},{name:"cc-banner-springer",prehideSelectors:[".cc-banner[data-cc-banner]"],detectCmp:[{exists:".cc-banner[data-cc-banner]"}],detectPopup:[{visible:".cc-banner[data-cc-banner]"}],optIn:[{waitForThenClick:".cc-banner[data-cc-banner] button[data-cc-action=accept]"}],optOut:[{if:{exists:".cc-banner[data-cc-banner] button[data-cc-action=reject]"},then:[{click:".cc-banner[data-cc-banner] button[data-cc-action=reject]"}],else:[{waitForThenClick:".cc-banner[data-cc-banner] button[data-cc-action=preferences]"},{waitFor:".cc-preferences[data-cc-preferences]"},{click:".cc-preferences[data-cc-preferences] input[type=radio][data-cc-action=toggle-category][value=off]",all:!0,optional:!0},{if:{exists:".cc-preferences[data-cc-preferences] button[data-cc-action=reject]"},then:[{click:".cc-preferences[data-cc-preferences] button[data-cc-action=reject]"}],else:[{click:".cc-preferences[data-cc-preferences] button[data-cc-action=save]"}]}]}],test:[{eval:"EVAL_CC_BANNER2_0"}]},{name:"cc_banner",cosmetic:!0,prehideSelectors:[".cc_banner-wrapper"],detectCmp:[{exists:".cc_banner-wrapper"}],detectPopup:[{visible:".cc_banner"}],optIn:[{click:".cc_btn_accept_all"}],optOut:[{hide:".cc_banner-wrapper"}]},{name:"check24-partnerprogramm-de",prehideSelectors:["[data-modal-content]:has([data-toggle-target^='cookie'])"],detectCmp:[{exists:"[data-toggle-target^='cookie']"}],detectPopup:[{visible:"[data-toggle-target^='cookie']",check:"any"}],optIn:[{waitForThenClick:"[data-cookie-accept-all]"}],optOut:[{waitForThenClick:"[data-cookie-dismiss-all]"}]},{name:"ciaopeople.it",prehideSelectors:["#cp-gdpr-choices"],detectCmp:[{exists:"#cp-gdpr-choices"}],detectPopup:[{visible:"#cp-gdpr-choices"}],optIn:[{waitForThenClick:".gdpr-btm__right > button:nth-child(2)"}],optOut:[{waitForThenClick:".gdpr-top-content > button"},{waitFor:".gdpr-top-back"},{waitForThenClick:".gdpr-btm__right > button:nth-child(1)"}],test:[{visible:"#cp-gdpr-choices",check:"none"}]},{vendorUrl:"https://www.civicuk.com/cookie-control/",name:"civic-cookie-control",prehideSelectors:["#ccc-module,#ccc-overlay,#ccc"],detectCmp:[{exists:"#ccc-module,#ccc-notify"}],detectPopup:[{visible:"#ccc"},{visible:"#ccc-module,#ccc-notify"}],optOut:[{if:{exists:"#ccc-notify"},then:[{waitForThenClick:["#ccc #ccc-notify .ccc-notify-buttons","xpath///button[contains(., 'Settings') or contains(., 'Cookie Preferences')]"]},{waitForVisible:"#ccc-module"}]},{if:{exists:"#ccc-reject-settings"},then:[{waitForThenClick:"#ccc-reject-settings"}],else:[{waitForThenClick:"#ccc-dismiss-button"}]}],optIn:[{waitForThenClick:"#ccc-recommended-settings,#ccc-notify-accept"}]},{name:"click.io",prehideSelectors:["#cl-consent"],detectCmp:[{exists:"#cl-consent"}],detectPopup:[{visible:"#cl-consent"}],optIn:[{waitForThenClick:'#cl-consent [data-role="b_agree"]'}],optOut:[{waitFor:'#cl-consent [data-role="b_options"]'},{wait:500},{click:'#cl-consent [data-role="b_options"]'},{waitFor:'.cl-consent-popup.cl-consent-visible [data-role="alloff"]'},{click:'.cl-consent-popup.cl-consent-visible [data-role="alloff"]',all:!0},{click:'[data-role="b_save"]'}],test:[{eval:"EVAL_CLICKIO_0",comment:"TODO: this only checks if we interacted at all"}]},{name:"clinch",intermediate:!1,runContext:{frame:!1,main:!0},prehideSelectors:[".consent-modal[role=dialog]"],detectCmp:[{exists:".consent-modal[role=dialog]"}],detectPopup:[{visible:".consent-modal[role=dialog]"}],optIn:[{click:"#consent_agree"}],optOut:[{if:{exists:"#consent_reject"},then:[{click:"#consent_reject"}],else:[{click:"#manage_cookie_preferences"},{click:"#cookie_consent_preferences input:checked",all:!0,optional:!0},{click:"#consent_save"}]}],test:[{eval:"EVAL_CLINCH_0"}]},{name:"clustrmaps.com",runContext:{urlPattern:"^https://(www\\.)?clustrmaps\\.com/"},cosmetic:!0,prehideSelectors:["#gdpr-cookie-message"],detectCmp:[{exists:"#gdpr-cookie-message"}],detectPopup:[{visible:"#gdpr-cookie-message"}],optIn:[{click:"button#gdpr-cookie-accept"}],optOut:[{hide:"#gdpr-cookie-message"}]},{name:"coinbase",intermediate:!1,runContext:{frame:!0,main:!0,urlPattern:"^https://(www|help)\\.coinbase\\.com"},prehideSelectors:[],detectCmp:[{exists:"div[class^=CookieBannerContent__Container]"}],detectPopup:[{visible:"div[class^=CookieBannerContent__Container]"}],optIn:[{click:"div[class^=CookieBannerContent__CTA] :nth-last-child(1)"}],optOut:[{click:"button[class^=CookieBannerContent__Settings]"},{click:"div[class^=CookiePreferencesModal__CategoryContainer] input:checked",all:!0,optional:!0},{click:"div[class^=CookiePreferencesModal__ButtonContainer] > button"}],test:[{eval:"EVAL_COINBASE_0"}]},{name:"Complianz banner",prehideSelectors:["#cmplz-cookiebanner-container"],detectCmp:[{exists:"#cmplz-cookiebanner-container .cmplz-cookiebanner"}],detectPopup:[{visible:"#cmplz-cookiebanner-container .cmplz-cookiebanner",check:"any"}],optIn:[{waitForThenClick:".cmplz-cookiebanner .cmplz-accept"}],optOut:[{waitForThenClick:".cmplz-cookiebanner .cmplz-deny"}],test:[{eval:"EVAL_COMPLIANZ_BANNER_0"}]},{name:"Complianz categories",prehideSelectors:['.cc-type-categories[aria-describedby="cookieconsent:desc"]'],detectCmp:[{exists:'.cc-type-categories[aria-describedby="cookieconsent:desc"]'}],detectPopup:[{visible:'.cc-type-categories[aria-describedby="cookieconsent:desc"]'}],optIn:[{any:[{click:".cc-accept-all"},{click:".cc-allow-all"},{click:".cc-allow"},{click:".cc-dismiss"}]}],optOut:[{if:{exists:'.cc-type-categories[aria-describedby="cookieconsent:desc"] .cc-dismiss'},then:[{click:".cc-dismiss"}],else:[{click:".cc-type-categories input[type=checkbox]:not([disabled]):checked",all:!0,optional:!0},{click:".cc-save"}]}]},{name:"Complianz notice",prehideSelectors:['.cc-type-info[aria-describedby="cookieconsent:desc"]'],cosmetic:!0,detectCmp:[{exists:'.cc-type-info[aria-describedby="cookieconsent:desc"] .cc-compliance .cc-btn'}],detectPopup:[{visible:'.cc-type-info[aria-describedby="cookieconsent:desc"] .cc-compliance .cc-btn'}],optIn:[{click:".cc-accept-all",optional:!0},{click:".cc-allow",optional:!0},{click:".cc-dismiss",optional:!0}],optOut:[{if:{exists:".cc-deny"},then:[{click:".cc-deny"}],else:[{hide:'[aria-describedby="cookieconsent:desc"]'}]}]},{name:"Complianz opt-both",prehideSelectors:['[aria-describedby="cookieconsent:desc"] .cc-type-opt-both'],detectCmp:[{exists:'[aria-describedby="cookieconsent:desc"] .cc-type-opt-both'}],detectPopup:[{visible:'[aria-describedby="cookieconsent:desc"] .cc-type-opt-both'}],optIn:[{click:".cc-accept-all",optional:!0},{click:".cc-allow",optional:!0},{click:".cc-dismiss",optional:!0}],optOut:[{waitForThenClick:".cc-deny"}]},{name:"Complianz opt-out",prehideSelectors:['[aria-describedby="cookieconsent:desc"].cc-type-opt-out'],detectCmp:[{exists:'[aria-describedby="cookieconsent:desc"].cc-type-opt-out'}],detectPopup:[{visible:'[aria-describedby="cookieconsent:desc"].cc-type-opt-out'}],optIn:[{click:".cc-accept-all",optional:!0},{click:".cc-allow",optional:!0},{click:".cc-dismiss",optional:!0}],optOut:[{if:{exists:".cc-deny"},then:[{click:".cc-deny"}],else:[{if:{exists:".cmp-pref-link"},then:[{click:".cmp-pref-link"},{waitForThenClick:".cmp-body [id*=rejectAll]"},{waitForThenClick:".cmp-body .cmp-save-btn"}]}]}]},{name:"Complianz optin",prehideSelectors:['.cc-type-opt-in[aria-describedby="cookieconsent:desc"]'],detectCmp:[{exists:'.cc-type-opt-in[aria-describedby="cookieconsent:desc"]'}],detectPopup:[{visible:'.cc-type-opt-in[aria-describedby="cookieconsent:desc"]'}],optIn:[{any:[{click:".cc-accept-all"},{click:".cc-allow"},{click:".cc-dismiss"}]}],optOut:[{if:{visible:".cc-deny"},then:[{click:".cc-deny"}],else:[{if:{visible:".cc-settings"},then:[{waitForThenClick:".cc-settings"},{waitForVisible:".cc-settings-view"},{click:".cc-settings-view input[type=checkbox]:not([disabled]):checked",all:!0,optional:!0},{click:".cc-settings-view .cc-btn-accept-selected"}],else:[{click:".cc-dismiss"}]}]}]},{name:"cookie-consent-spice",cosmetic:!1,runContext:{main:!0,frame:!1},prehideSelectors:[".spicy-consent-wrapper",".spicy-consent-bar"],detectCmp:[{exists:".spicy-consent-bar"}],detectPopup:[{visible:".spicy-consent-bar"}],optIn:[{waitForThenClick:".spicy-consent-bar__action-accept"}],optOut:[{waitForThenClick:".js-decline-all-cookies"}]},{name:"cookie-law-info",prehideSelectors:["#cookie-law-info-bar"],detectCmp:[{exists:"#cookie-law-info-bar"},{eval:"EVAL_COOKIE_LAW_INFO_DETECT"}],detectPopup:[{visible:"#cookie-law-info-bar"}],optIn:[{click:'[data-cli_action="accept_all"]'}],optOut:[{hide:"#cookie-law-info-bar"},{eval:"EVAL_COOKIE_LAW_INFO_0"}],test:[{eval:"EVAL_COOKIE_LAW_INFO_1"}]},{name:"cookie-manager-popup",cosmetic:!1,runContext:{main:!0,frame:!1},intermediate:!1,detectCmp:[{exists:"#notice-cookie-block #allow-functional-cookies, #notice-cookie-block #btn-cookie-settings"}],detectPopup:[{visible:"#notice-cookie-block"}],optIn:[{click:"#btn-cookie-allow"}],optOut:[{if:{exists:"#allow-functional-cookies"},then:[{click:"#allow-functional-cookies"}],else:[{waitForThenClick:"#btn-cookie-settings"},{waitForVisible:".modal-body"},{click:'.modal-body input:checked, .switch[data-switch="on"]',all:!0,optional:!0},{click:'[role="dialog"] .modal-footer button'}]}],prehideSelectors:["#btn-cookie-settings"],test:[{eval:"EVAL_COOKIE_MANAGER_POPUP_0"}]},{name:"cookie-notice",prehideSelectors:["#cookie-notice"],cosmetic:!0,detectCmp:[{visible:"#cookie-notice .cookie-notice-container"}],detectPopup:[{visible:"#cookie-notice"}],optIn:[{click:"#cn-accept-cookie"}],optOut:[{hide:"#cookie-notice"}]},{name:"cookie-script",vendorUrl:"https://cookie-script.com/",prehideSelectors:["#cookiescript_injected"],detectCmp:[{exists:"#cookiescript_injected"}],detectPopup:[{visible:"#cookiescript_injected"}],optOut:[{if:{exists:"#cookiescript_reject"},then:[{wait:100},{click:"#cookiescript_reject"}],else:[{click:"#cookiescript_manage"},{waitForVisible:".cookiescript_fsd_main"},{waitForThenClick:"#cookiescript_reject"}]}],optIn:[{click:"#cookiescript_accept"}]},{name:"cookieacceptbar",vendorUrl:"https://unknown",cosmetic:!0,prehideSelectors:["#cookieAcceptBar.cookieAcceptBar"],detectCmp:[{exists:"#cookieAcceptBar.cookieAcceptBar"}],detectPopup:[{visible:"#cookieAcceptBar.cookieAcceptBar"}],optIn:[{waitForThenClick:"#cookieAcceptBarConfirm"}],optOut:[{hide:"#cookieAcceptBar.cookieAcceptBar"}]},{name:"cookiealert",intermediate:!1,prehideSelectors:[],runContext:{frame:!0,main:!0},detectCmp:[{exists:".cookie-alert-extended"}],detectPopup:[{visible:".cookie-alert-extended-modal"}],optIn:[{click:"button[data-controller='cookie-alert/extended/button/accept']"},{eval:"EVAL_COOKIEALERT_0"}],optOut:[{click:"a[data-controller='cookie-alert/extended/detail-link']"},{click:".cookie-alert-configuration-input:checked",all:!0,optional:!0},{click:"button[data-controller='cookie-alert/extended/button/configuration']"},{eval:"EVAL_COOKIEALERT_0"}],test:[{eval:"EVAL_COOKIEALERT_2"}]},{name:"cookieconsent2",vendorUrl:"https://www.github.com/orestbida/cookieconsent",comment:"supports v2.x.x of the library",prehideSelectors:["#cc--main"],detectCmp:[{exists:"#cc--main"}],detectPopup:[{visible:"#cm"},{exists:"#s-all-bn"}],optIn:[{waitForThenClick:"#s-all-bn"}],optOut:[{waitForThenClick:"#s-rall-bn"}],test:[{eval:"EVAL_COOKIECONSENT2_TEST"}]},{name:"cookieconsent3",vendorUrl:"https://www.github.com/orestbida/cookieconsent",comment:"supports v3.x.x of the library",prehideSelectors:["#cc-main"],detectCmp:[{exists:"#cc-main"}],detectPopup:[{visible:"#cc-main .cm-wrapper"}],optIn:[{waitForThenClick:".cm__btn[data-role=all]"}],optOut:[{waitForThenClick:".cm__btn[data-role=necessary]"}],test:[{eval:"EVAL_COOKIECONSENT3_TEST"}]},{name:"cookiecuttr",vendorUrl:"https://github.com/cdwharton/cookieCuttr",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:""},prehideSelectors:[".cc-cookies"],detectCmp:[{exists:".cc-cookies .cc-cookie-accept"}],detectPopup:[{visible:".cc-cookies .cc-cookie-accept"}],optIn:[{waitForThenClick:".cc-cookies .cc-cookie-accept"}],optOut:[{if:{exists:".cc-cookies .cc-cookie-decline"},then:[{click:".cc-cookies .cc-cookie-decline"}],else:[{hide:".cc-cookies"}]}]},{name:"cookiefirst.com",prehideSelectors:["#cookiefirst-root,.cookiefirst-root,[aria-labelledby=cookie-preference-panel-title]"],detectCmp:[{exists:"#cookiefirst-root,.cookiefirst-root"}],detectPopup:[{visible:"#cookiefirst-root,.cookiefirst-root"}],optIn:[{click:"button[data-cookiefirst-action=accept]"}],optOut:[{if:{exists:"button[data-cookiefirst-action=adjust]"},then:[{click:"button[data-cookiefirst-action=adjust]"},{waitForVisible:"[data-cookiefirst-widget=modal]",timeout:1e3},{eval:"EVAL_COOKIEFIRST_1"},{wait:1e3},{click:"button[data-cookiefirst-action=save]"}],else:[{click:"button[data-cookiefirst-action=reject]"}]}],test:[{eval:"EVAL_COOKIEFIRST_0"}]},{name:"Cookie Information Banner",prehideSelectors:["#cookie-information-template-wrapper"],detectCmp:[{exists:"#cookie-information-template-wrapper"}],detectPopup:[{visible:"#cookie-information-template-wrapper"}],optIn:[{eval:"EVAL_COOKIEINFORMATION_1"}],optOut:[{hide:"#cookie-information-template-wrapper",comment:"some templates don't hide the banner automatically"},{eval:"EVAL_COOKIEINFORMATION_0"}],test:[{eval:"EVAL_COOKIEINFORMATION_2"}]},{name:"cookieyes",prehideSelectors:[".cky-overlay,.cky-consent-container"],detectCmp:[{exists:".cky-consent-container"}],detectPopup:[{visible:".cky-consent-container"}],optIn:[{waitForThenClick:".cky-consent-container [data-cky-tag=accept-button]"}],optOut:[{if:{exists:".cky-consent-container [data-cky-tag=reject-button]"},then:[{waitForThenClick:".cky-consent-container [data-cky-tag=reject-button]"}],else:[{if:{exists:".cky-consent-container [data-cky-tag=settings-button]"},then:[{click:".cky-consent-container [data-cky-tag=settings-button]"},{waitFor:".cky-modal-open input[type=checkbox]"},{click:".cky-modal-open input[type=checkbox]:checked",all:!0,optional:!0},{waitForThenClick:".cky-modal [data-cky-tag=detail-save-button]"}],else:[{hide:".cky-consent-container,.cky-overlay"}]}]}],test:[{eval:"EVAL_COOKIEYES_0"}]},{name:"corona-in-zahlen.de",prehideSelectors:[".cookiealert"],detectCmp:[{exists:".cookiealert"}],detectPopup:[{visible:".cookiealert"}],optOut:[{click:".configurecookies"},{click:".confirmcookies"}],optIn:[{click:".acceptcookies"}]},{name:"crossfit-com",cosmetic:!0,prehideSelectors:['body #modal > div > div[class^="_wrapper_"]'],detectCmp:[{exists:'body #modal > div > div[class^="_wrapper_"]'}],detectPopup:[{visible:'body #modal > div > div[class^="_wrapper_"]'}],optIn:[{click:'button[aria-label="accept cookie policy"]'}],optOut:[{hide:'body #modal > div > div[class^="_wrapper_"]'}]},{name:"csu-landtag-de",runContext:{urlPattern:"^https://(www\\.|)?csu-landtag\\.de"},prehideSelectors:["#cookie-disclaimer"],detectCmp:[{exists:"#cookie-disclaimer"}],detectPopup:[{visible:"#cookie-disclaimer"}],optIn:[{click:"#cookieall"}],optOut:[{click:"#cookiesel"}]},{name:"dailymotion-us",cosmetic:!0,prehideSelectors:['div[class*="CookiePopup__desktopContainer"]:has(div[class*="CookiePopup"])'],detectCmp:[{exists:'div[class*="CookiePopup__desktopContainer"]'}],detectPopup:[{visible:'div[class*="CookiePopup__desktopContainer"]'}],optIn:[{click:'div[class*="CookiePopup__desktopContainer"] > button > span'}],optOut:[{hide:'div[class*="CookiePopup__desktopContainer"]'}]},{name:"dailymotion.com",runContext:{urlPattern:"^https://(www\\.)?dailymotion\\.com/"},prehideSelectors:['div[class*="Overlay__container"]:has(div[class*="TCF2Popup"])'],detectCmp:[{exists:'div[class*="TCF2Popup"]'}],detectPopup:[{visible:'[class*="TCF2Popup"] a[href^="https://www.dailymotion.com/legal/cookiemanagement"]'}],optIn:[{waitForThenClick:'button[class*="TCF2Popup__button"]:not([class*="TCF2Popup__personalize"])'}],optOut:[{waitForThenClick:'button[class*="TCF2ContinueWithoutAcceptingButton"]'}],test:[{eval:"EVAL_DAILYMOTION_0"}]},{name:"dan-com",vendorUrl:"https://unknown",runContext:{main:!0,frame:!1},prehideSelectors:[],detectCmp:[{exists:".cookie-banner.show .cookie-banner__content-all-btn"}],detectPopup:[{visible:".cookie-banner.show .cookie-banner__content-all-btn"}],optIn:[{waitForThenClick:".cookie-banner__content-all-btn"}],optOut:[{waitForThenClick:".cookie-banner__content-essential-btn"}]},{name:"deepl.com",prehideSelectors:[".dl_cookieBanner_container"],detectCmp:[{exists:".dl_cookieBanner_container"}],detectPopup:[{visible:".dl_cookieBanner_container"}],optOut:[{click:".dl_cookieBanner--buttonSelected"}],optIn:[{click:".dl_cookieBanner--buttonAll"}]},{name:"delta.com",runContext:{urlPattern:"^https://www\\.delta\\.com/"},cosmetic:!0,prehideSelectors:["ngc-cookie-banner"],detectCmp:[{exists:"div.cookie-footer-container"}],detectPopup:[{visible:"div.cookie-footer-container"}],optIn:[{click:" button.cookie-close-icon"}],optOut:[{hide:"div.cookie-footer-container"}]},{name:"dmgmedia-us",prehideSelectors:["#mol-ads-cmp-iframe, div.mol-ads-cmp > form > div"],detectCmp:[{exists:"div.mol-ads-cmp > form > div"}],detectPopup:[{waitForVisible:"div.mol-ads-cmp > form > div"}],optIn:[{waitForThenClick:"button.mol-ads-cmp--btn-primary"}],optOut:[{waitForThenClick:"div.mol-ads-ccpa--message > u > a"},{waitForVisible:".mol-ads-cmp--modal-dialog"},{waitForThenClick:"a.mol-ads-cmp-footer-privacy"},{waitForThenClick:"button.mol-ads-cmp--btn-secondary"}]},{name:"dmgmedia",prehideSelectors:['[data-project="mol-fe-cmp"]'],detectCmp:[{exists:'[data-project="mol-fe-cmp"] [class*=footer]'}],detectPopup:[{visible:'[data-project="mol-fe-cmp"] [class*=footer]'}],optIn:[{waitForThenClick:'[data-project="mol-fe-cmp"] button[class*=primary]'}],optOut:[{waitForThenClick:'[data-project="mol-fe-cmp"] button[class*=basic]'},{waitForVisible:'[data-project="mol-fe-cmp"] div[class*="tabContent"]'},{waitForThenClick:'[data-project="mol-fe-cmp"] div[class*="toggle"][class*="enabled"]',all:!0},{waitForThenClick:['[data-project="mol-fe-cmp"] [class*=footer]',"xpath///button[contains(., 'Save & Exit')]"]}]},{name:"dndbeyond",vendorUrl:"https://www.dndbeyond.com/",runContext:{urlPattern:"^https://(www\\.)?dndbeyond\\.com/"},prehideSelectors:["[id^=cookie-consent-banner]"],detectCmp:[{exists:"[id^=cookie-consent-banner]"}],detectPopup:[{visible:"[id^=cookie-consent-banner]"}],optIn:[{waitForThenClick:"#cookie-consent-granted"}],optOut:[{waitForThenClick:"#cookie-consent-denied"}],test:[{eval:"EVAL_DNDBEYOND_TEST"}]},{name:"dpgmedia-nl",prehideSelectors:["#pg-shadow-root-host"],detectCmp:[{exists:"#pg-shadow-root-host"}],detectPopup:[{visible:["#pg-shadow-root-host","#pg-modal"]}],optIn:[{waitForThenClick:["#pg-shadow-root-host","#pg-accept-btn"]}],optOut:[{waitForThenClick:["#pg-shadow-root-host","#pg-configure-btn"]},{waitForThenClick:["#pg-shadow-root-host","#pg-reject-btn"]}]},{name:"Drupal",detectCmp:[{exists:"#drupalorg-crosssite-gdpr"}],detectPopup:[{visible:"#drupalorg-crosssite-gdpr"}],optOut:[{click:".no"}],optIn:[{click:".yes"}]},{name:"WP DSGVO Tools",link:"https://wordpress.org/plugins/shapepress-dsgvo/",prehideSelectors:[".sp-dsgvo"],cosmetic:!0,detectCmp:[{exists:".sp-dsgvo.sp-dsgvo-popup-overlay"}],detectPopup:[{visible:".sp-dsgvo.sp-dsgvo-popup-overlay",check:"any"}],optIn:[{click:".sp-dsgvo-privacy-btn-accept-all",all:!0}],optOut:[{hide:".sp-dsgvo.sp-dsgvo-popup-overlay"}],test:[{eval:"EVAL_DSGVO_0"}]},{name:"dunelm.com",prehideSelectors:["div[data-testid=cookie-consent-modal-backdrop]"],detectCmp:[{exists:"div[data-testid=cookie-consent-message-contents]"}],detectPopup:[{visible:"div[data-testid=cookie-consent-message-contents]"}],optIn:[{click:'[data-testid="cookie-consent-allow-all"]'}],optOut:[{click:"button[data-testid=cookie-consent-adjust-settings]"},{click:"button[data-testid=cookie-consent-preferences-save]"}],test:[{eval:"EVAL_DUNELM_0"}]},{name:"ebay",vendorUrl:"https://ebay.com",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?ebay\\.([.a-z]+)/"},prehideSelectors:["#gdpr-banner"],detectCmp:[{exists:"#gdpr-banner"}],detectPopup:[{visible:"#gdpr-banner"}],optIn:[{waitForThenClick:"#gdpr-banner-accept"}],optOut:[{waitForThenClick:"#gdpr-banner-decline"}]},{name:"ecosia",vendorUrl:"https://www.ecosia.org/",runContext:{urlPattern:"^https://www\\.ecosia\\.org/"},prehideSelectors:[".cookie-wrapper"],detectCmp:[{exists:".cookie-wrapper > .cookie-notice"}],detectPopup:[{visible:".cookie-wrapper > .cookie-notice"}],optIn:[{waitForThenClick:"[data-test-id=cookie-notice-accept]"}],optOut:[{waitForThenClick:"[data-test-id=cookie-notice-reject]"}]},{name:"Ensighten ensModal",prehideSelectors:[".ensModal"],detectCmp:[{exists:".ensModal"},{visible:"#ensModalWrapper[style*=block]"}],detectPopup:[{visible:"#ensModalWrapper[style*=block]"}],optIn:[{waitForThenClick:"#modalAcceptButton"}],optOut:[{wait:500},{visible:"#ensModalWrapper[style*=block]"},{waitForThenClick:".ensCheckbox:checked",all:!0},{waitForThenClick:"#ensSave"}]},{name:"Ensighten ensNotifyBanner",prehideSelectors:["#ensNotifyBanner"],detectCmp:[{exists:"#ensNotifyBanner"}],detectPopup:[{visible:"#ensNotifyBanner[style*=block]"}],optIn:[{waitForThenClick:"#ensCloseBanner"}],optOut:[{wait:500},{visible:"#ensNotifyBanner[style*=block]"},{waitForThenClick:"#ensRejectAll,#rejectAll,#ensRejectBanner,.rejectAll,#ensCloseBanner",timeout:2e3}]},{name:"espace-personnel.agirc-arrco.fr",runContext:{urlPattern:"^https://espace-personnel\\.agirc-arrco\\.fr/"},prehideSelectors:[".cdk-overlay-container"],detectCmp:[{exists:".cdk-overlay-container app-esaa-cookie-component"}],detectPopup:[{visible:".cdk-overlay-container app-esaa-cookie-component"}],optIn:[{waitForThenClick:".btn-cookie-accepter"}],optOut:[{waitForThenClick:".btn-cookie-refuser"}]},{name:"etsy",prehideSelectors:["#gdpr-single-choice-overlay","#gdpr-privacy-settings"],detectCmp:[{exists:"#gdpr-single-choice-overlay"}],detectPopup:[{visible:"#gdpr-single-choice-overlay"}],optOut:[{click:"button[data-gdpr-open-full-settings]"},{waitForVisible:".gdpr-overlay-body input",timeout:3e3},{wait:1e3},{eval:"EVAL_ETSY_0"},{eval:"EVAL_ETSY_1"}],optIn:[{click:"button[data-gdpr-single-choice-accept]"}]},{name:"eu-cookie-compliance-banner",detectCmp:[{exists:"body.eu-cookie-compliance-popup-open"}],detectPopup:[{exists:"body.eu-cookie-compliance-popup-open"}],optIn:[{click:".agree-button"}],optOut:[{if:{visible:".decline-button,.eu-cookie-compliance-save-preferences-button"},then:[{click:".decline-button,.eu-cookie-compliance-save-preferences-button"}]},{hide:".eu-cookie-compliance-banner-info, #sliding-popup"}],test:[{eval:"EVAL_EU_COOKIE_COMPLIANCE_0"}]},{name:"EU Cookie Law",prehideSelectors:[".pea_cook_wrapper,.pea_cook_more_info_popover"],cosmetic:!0,detectCmp:[{exists:".pea_cook_wrapper"}],detectPopup:[{wait:500},{visible:".pea_cook_wrapper"}],optIn:[{click:"#pea_cook_btn"}],optOut:[{hide:".pea_cook_wrapper"}],test:[{eval:"EVAL_EU_COOKIE_LAW_0"}]},{name:"europa-eu",vendorUrl:"https://ec.europa.eu/",runContext:{urlPattern:"^https://[^/]*europa\\.eu/"},prehideSelectors:["#cookie-consent-banner"],detectCmp:[{exists:".cck-container"}],detectPopup:[{visible:".cck-container"}],optIn:[{waitForThenClick:'.cck-actions-button[href="#accept"]'}],optOut:[{waitForThenClick:'.cck-actions-button[href="#refuse"]',hide:".cck-container"}]},{name:"EZoic",prehideSelectors:["#ez-cookie-dialog-wrapper"],detectCmp:[{exists:"#ez-cookie-dialog-wrapper"}],detectPopup:[{visible:"#ez-cookie-dialog-wrapper"}],optIn:[{click:"#ez-accept-all",optional:!0},{eval:"EVAL_EZOIC_0",optional:!0}],optOut:[{wait:500},{click:"#ez-manage-settings"},{waitFor:"#ez-cookie-dialog input[type=checkbox]"},{click:"#ez-cookie-dialog input[type=checkbox]:checked",all:!0},{click:"#ez-save-settings"}],test:[{eval:"EVAL_EZOIC_1"}]},{name:"facebook",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?facebook\\.com/"},prehideSelectors:['div[data-testid="cookie-policy-manage-dialog"]'],detectCmp:[{exists:'div[data-testid="cookie-policy-manage-dialog"]'}],detectPopup:[{visible:'div[data-testid="cookie-policy-manage-dialog"]'}],optIn:[{waitForThenClick:'button[data-cookiebanner="accept_button"]'},{waitForVisible:'div[data-testid="cookie-policy-manage-dialog"]',check:"none"}],optOut:[{waitForThenClick:'button[data-cookiebanner="accept_only_essential_button"]'},{waitForVisible:'div[data-testid="cookie-policy-manage-dialog"]',check:"none"}]},{name:"fides",vendorUrl:"https://github.com/ethyca/fides",prehideSelectors:["#fides-overlay"],detectCmp:[{exists:"#fides-overlay #fides-banner"}],detectPopup:[{visible:"#fides-overlay #fides-banner"},{eval:"EVAL_FIDES_DETECT_POPUP"}],optIn:[{waitForThenClick:"#fides-banner .fides-accept-all-button"}],optOut:[{waitForThenClick:"#fides-banner .fides-reject-all-button"}]},{name:"funding-choices",prehideSelectors:[".fc-consent-root,.fc-dialog-container,.fc-dialog-overlay,.fc-dialog-content"],detectCmp:[{exists:".fc-consent-root"}],detectPopup:[{exists:".fc-dialog-container"}],optOut:[{click:".fc-cta-do-not-consent,.fc-cta-manage-options"},{click:".fc-preference-consent:checked,.fc-preference-legitimate-interest:checked",all:!0,optional:!0},{click:".fc-confirm-choices",optional:!0}],optIn:[{click:".fc-cta-consent"}]},{name:"geeks-for-geeks",runContext:{urlPattern:"^https://www\\.geeksforgeeks\\.org/"},cosmetic:!0,prehideSelectors:[".cookie-consent"],detectCmp:[{exists:".cookie-consent"}],detectPopup:[{visible:".cookie-consent"}],optIn:[{click:".cookie-consent button.consent-btn"}],optOut:[{hide:".cookie-consent"}]},{name:"google-consent-standalone",prehideSelectors:[],detectCmp:[{exists:'a[href^="https://policies.google.com/technologies/cookies"'},{exists:'form[action^="https://consent.google."][action$="/save"]'}],detectPopup:[{visible:'a[href^="https://policies.google.com/technologies/cookies"'}],optIn:[{waitForThenClick:'form[action^="https://consent.google."][action$="/save"]:has(input[name=set_eom][value=false]) button'}],optOut:[{waitForThenClick:'form[action^="https://consent.google."][action$="/save"]:has(input[name=set_eom][value=true]) button'}]},{name:"google-cookiebar",vendorUrl:"https://www.android.com/better-together/quick-share-app/",cosmetic:!1,prehideSelectors:[".glue-cookie-notification-bar"],detectCmp:[{exists:".glue-cookie-notification-bar"}],detectPopup:[{visible:".glue-cookie-notification-bar"}],optIn:[{waitForThenClick:".glue-cookie-notification-bar__accept"}],optOut:[{if:{exists:".glue-cookie-notification-bar__reject"},then:[{click:".glue-cookie-notification-bar__reject"}],else:[{hide:".glue-cookie-notification-bar"}]}],test:[]},{name:"google.com",prehideSelectors:[".HTjtHe#xe7COe"],detectCmp:[{exists:".HTjtHe#xe7COe"},{exists:'.HTjtHe#xe7COe a[href^="https://policies.google.com/technologies/cookies"]'}],detectPopup:[{visible:".HTjtHe#xe7COe button#W0wltc"}],optIn:[{waitForThenClick:".HTjtHe#xe7COe button#L2AGLb"}],optOut:[{waitForThenClick:".HTjtHe#xe7COe button#W0wltc"}],test:[{eval:"EVAL_GOOGLE_0"}]},{name:"gov.uk",detectCmp:[{exists:"#global-cookie-message"}],detectPopup:[{exists:"#global-cookie-message"}],optIn:[{click:"button[data-accept-cookies=true]"}],optOut:[{click:"button[data-reject-cookies=true],#reject-cookies"},{click:"button[data-hide-cookie-banner=true],#hide-cookie-decision"}]},{name:"hashicorp",vendorUrl:"https://hashicorp.com/",runContext:{urlPattern:"^https://[^.]*\\.hashicorp\\.com/"},prehideSelectors:["[data-testid=consent-banner]"],detectCmp:[{exists:"[data-testid=consent-banner]"}],detectPopup:[{visible:"[data-testid=consent-banner]"}],optIn:[{waitForThenClick:"[data-testid=accept]"}],optOut:[{waitForThenClick:"[data-testid=manage-preferences]"},{waitForThenClick:"[data-testid=consent-mgr-dialog] [data-ga-button=save-preferences]"}]},{name:"healthline-media",prehideSelectors:["#modal-host > div.no-hash > div.window-wrapper"],detectCmp:[{exists:"#modal-host > div.no-hash > div.window-wrapper, div[data-testid=qualtrics-container]"}],detectPopup:[{exists:"#modal-host > div.no-hash > div.window-wrapper, div[data-testid=qualtrics-container]"}],optIn:[{click:"#modal-host > div.no-hash > div.window-wrapper > div:last-child button"}],optOut:[{if:{exists:'#modal-host > div.no-hash > div.window-wrapper > div:last-child a[href="/privacy-settings"]'},then:[{click:'#modal-host > div.no-hash > div.window-wrapper > div:last-child a[href="/privacy-settings"]'}],else:[{waitForVisible:"div#__next"},{click:"#__next div:nth-child(1) > button:first-child"}]}]},{name:"hema",prehideSelectors:[".cookie-modal"],detectCmp:[{visible:".cookie-modal .cookie-accept-btn"}],detectPopup:[{visible:".cookie-modal .cookie-accept-btn"}],optIn:[{waitForThenClick:".cookie-modal .cookie-accept-btn"}],optOut:[{waitForThenClick:".cookie-modal .js-cookie-reject-btn"}],test:[{eval:"EVAL_HEMA_TEST_0"}]},{name:"hetzner.com",runContext:{urlPattern:"^https://www\\.hetzner\\.com/"},prehideSelectors:["#CookieConsent"],detectCmp:[{exists:"#CookieConsent"}],detectPopup:[{visible:"#CookieConsent"}],optIn:[{click:"#CookieConsentGiven"}],optOut:[{click:"#CookieConsentDeclined"}]},{name:"hl.co.uk",prehideSelectors:[".cookieModalContent","#cookie-banner-overlay"],detectCmp:[{exists:"#cookie-banner-overlay"}],detectPopup:[{exists:"#cookie-banner-overlay"}],optIn:[{click:"#acceptCookieButton"}],optOut:[{click:"#manageCookie"},{hide:".cookieSettingsModal"},{waitFor:"#AOCookieToggle"},{click:"#AOCookieToggle[aria-pressed=true]",optional:!0},{waitFor:"#TPCookieToggle"},{click:"#TPCookieToggle[aria-pressed=true]",optional:!0},{click:"#updateCookieButton"}]},{name:"holidaymedia",vendorUrl:"https://holidaymedia.nl/",prehideSelectors:["dialog[data-cookie-consent]"],detectCmp:[{exists:"dialog[data-cookie-consent]"}],detectPopup:[{visible:"dialog[data-cookie-consent]"}],optIn:[{waitForThenClick:"button.cookie-consent__button--accept-all"}],optOut:[{waitForThenClick:'a[data-cookie-accept="functional"]',timeout:2e3}]},{name:"hu-manity",vendorUrl:"https://hu-manity.co/",prehideSelectors:["#hu.hu-wrapper"],detectCmp:[{exists:"#hu.hu-visible"}],detectPopup:[{visible:"#hu.hu-visible"}],optIn:[{waitForThenClick:"[data-hu-action=cookies-notice-consent-choices-3]"},{waitForThenClick:"#hu-cookies-save"}],optOut:[{waitForThenClick:"#hu-cookies-save"}]},{name:"hubspot",detectCmp:[{exists:"#hs-eu-cookie-confirmation"}],detectPopup:[{visible:"#hs-eu-cookie-confirmation"}],optIn:[{click:"#hs-eu-confirmation-button"}],optOut:[{click:"#hs-eu-decline-button"}]},{name:"indeed.com",cosmetic:!0,prehideSelectors:["#CookiePrivacyNotice"],detectCmp:[{exists:"#CookiePrivacyNotice"}],detectPopup:[{visible:"#CookiePrivacyNotice"}],optIn:[{click:"#CookiePrivacyNotice button[data-gnav-element-name=CookiePrivacyNoticeOk]"}],optOut:[{hide:"#CookiePrivacyNotice"}]},{name:"ing.de",runContext:{urlPattern:"^https://www\\.ing\\.de/"},cosmetic:!0,prehideSelectors:['div[slot="backdrop"]'],detectCmp:[{exists:'[data-tag-name="ing-cc-dialog-frame"]'}],detectPopup:[{visible:'[data-tag-name="ing-cc-dialog-frame"]'}],optIn:[{click:['[data-tag-name="ing-cc-dialog-level0"]','[data-tag-name="ing-cc-button"][class*="accept"]']}],optOut:[{click:['[data-tag-name="ing-cc-dialog-level0"]','[data-tag-name="ing-cc-button"][class*="more"]']}]},{name:"instagram",vendorUrl:"https://instagram.com",runContext:{urlPattern:"^https://www\\.instagram\\.com/"},prehideSelectors:[],detectCmp:[{exists:'xpath///span[contains(., "Vill du tillåta användningen av cookies från Instagram i den här webbläsaren?") or contains(., "Allow the use of cookies from Instagram on this browser?") or contains(., "Povolit v prohlížeči použití souborů cookie z Instagramu?") or contains(., "Dopustiti upotrebu kolačića s Instagrama na ovom pregledniku?") or contains(., "Разрешить использование файлов cookie от Instagram в этом браузере?") or contains(., "Vuoi consentire l\'uso dei cookie di Instagram su questo browser?") or contains(., "Povoliť používanie cookies zo služby Instagram v tomto prehliadači?") or contains(., "Die Verwendung von Cookies durch Instagram in diesem Browser erlauben?") or contains(., "Sallitaanko Instagramin evästeiden käyttö tällä selaimella?") or contains(., "Engedélyezed az Instagram cookie-jainak használatát ebben a böngészőben?") or contains(., "Het gebruik van cookies van Instagram toestaan in deze browser?") or contains(., "Bu tarayıcıda Instagram\'dan çerez kullanımına izin verilsin mi?") or contains(., "Permitir o uso de cookies do Instagram neste navegador?") or contains(., "Permiţi folosirea modulelor cookie de la Instagram în acest browser?") or contains(., "Autoriser l’utilisation des cookies d’Instagram sur ce navigateur ?") or contains(., "¿Permitir el uso de cookies de Instagram en este navegador?") or contains(., "Zezwolić na użycie plików cookie z Instagramu w tej przeglądarce?") or contains(., "Να επιτρέπεται η χρήση cookies από τo Instagram σε αυτό το πρόγραμμα περιήγησης;") or contains(., "Разрешавате ли използването на бисквитки от Instagram на този браузър?") or contains(., "Vil du tillade brugen af cookies fra Instagram i denne browser?") or contains(., "Vil du tillate bruk av informasjonskapsler fra Instagram i denne nettleseren?")]'}],detectPopup:[{visible:'xpath///span[contains(., "Vill du tillåta användningen av cookies från Instagram i den här webbläsaren?") or contains(., "Allow the use of cookies from Instagram on this browser?") or contains(., "Povolit v prohlížeči použití souborů cookie z Instagramu?") or contains(., "Dopustiti upotrebu kolačića s Instagrama na ovom pregledniku?") or contains(., "Разрешить использование файлов cookie от Instagram в этом браузере?") or contains(., "Vuoi consentire l\'uso dei cookie di Instagram su questo browser?") or contains(., "Povoliť používanie cookies zo služby Instagram v tomto prehliadači?") or contains(., "Die Verwendung von Cookies durch Instagram in diesem Browser erlauben?") or contains(., "Sallitaanko Instagramin evästeiden käyttö tällä selaimella?") or contains(., "Engedélyezed az Instagram cookie-jainak használatát ebben a böngészőben?") or contains(., "Het gebruik van cookies van Instagram toestaan in deze browser?") or contains(., "Bu tarayıcıda Instagram\'dan çerez kullanımına izin verilsin mi?") or contains(., "Permitir o uso de cookies do Instagram neste navegador?") or contains(., "Permiţi folosirea modulelor cookie de la Instagram în acest browser?") or contains(., "Autoriser l’utilisation des cookies d’Instagram sur ce navigateur ?") or contains(., "¿Permitir el uso de cookies de Instagram en este navegador?") or contains(., "Zezwolić na użycie plików cookie z Instagramu w tej przeglądarce?") or contains(., "Να επιτρέπεται η χρήση cookies από τo Instagram σε αυτό το πρόγραμμα περιήγησης;") or contains(., "Разрешавате ли използването на бисквитки от Instagram на този браузър?") or contains(., "Vil du tillade brugen af cookies fra Instagram i denne browser?") or contains(., "Vil du tillate bruk av informasjonskapsler fra Instagram i denne nettleseren?")]'}],optIn:[{waitForThenClick:"xpath///button[contains(., 'Tillad alle cookies') or contains(., 'Alle Cookies erlauben') or contains(., 'Allow all cookies') or contains(., 'Разрешаване на всички бисквитки') or contains(., 'Tillåt alla cookies') or contains(., 'Povolit všechny soubory cookie') or contains(., 'Tüm çerezlere izin ver') or contains(., 'Permite toate modulele cookie') or contains(., 'Να επιτρέπονται όλα τα cookies') or contains(., 'Tillat alle informasjonskapsler') or contains(., 'Povoliť všetky cookies') or contains(., 'Permitir todas las cookies') or contains(., 'Permitir todos os cookies') or contains(., 'Alle cookies toestaan') or contains(., 'Salli kaikki evästeet') or contains(., 'Consenti tutti i cookie') or contains(., 'Az összes cookie engedélyezése') or contains(., 'Autoriser tous les cookies') or contains(., 'Zezwól na wszystkie pliki cookie') or contains(., 'Разрешить все cookie') or contains(., 'Dopusti sve kolačiće')]"}],optOut:[{waitForThenClick:"xpath///button[contains(., 'Отклонить необязательные файлы cookie') or contains(., 'Decline optional cookies') or contains(., 'Refuser les cookies optionnels') or contains(., 'Hylkää valinnaiset evästeet') or contains(., 'Afvis valgfrie cookies') or contains(., 'Odmietnuť nepovinné cookies') or contains(., 'Απόρριψη προαιρετικών cookies') or contains(., 'Neka valfria cookies') or contains(., 'Optionale Cookies ablehnen') or contains(., 'Rifiuta cookie facoltativi') or contains(., 'Odbij neobavezne kolačiće') or contains(., 'Avvis valgfrie informasjonskapsler') or contains(., 'İsteğe bağlı çerezleri reddet') or contains(., 'Recusar cookies opcionais') or contains(., 'Optionele cookies afwijzen') or contains(., 'Rechazar cookies opcionales') or contains(., 'Odrzuć opcjonalne pliki cookie') or contains(., 'Отхвърляне на бисквитките по избор') or contains(., 'Odmítnout volitelné soubory cookie') or contains(., 'Refuză modulele cookie opţionale') or contains(., 'A nem kötelező cookie-k elutasítása')]"},{wait:2e3}]},{name:"ionos.de",prehideSelectors:[".privacy-consent--backdrop",".privacy-consent--modal"],detectCmp:[{exists:".privacy-consent--modal"}],detectPopup:[{visible:".privacy-consent--modal"}],optIn:[{click:"#selectAll"}],optOut:[{click:".footer-config-link"},{click:"#confirmSelection"}]},{name:"itopvpn.com",cosmetic:!0,prehideSelectors:[".pop-cookie"],detectCmp:[{exists:".pop-cookie"}],detectPopup:[{exists:".pop-cookie"}],optIn:[{click:"#_pcookie"}],optOut:[{hide:".pop-cookie"}]},{name:"iubenda",prehideSelectors:["#iubenda-cs-banner"],detectCmp:[{exists:"#iubenda-cs-banner"}],detectPopup:[{visible:".iubenda-cs-accept-btn"}],optIn:[{waitForThenClick:".iubenda-cs-accept-btn"}],optOut:[{waitForThenClick:".iubenda-cs-customize-btn"},{eval:"EVAL_IUBENDA_0"},{waitForThenClick:"#iubFooterBtn"}],test:[{eval:"EVAL_IUBENDA_1"}]},{name:"iWink",prehideSelectors:["body.cookies-request #cookie-bar"],detectCmp:[{exists:"body.cookies-request #cookie-bar"}],detectPopup:[{visible:"body.cookies-request #cookie-bar"}],optIn:[{waitForThenClick:"body.cookies-request #cookie-bar .allow-cookies"}],optOut:[{waitForThenClick:"body.cookies-request #cookie-bar .disallow-cookies"}],test:[{eval:"EVAL_IWINK_TEST"}]},{name:"jdsports",vendorUrl:"https://www.jdsports.co.uk/",runContext:{urlPattern:"^https://(www|m)\\.jdsports\\."},prehideSelectors:[".miniConsent,#PrivacyPolicyBanner"],detectCmp:[{exists:".miniConsent,#PrivacyPolicyBanner"}],detectPopup:[{visible:".miniConsent,#PrivacyPolicyBanner"}],optIn:[{waitForThenClick:".miniConsent .accept-all-cookies"}],optOut:[{if:{exists:"#PrivacyPolicyBanner"},then:[{hide:"#PrivacyPolicyBanner"}],else:[{waitForThenClick:"#cookie-settings"},{waitForThenClick:"#reject-all-cookies"}]}]},{name:"johnlewis.com",prehideSelectors:["div[class^=pecr-cookie-banner-]"],detectCmp:[{exists:"div[class^=pecr-cookie-banner-]"}],detectPopup:[{exists:"div[class^=pecr-cookie-banner-]"}],optOut:[{click:"button[data-test^=manage-cookies]"},{wait:"500"},{click:"label[data-test^=toggle][class*=checked]:not([class*=disabled])",all:!0,optional:!0},{click:"button[data-test=save-preferences]"}],optIn:[{click:"button[data-test=allow-all]"}]},{name:"jquery.cookieBar",vendorUrl:"https://github.com/kovarp/jquery.cookieBar",prehideSelectors:[".cookie-bar"],cosmetic:!0,detectCmp:[{exists:".cookie-bar .cookie-bar__message,.cookie-bar .cookie-bar__buttons"}],detectPopup:[{visible:".cookie-bar .cookie-bar__message,.cookie-bar .cookie-bar__buttons",check:"any"}],optIn:[{click:".cookie-bar .cookie-bar__btn"}],optOut:[{hide:".cookie-bar"}],test:[{visible:".cookie-bar .cookie-bar__message,.cookie-bar .cookie-bar__buttons",check:"none"},{eval:"EVAL_JQUERY_COOKIEBAR_0"}]},{name:"justwatch.com",prehideSelectors:[".consent-banner"],detectCmp:[{exists:".consent-banner .consent-banner__actions"}],detectPopup:[{visible:".consent-banner .consent-banner__actions"}],optIn:[{click:".consent-banner__actions button.basic-button.primary"}],optOut:[{click:".consent-banner__actions button.basic-button.secondary"},{waitForThenClick:".consent-modal__footer button.basic-button.secondary"},{waitForThenClick:".consent-modal ion-content > div > a:nth-child(9)"},{click:"label.consent-switch input[type=checkbox]:checked",all:!0,optional:!0},{waitForVisible:".consent-modal__footer button.basic-button.primary"},{click:".consent-modal__footer button.basic-button.primary"}]},{name:"kconsent",cosmetic:!1,runContext:{main:!0,frame:!1},prehideSelectors:[".kc-overlay"],detectCmp:[{exists:"#kconsent"}],detectPopup:[{visible:".kc-dialog"}],optIn:[{waitForThenClick:"#kc-acceptAndHide"}],optOut:[{waitForThenClick:"#kc-denyAndHide"}]},{name:"ketch",vendorUrl:"https://www.ketch.com",runContext:{frame:!1,main:!0},intermediate:!1,prehideSelectors:["#lanyard_root div[role='dialog']"],detectCmp:[{exists:"#lanyard_root div[role='dialog']"}],detectPopup:[{visible:"#lanyard_root div[role='dialog']"}],optIn:[{if:{exists:"#lanyard_root button[class='confirmButton']"},then:[{waitForThenClick:"#lanyard_root div[class*=buttons] > :nth-child(2)"},{click:"#lanyard_root button[class='confirmButton']"}],else:[{waitForThenClick:"#lanyard_root div[class*=buttons] > :nth-child(2)"}]}],optOut:[{if:{exists:"#lanyard_root [aria-describedby=banner-description]"},then:[{waitForThenClick:"#lanyard_root div[class*=buttons] > button[class*=secondaryButton], #lanyard_root button[class*=buttons-secondary]",comment:"can be either settings or reject button"}]},{waitFor:"#lanyard_root [aria-describedby=preference-description],#lanyard_root [aria-describedby=modal-description], #ketch-preferences",timeout:1e3,optional:!0},{if:{exists:"#lanyard_root [aria-describedby=preference-description],#lanyard_root [aria-describedby=modal-description], #ketch-preferences"},then:[{waitForThenClick:"#lanyard_root button[class*=rejectButton], #lanyard_root button[class*=rejectAllButton]"},{click:"#lanyard_root button[class*=confirmButton],#lanyard_root div[class*=actions_] > button:nth-child(1), #lanyard_root button[class*=actionButton]"}]}],test:[{eval:"EVAL_KETCH_TEST"}]},{name:"kleinanzeigen-de",runContext:{urlPattern:"^https?://(www\\.)?kleinanzeigen\\.de"},prehideSelectors:["#gdpr-banner-container"],detectCmp:[{any:[{exists:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-cmp-button]"},{exists:"#ConsentManagementPage"}]}],detectPopup:[{any:[{visible:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-cmp-button]"},{visible:"#ConsentManagementPage"}]}],optIn:[{if:{exists:"#gdpr-banner-container #gdpr-banner"},then:[{click:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-accept]"}],else:[{click:"#ConsentManagementPage .Button-primary"}]}],optOut:[{if:{exists:"#gdpr-banner-container #gdpr-banner"},then:[{click:"#gdpr-banner-container #gdpr-banner [data-testid=gdpr-banner-cmp-button]"}],else:[{click:"#ConsentManagementPage .Button-secondary"}]}]},{name:"lightbox",prehideSelectors:[".darken-layer.open,.lightbox.lightbox--cookie-consent"],detectCmp:[{exists:"body.cookie-consent-is-active div.lightbox--cookie-consent > div.lightbox__content > div.cookie-consent[data-jsb]"}],detectPopup:[{visible:"body.cookie-consent-is-active div.lightbox--cookie-consent > div.lightbox__content > div.cookie-consent[data-jsb]"}],optOut:[{click:".cookie-consent__footer > button[type='submit']:not([data-button='selectAll'])"}],optIn:[{click:".cookie-consent__footer > button[type='submit'][data-button='selectAll']"}]},{name:"lineagrafica",vendorUrl:"https://addons.prestashop.com/en/legal/8734-eu-cookie-law-gdpr-banner-blocker.html",cosmetic:!0,prehideSelectors:["#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"],detectCmp:[{exists:"#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"}],detectPopup:[{exists:"#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"}],optIn:[{waitForThenClick:"#lgcookieslaw_accept"}],optOut:[{hide:"#lgcookieslaw_banner,#lgcookieslaw_modal,.lgcookieslaw-overlay"}]},{name:"linkedin.com",prehideSelectors:[".artdeco-global-alert[type=COOKIE_CONSENT]"],detectCmp:[{exists:".artdeco-global-alert[type=COOKIE_CONSENT]"}],detectPopup:[{visible:".artdeco-global-alert[type=COOKIE_CONSENT]"}],optIn:[{waitForVisible:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=ACCEPT]"},{wait:500},{waitForThenClick:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=ACCEPT]"}],optOut:[{waitForVisible:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=DENY]"},{wait:500},{waitForThenClick:".artdeco-global-alert[type=COOKIE_CONSENT] button[action-type=DENY]"}],test:[{waitForVisible:".artdeco-global-alert[type=COOKIE_CONSENT]",check:"none"}]},{name:"livejasmin",vendorUrl:"https://www.livejasmin.com/",runContext:{urlPattern:"^https://(m|www)\\.livejasmin\\.com/"},prehideSelectors:["#consent_modal"],detectCmp:[{exists:"#consent_modal"}],detectPopup:[{visible:"#consent_modal"}],optIn:[{waitForThenClick:"#consent_modal button[data-testid=ButtonStyledButton]:first-of-type"}],optOut:[{waitForThenClick:"#consent_modal button[data-testid=ButtonStyledButton]:nth-of-type(2)"},{waitForVisible:"[data-testid=PrivacyPreferenceCenterWithConsentCookieContent]"},{click:"[data-testid=PrivacyPreferenceCenterWithConsentCookieContent] input[data-testid=PrivacyPreferenceCenterWithConsentCookieSwitch]:checked",optional:!0,all:!0},{waitForThenClick:"[data-testid=PrivacyPreferenceCenterWithConsentCookieContent] button[data-testid=ButtonStyledButton]:last-child"}]},{name:"macpaw.com",cosmetic:!0,prehideSelectors:['div[data-banner="cookies"]'],detectCmp:[{exists:'div[data-banner="cookies"]'}],detectPopup:[{exists:'div[data-banner="cookies"]'}],optIn:[{click:'button[data-banner-close="cookies"]'}],optOut:[{hide:'div[data-banner="cookies"]'}]},{name:"marksandspencer.com",cosmetic:!0,detectCmp:[{exists:".navigation-cookiebbanner"}],detectPopup:[{visible:".navigation-cookiebbanner"}],optOut:[{hide:".navigation-cookiebbanner"}],optIn:[{click:".navigation-cookiebbanner__submit"}]},{name:"mediamarkt.de",prehideSelectors:["div[aria-labelledby=pwa-consent-layer-title]","div[class^=StyledConsentLayerWrapper-]"],detectCmp:[{exists:"div[aria-labelledby^=pwa-consent-layer-title]"}],detectPopup:[{exists:"div[aria-labelledby^=pwa-consent-layer-title]"}],optOut:[{click:"button[data-test^=pwa-consent-layer-deny-all]"}],optIn:[{click:"button[data-test^=pwa-consent-layer-accept-all"}]},{name:"Mediavine",prehideSelectors:['[data-name="mediavine-gdpr-cmp"]'],detectCmp:[{exists:'[data-name="mediavine-gdpr-cmp"]'}],detectPopup:[{wait:500},{visible:'[data-name="mediavine-gdpr-cmp"]'}],optIn:[{waitForThenClick:'[data-name="mediavine-gdpr-cmp"] [format="primary"]'}],optOut:[{waitForThenClick:'[data-name="mediavine-gdpr-cmp"] [data-view="manageSettings"]'},{waitFor:'[data-name="mediavine-gdpr-cmp"] input[type=checkbox]'},{eval:"EVAL_MEDIAVINE_0",optional:!0},{click:'[data-name="mediavine-gdpr-cmp"] [format="secondary"]'}]},{name:"medium",vendorUrl:"https://medium.com",cosmetic:!0,runContext:{main:!0,frame:!1,urlPattern:"^https://([a-z0-9-]+\\.)?medium\\.com/"},prehideSelectors:[],detectCmp:[{exists:'div:has(> div > div > div[role=alert] > a[href^="https://policy.medium.com/medium-privacy-policy-"])'}],detectPopup:[{visible:'div:has(> div > div > div[role=alert] > a[href^="https://policy.medium.com/medium-privacy-policy-"])'}],optIn:[{waitForThenClick:"[data-testid=close-button]"}],optOut:[{hide:'div:has(> div > div > div[role=alert] > a[href^="https://policy.medium.com/medium-privacy-policy-"])'}]},{name:"microsoft.com",prehideSelectors:["#wcpConsentBannerCtrl"],detectCmp:[{exists:"#wcpConsentBannerCtrl"}],detectPopup:[{exists:"#wcpConsentBannerCtrl"}],optOut:[{eval:"EVAL_MICROSOFT_0"}],optIn:[{eval:"EVAL_MICROSOFT_1"}],test:[{eval:"EVAL_MICROSOFT_2"}]},{name:"midway-usa",runContext:{urlPattern:"^https://www\\.midwayusa\\.com/"},cosmetic:!0,prehideSelectors:["#cookie-container"],detectCmp:[{exists:['div[aria-label="Cookie Policy Banner"]']}],detectPopup:[{visible:"#cookie-container"}],optIn:[{click:"button#cookie-btn"}],optOut:[{hide:'div[aria-label="Cookie Policy Banner"]'}]},{name:"moneysavingexpert.com",detectCmp:[{exists:"dialog[data-testid=accept-our-cookies-dialog]"}],detectPopup:[{visible:"dialog[data-testid=accept-our-cookies-dialog]"}],optIn:[{click:"#banner-accept"}],optOut:[{click:"#banner-manage"},{click:"#pc-confirm"}]},{name:"monzo.com",prehideSelectors:[".cookie-alert, cookie-alert__content"],detectCmp:[{exists:'div.cookie-alert[role="dialog"]'},{exists:'a[href*="monzo"]'}],detectPopup:[{visible:".cookie-alert__content"}],optIn:[{click:".js-accept-cookie-policy"}],optOut:[{click:".js-decline-cookie-policy"}]},{name:"Moove",prehideSelectors:["#moove_gdpr_cookie_info_bar"],detectCmp:[{exists:"#moove_gdpr_cookie_info_bar"}],detectPopup:[{visible:"#moove_gdpr_cookie_info_bar:not(.moove-gdpr-info-bar-hidden)"}],optIn:[{waitForThenClick:".moove-gdpr-infobar-allow-all"}],optOut:[{if:{exists:"#moove_gdpr_cookie_info_bar .change-settings-button"},then:[{click:"#moove_gdpr_cookie_info_bar .change-settings-button"},{waitForVisible:"#moove_gdpr_cookie_modal"},{eval:"EVAL_MOOVE_0"},{click:".moove-gdpr-modal-save-settings"}],else:[{hide:"#moove_gdpr_cookie_info_bar"}]}],test:[{visible:"#moove_gdpr_cookie_info_bar",check:"none"}]},{name:"national-lottery.co.uk",detectCmp:[{exists:".cuk_cookie_consent"}],detectPopup:[{visible:".cuk_cookie_consent",check:"any"}],optOut:[{click:".cuk_cookie_consent_manage_pref"},{click:".cuk_cookie_consent_save_pref"},{click:".cuk_cookie_consent_close"}],optIn:[{click:".cuk_cookie_consent_accept_all"}]},{name:"nba.com",runContext:{urlPattern:"^https://(www\\.)?nba.com/"},cosmetic:!0,prehideSelectors:["#onetrust-banner-sdk"],detectCmp:[{exists:"#onetrust-banner-sdk"}],detectPopup:[{visible:"#onetrust-banner-sdk"}],optIn:[{click:"#onetrust-accept-btn-handler"}],optOut:[{hide:"#onetrust-banner-sdk"}]},{name:"netbeat.de",runContext:{urlPattern:"^https://(www\\.)?netbeat\\.de/"},prehideSelectors:["div#cookieWarning"],detectCmp:[{exists:"div#cookieWarning"}],detectPopup:[{visible:"div#cookieWarning"}],optIn:[{waitForThenClick:"a#btnCookiesAcceptAll"}],optOut:[{waitForThenClick:"a#btnCookiesDenyAll"}]},{name:"netflix.de",detectCmp:[{exists:"#cookie-disclosure"}],detectPopup:[{visible:".cookie-disclosure-message",check:"any"}],optIn:[{click:".btn-accept"}],optOut:[{hide:"#cookie-disclosure"},{click:".btn-reject"}]},{name:"nhs.uk",prehideSelectors:["#nhsuk-cookie-banner"],detectCmp:[{exists:"#nhsuk-cookie-banner"}],detectPopup:[{exists:"#nhsuk-cookie-banner"}],optOut:[{click:"#nhsuk-cookie-banner__link_accept"}],optIn:[{click:"#nhsuk-cookie-banner__link_accept_analytics"}]},{name:"nike",vendorUrl:"https://nike.com",runContext:{urlPattern:"^https://(www\\.)?nike\\.com/"},prehideSelectors:[],detectCmp:[{exists:"[data-testid=cookie-dialog-root]"}],detectPopup:[{visible:"[data-testid=cookie-dialog-root]"}],optIn:[{waitForThenClick:"[data-testid=dialog-accept-button]"}],optOut:[{waitForThenClick:"input[type=radio][id$=-declineLabel]",all:!0},{waitForThenClick:"[data-testid=confirm-choice-button]"}]},{name:"notice-cookie",prehideSelectors:[".button--notice"],cosmetic:!0,detectCmp:[{exists:".notice--cookie"}],detectPopup:[{visible:".notice--cookie"}],optIn:[{click:".button--notice"}],optOut:[{hide:".notice--cookie"}]},{name:"nrk.no",cosmetic:!0,prehideSelectors:[".nrk-masthead__info-banner--cookie"],detectCmp:[{exists:".nrk-masthead__info-banner--cookie"}],detectPopup:[{exists:".nrk-masthead__info-banner--cookie"}],optIn:[{click:"div.nrk-masthead__info-banner--cookie button > span:has(+ svg.nrk-close)"}],optOut:[{hide:".nrk-masthead__info-banner--cookie"}]},{name:"obi.de",prehideSelectors:[".disc-cp--active"],detectCmp:[{exists:".disc-cp-modal__modal"}],detectPopup:[{visible:".disc-cp-modal__modal"}],optIn:[{click:".js-disc-cp-accept-all"}],optOut:[{click:".js-disc-cp-deny-all"}]},{name:"om",vendorUrl:"https://olli-machts.de/en/extension/cookie-manager",prehideSelectors:[".tx-om-cookie-consent"],detectCmp:[{exists:".tx-om-cookie-consent .active[data-omcookie-panel]"}],detectPopup:[{exists:".tx-om-cookie-consent .active[data-omcookie-panel]"}],optIn:[{waitForThenClick:"[data-omcookie-panel-save=all]"}],optOut:[{if:{exists:"[data-omcookie-panel-save=min]"},then:[{waitForThenClick:"[data-omcookie-panel-save=min]"}],else:[{click:"input[data-omcookie-panel-grp]:checked:not(:disabled)",all:!0,optional:!0},{waitForThenClick:"[data-omcookie-panel-save=save]"}]}]},{name:"onlyFans.com",runContext:{urlPattern:"^https://onlyfans\\.com/"},prehideSelectors:["div.b-cookies-informer"],detectCmp:[{exists:"div.b-cookies-informer"}],detectPopup:[{exists:"div.b-cookies-informer"}],optIn:[{click:"div.b-cookies-informer__nav > button:nth-child(2)"}],optOut:[{click:"div.b-cookies-informer__nav > button:nth-child(1)"},{if:{exists:"div.b-cookies-informer__switchers"},then:[{click:"div.b-cookies-informer__switchers input:not([disabled])",all:!0},{click:"div.b-cookies-informer__nav > button"}]}]},{name:"openai",vendorUrl:"https://platform.openai.com/",cosmetic:!1,runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?openai\\.com/"},prehideSelectors:["[data-testid=cookie-consent-banner]"],detectCmp:[{exists:"[data-testid=cookie-consent-banner]"}],detectPopup:[{visible:"[data-testid=cookie-consent-banner]"}],optIn:[{waitForThenClick:"xpath///button[contains(., 'Accept all')]"}],optOut:[{waitForThenClick:"xpath///button[contains(., 'Reject all')]"}],test:[{wait:500},{eval:"EVAL_OPENAI_TEST"}]},{name:"openli",vendorUrl:"https://openli.com",prehideSelectors:[".legalmonster-cleanslate"],detectCmp:[{exists:".legalmonster-cleanslate"}],detectPopup:[{visible:".legalmonster-cleanslate #lm-cookie-wall-container",check:"any"}],optIn:[{waitForThenClick:"#lm-accept-all"}],optOut:[{waitForThenClick:"#lm-accept-necessary"}]},{name:"opera.com",vendorUrl:"https://unknown",cosmetic:!1,runContext:{main:!0,frame:!1},intermediate:!1,prehideSelectors:[],detectCmp:[{exists:"#cookie-consent .manage-cookies__btn"}],detectPopup:[{visible:"#cookie-consent .cookie-basic-consent__btn"}],optIn:[{waitForThenClick:"#cookie-consent .cookie-basic-consent__btn"}],optOut:[{waitForThenClick:"#cookie-consent .manage-cookies__btn"},{waitForThenClick:"#cookie-consent .active.marketing_option_switch.cookie-consent__switch",all:!0},{waitForThenClick:"#cookie-consent .cookie-selection__btn"}],test:[{eval:"EVAL_OPERA_0"}]},{name:"osano",prehideSelectors:[".osano-cm-window,.osano-cm-dialog"],detectCmp:[{exists:".osano-cm-window"}],detectPopup:[{visible:".osano-cm-dialog"}],optIn:[{click:".osano-cm-accept-all",optional:!0}],optOut:[{waitForThenClick:".osano-cm-denyAll"}]},{name:"otto.de",prehideSelectors:[".cookieBanner--visibility"],detectCmp:[{exists:".cookieBanner--visibility"}],detectPopup:[{visible:".cookieBanner__wrapper"}],optIn:[{click:".js_cookieBannerPermissionButton"}],optOut:[{click:".js_cookieBannerProhibitionButton"}]},{name:"ourworldindata",vendorUrl:"https://ourworldindata.org/",runContext:{urlPattern:"^https://ourworldindata\\.org/"},prehideSelectors:[".cookie-manager"],detectCmp:[{exists:".cookie-manager"}],detectPopup:[{visible:".cookie-manager .cookie-notice.open"}],optIn:[{waitForThenClick:".cookie-notice [data-test=accept]"}],optOut:[{waitForThenClick:".cookie-notice [data-test=reject]"}]},{name:"pabcogypsum",vendorUrl:"https://unknown",prehideSelectors:[".js-cookie-notice:has(#cookie_settings-form)"],detectCmp:[{exists:".js-cookie-notice #cookie_settings-form"}],detectPopup:[{visible:".js-cookie-notice #cookie_settings-form"}],optIn:[{waitForThenClick:".js-cookie-notice button[value=allow]"}],optOut:[{waitForThenClick:".js-cookie-notice button[value=disable]"}]},{name:"paypal-us",prehideSelectors:["#ccpaCookieContent_wrapper, article.ppvx_modal--overpanel"],detectCmp:[{exists:"#ccpaCookieBanner, .privacy-sheet-content"}],detectPopup:[{visible:"#ccpaCookieBanner, .privacy-sheet-content"}],optIn:[{click:"#acceptAllButton"}],optOut:[{if:{exists:"#bannerDeclineButton"},then:[{click:"#bannerDeclineButton"}],else:[{if:{exists:"a#manageCookiesLink"},then:[{click:"a#manageCookiesLink"}],else:[{waitForVisible:".privacy-sheet-content #formContent"},{click:"#formContent .cookiepref-11m2iee-checkbox_base input:checked",all:!0,optional:!0},{click:".cookieAction.saveCookie,.confirmCookie #submitCookiesBtn"}]}]}]},{name:"paypal.com",prehideSelectors:["#gdprCookieBanner"],detectCmp:[{exists:"#gdprCookieBanner"}],detectPopup:[{visible:"#gdprCookieContent_wrapper"}],optIn:[{click:"#acceptAllButton"}],optOut:[{wait:200},{click:".gdprCookieBanner_decline-button"}],test:[{wait:500},{eval:"EVAL_PAYPAL_0"}]},{name:"pinetools.com",cosmetic:!0,prehideSelectors:["#aviso_cookies"],detectCmp:[{exists:"#aviso_cookies"}],detectPopup:[{exists:".lang_en #aviso_cookies"}],optIn:[{click:"#aviso_cookies .a_boton_cerrar"}],optOut:[{hide:"#aviso_cookies"}]},{name:"pinterest-business",vendorUrl:"https://business.pinterest.com/",runContext:{urlPattern:"^https://.*\\.pinterest\\.com/"},prehideSelectors:[".BusinessCookieConsent"],detectCmp:[{exists:".BusinessCookieConsent"}],detectPopup:[{visible:".BusinessCookieConsent [data-id=cookie-consent-banner-buttons]"}],optIn:[{waitForThenClick:"[data-id=cookie-consent-banner-buttons] > div:nth-child(1) button"}],optOut:[{waitForThenClick:"[data-id=cookie-consent-banner-buttons] > div:nth-child(2) button"}]},{name:"pmc",cosmetic:!0,prehideSelectors:["#pmc-pp-tou--notice"],detectCmp:[{exists:"#pmc-pp-tou--notice"}],detectPopup:[{visible:"#pmc-pp-tou--notice"}],optIn:[{click:"span.pmc-pp-tou--notice-close-btn"}],optOut:[{hide:"#pmc-pp-tou--notice"}]},{name:"pornhub.com",runContext:{urlPattern:"^https://(www\\.)?pornhub\\.com/"},cosmetic:!1,prehideSelectors:["#cookieBanner #cookieBannerContent"],detectCmp:[{exists:"#cookieBanner #cookieBannerContent"}],detectPopup:[{visible:"#cookieBanner #cookieBannerContent"}],optIn:[{waitForThenClick:"#cookieBanner [data-label=accept_all]"}],optOut:[{waitForThenClick:"#cookieBanner [data-label=accept_essential]"}]},{name:"pornpics.com",cosmetic:!0,prehideSelectors:["#cookie-contract"],detectCmp:[{exists:"#cookie-contract"}],detectPopup:[{visible:"#cookie-contract"}],optIn:[{click:"#cookie-contract .icon-cross"}],optOut:[{hide:"#cookie-contract"}]},{name:"PrimeBox CookieBar",prehideSelectors:["#cookie-bar"],detectCmp:[{exists:"#cookie-bar .cb-enable,#cookie-bar .cb-disable,#cookie-bar .cb-policy"}],detectPopup:[{visible:"#cookie-bar .cb-enable,#cookie-bar .cb-disable,#cookie-bar .cb-policy",check:"any"}],optIn:[{waitForThenClick:"#cookie-bar .cb-enable"}],optOut:[{click:"#cookie-bar .cb-disable",optional:!0},{hide:"#cookie-bar"}],test:[{eval:"EVAL_PRIMEBOX_0"}]},{name:"privacymanager.io",prehideSelectors:["#gdpr-consent-tool-wrapper",'iframe[src^="https://cmp-consent-tool.privacymanager.io"]'],runContext:{urlPattern:"^https://cmp-consent-tool\\.privacymanager\\.io/",main:!1,frame:!0},detectCmp:[{exists:"button#save"}],detectPopup:[{visible:"button#save"}],optIn:[{click:"button#save"}],optOut:[{if:{exists:"#denyAll"},then:[{click:"#denyAll"},{waitForThenClick:".okButton"}],else:[{waitForThenClick:"#manageSettings"},{waitFor:".purposes-overview-list"},{waitFor:"button#saveAndExit"},{click:"span[role=checkbox][aria-checked=true]",all:!0,optional:!0},{click:"button#saveAndExit"}]}]},{name:"productz.com",vendorUrl:"https://productz.com/",runContext:{urlPattern:"^https://productz\\.com/"},prehideSelectors:[],detectCmp:[{exists:".c-modal.is-active"}],detectPopup:[{visible:".c-modal.is-active"}],optIn:[{waitForThenClick:".c-modal.is-active .is-accept"}],optOut:[{waitForThenClick:".c-modal.is-active .is-dismiss"}]},{name:"pubtech",prehideSelectors:["#pubtech-cmp"],detectCmp:[{exists:"#pubtech-cmp"}],detectPopup:[{visible:"#pubtech-cmp #pt-actions"}],optIn:[{if:{exists:"#pt-accept-all"},then:[{click:"#pubtech-cmp #pt-actions #pt-accept-all"}],else:[{click:"#pubtech-cmp #pt-actions button:nth-of-type(2)"}]}],optOut:[{click:"#pubtech-cmp #pt-close"}],test:[{eval:"EVAL_PUBTECH_0"}]},{name:"quantcast",prehideSelectors:["#qc-cmp2-main,#qc-cmp2-container"],detectCmp:[{exists:"#qc-cmp2-container"}],detectPopup:[{visible:"#qc-cmp2-ui"}],optOut:[{waitFor:'.qc-cmp2-summary-buttons > button[mode="secondary"]',timeout:2e3},{if:{exists:'.qc-cmp2-summary-buttons > button[mode="secondary"]:nth-of-type(2)'},then:[{click:'.qc-cmp2-summary-buttons > button[mode="secondary"]:nth-of-type(2)'}],else:[{click:'.qc-cmp2-summary-buttons > button[mode="secondary"]:nth-of-type(1)'},{waitFor:"#qc-cmp2-ui"},{click:'.qc-cmp2-toggle-switch > button[aria-checked="true"]',all:!0,optional:!0},{click:'.qc-cmp2-main button[aria-label="REJECT ALL"]',optional:!0},{waitForThenClick:'.qc-cmp2-main button[aria-label="SAVE & EXIT"],.qc-cmp2-buttons-desktop > button[mode="primary"]',timeout:5e3}]}],optIn:[{click:'.qc-cmp2-summary-buttons > button[mode="primary"]'}]},{name:"reddit.com",runContext:{urlPattern:"^https://www\\.reddit\\.com/"},prehideSelectors:["[bundlename=reddit_cookie_banner]"],detectCmp:[{exists:"reddit-cookie-banner"}],detectPopup:[{visible:"reddit-cookie-banner"}],optIn:[{waitForThenClick:["reddit-cookie-banner","#accept-all-cookies-button > button"]}],optOut:[{waitForThenClick:["reddit-cookie-banner","#reject-nonessential-cookies-button > button"]}],test:[{eval:"EVAL_REDDIT_0"}]},{name:"roblox",vendorUrl:"https://roblox.com",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?roblox\\.com/"},prehideSelectors:[],detectCmp:[{exists:".cookie-banner-wrapper"}],detectPopup:[{visible:".cookie-banner-wrapper .cookie-banner"}],optIn:[{waitForThenClick:".cookie-banner-wrapper button.btn-cta-lg"}],optOut:[{waitForThenClick:".cookie-banner-wrapper button.btn-secondary-lg"}],test:[{eval:"EVAL_ROBLOX_TEST"}]},{name:"rog-forum.asus.com",runContext:{urlPattern:"^https://rog-forum\\.asus\\.com/"},prehideSelectors:["#cookie-policy-info"],detectCmp:[{exists:"#cookie-policy-info"}],detectPopup:[{visible:"#cookie-policy-info"}],optIn:[{click:'div.cookie-btn-box > div[aria-label="Accept"]'}],optOut:[{click:'div.cookie-btn-box > div[aria-label="Reject"]'},{waitForThenClick:'.cookie-policy-lightbox-bottom > div[aria-label="Save Settings"]'}]},{name:"roofingmegastore.co.uk",runContext:{urlPattern:"^https://(www\\.)?roofingmegastore\\.co\\.uk"},prehideSelectors:["#m-cookienotice"],detectCmp:[{exists:"#m-cookienotice"}],detectPopup:[{visible:"#m-cookienotice"}],optIn:[{click:"#accept-cookies"}],optOut:[{click:"#manage-cookies"},{waitForThenClick:"#accept-selected"}]},{name:"samsung.com",runContext:{urlPattern:"^https://www\\.samsung\\.com/"},cosmetic:!0,prehideSelectors:["div.cookie-bar"],detectCmp:[{exists:"div.cookie-bar"}],detectPopup:[{visible:"div.cookie-bar"}],optIn:[{click:"div.cookie-bar__manage > a"}],optOut:[{hide:"div.cookie-bar"}]},{name:"setapp.com",vendorUrl:"https://setapp.com/",cosmetic:!0,runContext:{urlPattern:"^https://setapp\\.com/"},prehideSelectors:[],detectCmp:[{exists:".cookie-banner.js-cookie-banner"}],detectPopup:[{visible:".cookie-banner.js-cookie-banner"}],optIn:[{waitForThenClick:".cookie-banner.js-cookie-banner button"}],optOut:[{hide:".cookie-banner.js-cookie-banner"}]},{name:"sibbo",prehideSelectors:["sibbo-cmp-layout"],detectCmp:[{exists:"sibbo-cmp-layout"}],detectPopup:[{visible:"#rejectAllMain"}],optIn:[{click:"#acceptAllMain"}],optOut:[{click:"#rejectAllMain"}]},{name:"similarweb.com",cosmetic:!0,prehideSelectors:[".app-cookies-notification"],detectCmp:[{exists:".app-cookies-notification"}],detectPopup:[{exists:".app-layout .app-cookies-notification"}],optIn:[{click:"button.app-cookies-notification__dismiss"}],optOut:[{hide:".app-layout .app-cookies-notification"}]},{name:"Sirdata",cosmetic:!1,prehideSelectors:["#sd-cmp"],detectCmp:[{exists:"#sd-cmp"}],detectPopup:[{visible:"#sd-cmp"}],optIn:[{waitForThenClick:"#sd-cmp .sd-cmp-3cRQ2"}],optOut:[{waitForThenClick:["#sd-cmp","xpath///span[contains(., 'Do not accept') or contains(., 'Acceptera inte') or contains(., 'No aceptar') or contains(., 'Ikke acceptere') or contains(., 'Nicht akzeptieren') or contains(., 'Не приемам') or contains(., 'Να μην γίνει αποδοχή') or contains(., 'Niet accepteren') or contains(., 'Nepřijímat') or contains(., 'Nie akceptuj') or contains(., 'Nu acceptați') or contains(., 'Não aceitar') or contains(., 'Continuer sans accepter') or contains(., 'Non accettare') or contains(., 'Nem fogad el')]"]}]},{name:"skyscanner",vendorUrl:"https://skyscanner.com",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?skyscanner[\\.a-z]+/"},prehideSelectors:[".cookie-banner-wrapper"],detectCmp:[{exists:"#cookieBannerContent"}],detectPopup:[{visible:"#cookieBannerContent"}],optIn:[{waitForThenClick:"[data-tracking-element-id=cookie_banner_accept_all]"}],optOut:[{waitForThenClick:"[data-tracking-element-id=cookie_banner_essential_only]"},{waitForVisible:"#cookieBannerContent",check:"none"}],test:[{eval:"EVAL_SKYSCANNER_TEST"}]},{name:"snigel",detectCmp:[{exists:".snigel-cmp-framework"}],detectPopup:[{visible:".snigel-cmp-framework"}],optOut:[{click:"#sn-b-custom"},{click:"#sn-b-save"}],test:[{eval:"EVAL_SNIGEL_0"}],optIn:[{click:".snigel-cmp-framework #accept-choices"}]},{name:"steampowered.com",detectCmp:[{exists:".cookiepreferences_popup"},{visible:".cookiepreferences_popup"}],detectPopup:[{visible:".cookiepreferences_popup"}],optOut:[{click:"#rejectAllButton"}],optIn:[{click:"#acceptAllButton"}],test:[{wait:1e3},{eval:"EVAL_STEAMPOWERED_0"}]},{name:"strato.de",prehideSelectors:[".consent__wrapper"],runContext:{urlPattern:"^https://www\\.strato\\.de/"},detectCmp:[{exists:".consent"}],detectPopup:[{visible:".consent"}],optIn:[{click:"button.consentAgree"}],optOut:[{click:"button.consentSettings"},{waitForThenClick:"button#consentSubmit"}]},{name:"svt.se",vendorUrl:"https://www.svt.se/",runContext:{urlPattern:"^https://www\\.svt\\.se/"},prehideSelectors:["[class*=CookieConsent__root___]"],detectCmp:[{exists:"[class*=CookieConsent__root___]"}],detectPopup:[{visible:"[class*=CookieConsent__modal___]"}],optIn:[{waitForThenClick:"[class*=CookieConsent__modal___] > div > button[class*=primary]"}],optOut:[{waitForThenClick:"[class*=CookieConsent__modal___] > div > button[class*=secondary]:nth-child(2)"}],test:[{eval:"EVAL_SVT_TEST"}]},{name:"takealot.com",cosmetic:!0,prehideSelectors:['div[class^="cookies-banner-module_"]'],detectCmp:[{exists:'div[class^="cookies-banner-module_cookie-banner_"]'}],detectPopup:[{exists:'div[class^="cookies-banner-module_cookie-banner_"]'}],optIn:[{click:'button[class*="cookies-banner-module_dismiss-button_"]'}],optOut:[{hide:'div[class^="cookies-banner-module_"]'},{if:{exists:'div[class^="cookies-banner-module_small-cookie-banner_"]'},then:[{eval:"EVAL_TAKEALOT_0"}],else:[]}]},{name:"tarteaucitron.js",prehideSelectors:["#tarteaucitronRoot"],detectCmp:[{exists:"#tarteaucitronRoot"}],detectPopup:[{visible:"#tarteaucitronRoot #tarteaucitronAlertBig",check:"any"}],optIn:[{eval:"EVAL_TARTEAUCITRON_1"}],optOut:[{eval:"EVAL_TARTEAUCITRON_0"}],test:[{eval:"EVAL_TARTEAUCITRON_2",comment:"sometimes there are required categories, so we check that at least something is false"}]},{name:"taunton",vendorUrl:"https://www.taunton.com/",prehideSelectors:["#taunton-user-consent__overlay"],detectCmp:[{exists:"#taunton-user-consent__overlay"}],detectPopup:[{exists:"#taunton-user-consent__overlay:not([aria-hidden=true])"}],optIn:[{click:"#taunton-user-consent__toolbar input[type=checkbox]:not(:checked)"},{click:"#taunton-user-consent__toolbar button[type=submit]"}],optOut:[{click:"#taunton-user-consent__toolbar input[type=checkbox]:checked",optional:!0,all:!0},{click:"#taunton-user-consent__toolbar button[type=submit]"}],test:[{eval:"EVAL_TAUNTON_TEST"}]},{name:"Tealium",prehideSelectors:["#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs,#__tealiumImplicitmodal,#consent-layer"],detectCmp:[{exists:"#__tealiumGDPRecModal *,#__tealiumGDPRcpPrefs *,#__tealiumImplicitmodal *"},{eval:"EVAL_TEALIUM_0"}],detectPopup:[{visible:"#__tealiumGDPRecModal *,#__tealiumGDPRcpPrefs *,#__tealiumImplicitmodal *",check:"any"}],optOut:[{eval:"EVAL_TEALIUM_1"},{eval:"EVAL_TEALIUM_DONOTSELL"},{hide:"#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs,#__tealiumImplicitmodal"},{waitForThenClick:"#cm-acceptNone,.js-accept-essential-cookies,#continueWithoutAccepting",timeout:1e3,optional:!0}],optIn:[{hide:"#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs"},{eval:"EVAL_TEALIUM_2"}],test:[{eval:"EVAL_TEALIUM_3"},{eval:"EVAL_TEALIUM_DONOTSELL_CHECK"},{visible:"#__tealiumGDPRecModal,#__tealiumGDPRcpPrefs",check:"none"}]},{name:"temu",vendorUrl:"https://temu.com",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?temu\\.com/"},prehideSelectors:[],detectCmp:[{exists:'div > div > div > div > span[href*="/cookie-and-similar-technologies-policy.html"]'}],detectPopup:[{visible:'div > div > div > div > span[href*="/cookie-and-similar-technologies-policy.html"]'}],optIn:[{waitForThenClick:'div > div > div:has(> div > span[href*="/cookie-and-similar-technologies-policy.html"]) > [role=button]:nth-child(3)'}],optOut:[{if:{exists:"xpath///span[contains(., 'Alle afwijzen') or contains(., 'Reject all') or contains(., 'Tümünü reddet') or contains(., 'Odrzuć wszystko')]"},then:[{waitForThenClick:"xpath///span[contains(., 'Alle afwijzen') or contains(., 'Reject all') or contains(., 'Tümünü reddet') or contains(., 'Odrzuć wszystko')]"}],else:[{waitForThenClick:'div > div > div:has(> div > span[href*="/cookie-and-similar-technologies-policy.html"]) > [role=button]:nth-child(2)'}]}]},{name:"Termly",prehideSelectors:["#termly-code-snippet-support"],detectCmp:[{exists:"#termly-code-snippet-support"}],detectPopup:[{visible:"#termly-code-snippet-support div"}],optIn:[{waitForThenClick:'[data-tid="banner-accept"]'}],optOut:[{if:{exists:'[data-tid="banner-decline"]'},then:[{click:'[data-tid="banner-decline"]'}],else:[{click:".t-preference-button"},{wait:500},{if:{exists:".t-declineAllButton"},then:[{click:".t-declineAllButton"}],else:[{waitForThenClick:".t-preference-modal input[type=checkbox][checked]:not([disabled])",all:!0},{waitForThenClick:".t-saveButton"}]}]}]},{name:"termsfeed",vendorUrl:"https://termsfeed.com",comment:"v4.x.x",prehideSelectors:[".termsfeed-com---nb"],detectCmp:[{exists:".termsfeed-com---nb"}],detectPopup:[{visible:".termsfeed-com---nb"}],optIn:[{waitForThenClick:".cc-nb-okagree"}],optOut:[{waitForThenClick:".cc-nb-reject"}]},{name:"termsfeed3",vendorUrl:"https://termsfeed.com",comment:"v3.x.x",prehideSelectors:[".cc_dialog.cc_css_reboot,.cc_overlay_lock"],detectCmp:[{exists:".cc_dialog.cc_css_reboot"}],detectPopup:[{visible:".cc_dialog.cc_css_reboot"}],optIn:[{waitForThenClick:".cc_dialog.cc_css_reboot .cc_b_ok"}],optOut:[{if:{exists:".cc_dialog.cc_css_reboot .cc_b_cp"},then:[{click:".cc_dialog.cc_css_reboot .cc_b_cp"},{waitForVisible:".cookie-consent-preferences-dialog .cc_cp_f_save button"},{waitForThenClick:".cookie-consent-preferences-dialog .cc_cp_f_save button"}],else:[{hide:".cc_dialog.cc_css_reboot,.cc_overlay_lock"}]}]},{name:"tesco",vendorUrl:"https://www.tesco.com",cosmetic:!1,runContext:{urlPattern:"^https://(www\\.)?tesco\\.com/"},prehideSelectors:["[class*=CookieBanner__Sizer]"],detectCmp:[{exists:"[aria-label=consent-banner]"}],detectPopup:[{visible:"[aria-label=consent-banner]"}],optIn:[{wait:1e3},{waitForThenClick:"xpath///button[contains(., 'Accept all')]"}],optOut:[{wait:1e3},{waitForThenClick:"xpath///button[contains(., 'Reject all')]"}]},{name:"tesla",vendorUrl:"https://tesla.com/",runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?tesla\\.com/"},prehideSelectors:[],detectCmp:[{exists:"#cookie_banner"}],detectPopup:[{visible:"#cookie_banner"}],optIn:[{waitForThenClick:"#tsla-accept-cookie"}],optOut:[{waitForThenClick:"#tsla-reject-cookie"}],test:[{eval:"EVAL_TESLA_TEST"}]},{name:"Test page cosmetic CMP",cosmetic:!0,prehideSelectors:["#privacy-test-page-cmp-test-prehide"],detectCmp:[{exists:"#privacy-test-page-cmp-test-banner"}],detectPopup:[{visible:"#privacy-test-page-cmp-test-banner"}],optIn:[{waitFor:"#accept-all"},{click:"#accept-all"}],optOut:[{hide:"#privacy-test-page-cmp-test-banner"}],test:[{wait:500},{eval:"EVAL_TESTCMP_COSMETIC_0"}]},{name:"Test page CMP",prehideSelectors:["#reject-all"],detectCmp:[{exists:"#privacy-test-page-cmp-test"}],detectPopup:[{visible:"#privacy-test-page-cmp-test"}],optIn:[{waitFor:"#accept-all"},{click:"#accept-all"}],optOut:[{waitFor:"#reject-all"},{eval:"EVAL_TESTCMP_STEP"},{click:"#reject-all"}],test:[{eval:"EVAL_TESTCMP_0"}]},{name:"thalia.de",prehideSelectors:[".consent-banner-box"],detectCmp:[{exists:"consent-banner[component=consent-banner]"}],detectPopup:[{visible:".consent-banner-box"}],optIn:[{click:".button-zustimmen"}],optOut:[{click:"button[data-consent=disagree]"}]},{name:"thefreedictionary.com",prehideSelectors:["#cmpBanner"],detectCmp:[{exists:"#cmpBanner"}],detectPopup:[{visible:"#cmpBanner"}],optIn:[{eval:"EVAL_THEFREEDICTIONARY_1"}],optOut:[{eval:"EVAL_THEFREEDICTIONARY_0"}]},{name:"theverge",runContext:{frame:!1,main:!0,urlPattern:"^https://(www)?\\.theverge\\.com"},intermediate:!1,prehideSelectors:[".duet--cta--cookie-banner"],detectCmp:[{exists:".duet--cta--cookie-banner"}],detectPopup:[{visible:".duet--cta--cookie-banner"}],optIn:[{click:".duet--cta--cookie-banner button.tracking-12",all:!1}],optOut:[{click:".duet--cta--cookie-banner button.tracking-12 > span"}],test:[{eval:"EVAL_THEVERGE_0"}]},{name:"tidbits-com",cosmetic:!0,prehideSelectors:["#eu_cookie_law_widget-2"],detectCmp:[{exists:"#eu_cookie_law_widget-2"}],detectPopup:[{visible:"#eu_cookie_law_widget-2"}],optIn:[{click:"#eu-cookie-law form > input.accept"}],optOut:[{hide:"#eu_cookie_law_widget-2"}]},{name:"tractor-supply",runContext:{urlPattern:"^https://www\\.tractorsupply\\.com/"},cosmetic:!0,prehideSelectors:[".tsc-cookie-banner"],detectCmp:[{exists:".tsc-cookie-banner"}],detectPopup:[{visible:".tsc-cookie-banner"}],optIn:[{click:"#cookie-banner-cancel"}],optOut:[{hide:".tsc-cookie-banner"}]},{name:"trader-joes-com",cosmetic:!0,prehideSelectors:['div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'],detectCmp:[{exists:'div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'}],detectPopup:[{visible:'div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'}],optIn:[{click:'div[class^="CookiesAlert_cookiesAlert__container__"] button'}],optOut:[{hide:'div.aem-page > div[class^="CookiesAlert_cookiesAlert__"]'}]},{name:"transcend",vendorUrl:"https://unknown",cosmetic:!0,prehideSelectors:["#transcend-consent-manager"],detectCmp:[{exists:"#transcend-consent-manager"}],detectPopup:[{visible:"#transcend-consent-manager"}],optIn:[{waitForThenClick:["#transcend-consent-manager","#consentManagerMainDialog .inner-container button"]}],optOut:[{hide:"#transcend-consent-manager"}]},{name:"transip-nl",runContext:{urlPattern:"^https://www\\.transip\\.nl/"},prehideSelectors:["#consent-modal"],detectCmp:[{any:[{exists:"#consent-modal"},{exists:"#privacy-settings-content"}]}],detectPopup:[{any:[{visible:"#consent-modal"},{visible:"#privacy-settings-content"}]}],optIn:[{click:'button[type="submit"]'}],optOut:[{if:{exists:"#privacy-settings-content"},then:[{click:'button[type="submit"]'}],else:[{click:"div.one-modal__action-footer-column--secondary > a"}]}]},{name:"tropicfeel-com",prehideSelectors:["#shopify-section-cookies-controller"],detectCmp:[{exists:"#shopify-section-cookies-controller"}],detectPopup:[{visible:"#shopify-section-cookies-controller #cookies-controller-main-pane",check:"any"}],optIn:[{waitForThenClick:"#cookies-controller-main-pane form[data-form-allow-all] button"}],optOut:[{click:"#cookies-controller-main-pane a[data-tab-target=manage-cookies]"},{waitFor:"#manage-cookies-pane.active"},{click:"#manage-cookies-pane.active input[type=checkbox][checked]:not([disabled])",all:!0},{click:"#manage-cookies-pane.active button[type=submit]"}],test:[]},{name:"true-car",runContext:{urlPattern:"^https://www\\.truecar\\.com/"},cosmetic:!0,prehideSelectors:[['div[aria-labelledby="cookie-banner-heading"]']],detectCmp:[{exists:'div[aria-labelledby="cookie-banner-heading"]'}],detectPopup:[{visible:'div[aria-labelledby="cookie-banner-heading"]'}],optIn:[{click:'div[aria-labelledby="cookie-banner-heading"] > button[aria-label="Close"]'}],optOut:[{hide:'div[aria-labelledby="cookie-banner-heading"]'}]},{name:"truyo",prehideSelectors:["#truyo-consent-module"],detectCmp:[{exists:"#truyo-cookieBarContent"}],detectPopup:[{visible:"#truyo-consent-module"}],optIn:[{click:"button#acceptAllCookieButton"}],optOut:[{click:"button#declineAllCookieButton"}]},{name:"twcc",vendorUrl:"https://unknown",cosmetic:!1,runContext:{main:!0,frame:!1,urlPattern:""},prehideSelectors:["#twcc__mechanism"],detectCmp:[{exists:"#twcc__mechanism .twcc__notice"}],detectPopup:[{visible:"#twcc__mechanism .twcc__notice"}],optIn:[{waitForThenClick:"#twcc__accept-button"}],optOut:[{waitForThenClick:"#twcc__decline-button"}],test:[{eval:"EVAL_TWCC_TEST"}]},{name:"twitch-mobile",vendorUrl:"https://m.twitch.tv/",cosmetic:!0,runContext:{urlPattern:"^https?://m\\.twitch\\.tv"},prehideSelectors:[],detectCmp:[{exists:'.ReactModal__Overlay [href="https://www.twitch.tv/p/cookie-policy"]'}],detectPopup:[{visible:'.ReactModal__Overlay [href="https://www.twitch.tv/p/cookie-policy"]'}],optIn:[{waitForThenClick:'.ReactModal__Overlay:has([href="https://www.twitch.tv/p/cookie-policy"]) button'}],optOut:[{hide:'.ReactModal__Overlay:has([href="https://www.twitch.tv/p/cookie-policy"])'}]},{name:"twitch.tv",runContext:{urlPattern:"^https?://(www\\.)?twitch\\.tv"},prehideSelectors:["div:has(> .consent-banner .consent-banner__content--gdpr-v2),.ReactModalPortal:has([data-a-target=consent-modal-save])"],detectCmp:[{exists:".consent-banner .consent-banner__content--gdpr-v2"}],detectPopup:[{visible:".consent-banner .consent-banner__content--gdpr-v2"}],optIn:[{click:'button[data-a-target="consent-banner-accept"]'}],optOut:[{hide:"div:has(> .consent-banner .consent-banner__content--gdpr-v2)"},{click:'button[data-a-target="consent-banner-manage-preferences"]'},{waitFor:"input[type=checkbox][data-a-target=tw-checkbox]"},{click:"input[type=checkbox][data-a-target=tw-checkbox][checked]:not([disabled])",all:!0,optional:!0},{waitForThenClick:"[data-a-target=consent-modal-save]"},{waitForVisible:".ReactModalPortal:has([data-a-target=consent-modal-save])",check:"none"}]},{name:"twitter",runContext:{urlPattern:"^https://([a-z0-9-]+\\.)?(twitter|x)\\.com/"},prehideSelectors:['[data-testid="BottomBar"]'],detectCmp:[{exists:'[data-testid="BottomBar"] div'}],detectPopup:[{visible:'[data-testid="BottomBar"] div'}],optIn:[{waitForThenClick:'[data-testid="BottomBar"] > div:has(>div:first-child>div:last-child>button[role=button]>span) > div:last-child > button[role=button]:first-child'}],optOut:[{waitForThenClick:'[data-testid="BottomBar"] > div:has(>div:first-child>div:last-child>button[role=button]>span) > div:last-child > button[role=button]:last-child'}],TODOtest:[{eval:"EVAL_document.cookie.includes('d_prefs=MjoxLGNvbnNlbnRfdmVyc2lvbjoy')"}]},{name:"ubuntu.com",prehideSelectors:["dialog.cookie-policy"],detectCmp:[{any:[{exists:"dialog.cookie-policy header"},{exists:'xpath///*[@id="modal"]/div/header'}]}],detectPopup:[{any:[{visible:"dialog header"},{visible:'xpath///*[@id="modal"]/div/header'}]}],optIn:[{any:[{waitForThenClick:"#cookie-policy-button-accept"},{waitForThenClick:'xpath///*[@id="cookie-policy-button-accept"]'}]}],optOut:[{any:[{waitForThenClick:"button.js-manage"},{waitForThenClick:'xpath///*[@id="cookie-policy-content"]/p[4]/button[2]'}]},{waitForThenClick:"dialog.cookie-policy .p-switch__input:checked",optional:!0,all:!0,timeout:500},{any:[{waitForThenClick:"dialog.cookie-policy .js-save-preferences"},{waitForThenClick:'xpath///*[@id="modal"]/div/button'}]}],test:[{eval:"EVAL_UBUNTU_COM_0"}]},{name:"UK Cookie Consent",prehideSelectors:["#catapult-cookie-bar"],cosmetic:!0,detectCmp:[{exists:"#catapult-cookie-bar"}],detectPopup:[{exists:".has-cookie-bar #catapult-cookie-bar"}],optIn:[{click:"#catapultCookie"}],optOut:[{hide:"#catapult-cookie-bar"}],test:[{eval:"EVAL_UK_COOKIE_CONSENT_0"}]},{name:"urbanarmorgear-com",cosmetic:!0,prehideSelectors:['div[class^="Layout__CookieBannerContainer-"]'],detectCmp:[{exists:'div[class^="Layout__CookieBannerContainer-"]'}],detectPopup:[{visible:'div[class^="Layout__CookieBannerContainer-"]'}],optIn:[{click:'button[class^="CookieBanner__AcceptButton"]'}],optOut:[{hide:'div[class^="Layout__CookieBannerContainer-"]'}]},{name:"usercentrics-api",detectCmp:[{exists:"#usercentrics-root,#usercentrics-cmp-ui"}],detectPopup:[{eval:"EVAL_USERCENTRICS_API_0"},{if:{exists:"#usercentrics-cmp-ui"},then:[{waitForVisible:"#usercentrics-cmp-ui",timeout:2e3}],else:[{exists:["#usercentrics-root","[data-testid=uc-container]"]},{waitForVisible:"#usercentrics-root",timeout:2e3}]}],optIn:[{eval:"EVAL_USERCENTRICS_API_3"},{eval:"EVAL_USERCENTRICS_API_1"},{eval:"EVAL_USERCENTRICS_API_5"}],optOut:[{eval:"EVAL_USERCENTRICS_API_1"},{eval:"EVAL_USERCENTRICS_API_2"}],test:[{eval:"EVAL_USERCENTRICS_API_6"}]},{name:"usercentrics-button",detectCmp:[{exists:"#usercentrics-button"}],detectPopup:[{visible:"#usercentrics-button #uc-btn-accept-banner"}],optIn:[{click:"#usercentrics-button #uc-btn-accept-banner"}],optOut:[{click:"#usercentrics-button #uc-btn-deny-banner"}],test:[{eval:"EVAL_USERCENTRICS_BUTTON_0"}]},{name:"uswitch.com",runContext:{main:!0,frame:!1,urlPattern:"^https://(www\\.)?uswitch\\.com/"},prehideSelectors:[".ucb"],detectCmp:[{exists:".ucb-banner"}],detectPopup:[{visible:".ucb-banner"}],optIn:[{waitForThenClick:".ucb-banner .ucb-btn-accept"}],optOut:[{waitForThenClick:".ucb-banner .ucb-btn-save"}]},{name:"vodafone.de",runContext:{urlPattern:"^https://www\\.vodafone\\.de/"},prehideSelectors:[".dip-consent,.dip-consent-container"],detectCmp:[{exists:".dip-consent-container"}],detectPopup:[{visible:".dip-consent-content"}],optOut:[{click:'.dip-consent-btn[tabindex="2"]'}],optIn:[{click:'.dip-consent-btn[tabindex="1"]'}]},{name:"waitrose.com",prehideSelectors:["div[aria-labelledby=CookieAlertModalHeading]","section[data-test=initial-waitrose-cookie-consent-banner]","section[data-test=cookie-consent-modal]"],detectCmp:[{exists:"section[data-test=initial-waitrose-cookie-consent-banner]"}],detectPopup:[{visible:"section[data-test=initial-waitrose-cookie-consent-banner]"}],optIn:[{click:"button[data-test=accept-all]"}],optOut:[{click:"button[data-test=manage-cookies]"},{wait:200},{eval:"EVAL_WAITROSE_0"},{click:"button[data-test=submit]"}],test:[{eval:"EVAL_WAITROSE_1"}]},{name:"webflow",vendorUrl:"https://webflow.com/",prehideSelectors:[".fs-cc-components"],detectCmp:[{exists:".fs-cc-components"}],detectPopup:[{visible:".fs-cc-components"},{visible:"[fs-cc=banner]"}],optIn:[{wait:500},{waitForThenClick:"[fs-cc=banner] [fs-cc=allow]"}],optOut:[{wait:500},{waitForThenClick:"[fs-cc=banner] [fs-cc=deny]"}]},{name:"wetransfer.com",detectCmp:[{exists:".welcome__cookie-notice"}],detectPopup:[{visible:".welcome__cookie-notice"}],optIn:[{click:".welcome__button--accept"}],optOut:[{click:".welcome__button--decline"}]},{name:"whitepages.com",runContext:{urlPattern:"^https://www\\.whitepages\\.com/"},cosmetic:!0,prehideSelectors:[".cookie-wrapper, .cookie-overlay"],detectCmp:[{exists:".cookie-wrapper"}],detectPopup:[{visible:".cookie-overlay"}],optIn:[{click:'button[aria-label="Got it"]'}],optOut:[{hide:".cookie-wrapper"}]},{name:"wolframalpha",vendorUrl:"https://www.wolframalpha.com",prehideSelectors:[],cosmetic:!0,runContext:{urlPattern:"^https://www\\.wolframalpha\\.com/"},detectCmp:[{exists:"section._a_yb"}],detectPopup:[{visible:"section._a_yb"}],optIn:[{waitForThenClick:"section._a_yb button"}],optOut:[{hide:"section._a_yb"}]},{name:"woo-commerce-com",prehideSelectors:[".wccom-comp-privacy-banner .wccom-privacy-banner"],detectCmp:[{exists:".wccom-comp-privacy-banner .wccom-privacy-banner"}],detectPopup:[{exists:".wccom-comp-privacy-banner .wccom-privacy-banner"}],optIn:[{click:".wccom-privacy-banner__content-buttons button.is-primary"}],optOut:[{click:".wccom-privacy-banner__content-buttons button.is-secondary"},{waitForThenClick:"input[type=checkbox][checked]:not([disabled])",all:!0},{click:"div.wccom-modal__footer > button"}]},{name:"WP Cookie Notice for GDPR",vendorUrl:"https://wordpress.org/plugins/gdpr-cookie-consent/",prehideSelectors:["#gdpr-cookie-consent-bar"],detectCmp:[{exists:"#gdpr-cookie-consent-bar"}],detectPopup:[{visible:"#gdpr-cookie-consent-bar"}],optIn:[{waitForThenClick:"#gdpr-cookie-consent-bar #cookie_action_accept"}],optOut:[{waitForThenClick:"#gdpr-cookie-consent-bar #cookie_action_reject"}],test:[{eval:"EVAL_WP_COOKIE_NOTICE_0"}]},{name:"wpcc",cosmetic:!0,prehideSelectors:[".wpcc-container"],detectCmp:[{exists:".wpcc-container"}],detectPopup:[{exists:".wpcc-container .wpcc-message"}],optIn:[{click:".wpcc-compliance .wpcc-btn"}],optOut:[{hide:".wpcc-container"}]},{name:"xe.com",vendorUrl:"https://www.xe.com/",runContext:{urlPattern:"^https://www\\.xe\\.com/"},prehideSelectors:["[class*=ConsentBanner]"],detectCmp:[{exists:"[class*=ConsentBanner]"}],detectPopup:[{visible:"[class*=ConsentBanner]"}],optIn:[{waitForThenClick:"[class*=ConsentBanner] .egnScw"}],optOut:[{wait:1e3},{waitForThenClick:"[class*=ConsentBanner] .frDWEu"},{waitForThenClick:"[class*=ConsentBanner] .hXIpFU"}],test:[{eval:"EVAL_XE_TEST"}]},{name:"xhamster-eu",prehideSelectors:[".cookies-modal"],detectCmp:[{exists:".cookies-modal"}],detectPopup:[{exists:".cookies-modal"}],optIn:[{click:"button.cmd-button-accept-all"}],optOut:[{click:"button.cmd-button-reject-all"}]},{name:"xhamster-us",runContext:{urlPattern:"^https://(www\\.)?xhamster\\d?\\.com"},cosmetic:!0,prehideSelectors:[".cookie-announce"],detectCmp:[{exists:".cookie-announce"}],detectPopup:[{visible:".cookie-announce .announce-text"}],optIn:[{click:".cookie-announce button.xh-button"}],optOut:[{hide:".cookie-announce"}]},{name:"xing.com",detectCmp:[{exists:"div[class^=cookie-consent-CookieConsent]"}],detectPopup:[{exists:"div[class^=cookie-consent-CookieConsent]"}],optIn:[{click:"#consent-accept-button"}],optOut:[{click:"#consent-settings-button"},{click:".consent-banner-button-accept-overlay"}],test:[{eval:"EVAL_XING_0"}]},{name:"xnxx-com",cosmetic:!0,prehideSelectors:["#cookies-use-alert"],detectCmp:[{exists:"#cookies-use-alert"}],detectPopup:[{visible:"#cookies-use-alert"}],optIn:[{click:"#cookies-use-alert .close"}],optOut:[{hide:"#cookies-use-alert"}]},{name:"xvideos",vendorUrl:"https://xvideos.com",runContext:{urlPattern:"^https://[^/]*xvideos\\.com/"},prehideSelectors:[],detectCmp:[{exists:".disclaimer-opened #disclaimer-cookies"}],detectPopup:[{visible:".disclaimer-opened #disclaimer-cookies"}],optIn:[{waitForThenClick:"#disclaimer-accept_cookies"}],optOut:[{waitForThenClick:"#disclaimer-reject_cookies"}]},{name:"Yahoo",runContext:{urlPattern:"^https://consent\\.yahoo\\.com/v2/"},prehideSelectors:["#reject-all"],detectCmp:[{exists:"#consent-page"}],detectPopup:[{visible:"#consent-page"}],optIn:[{waitForThenClick:"#consent-page button[value=agree]"}],optOut:[{waitForThenClick:"#consent-page button[value=reject]"}]},{name:"youporn.com",cosmetic:!0,prehideSelectors:[".euCookieModal, #js_euCookieModal"],detectCmp:[{exists:".euCookieModal"}],detectPopup:[{exists:".euCookieModal, #js_euCookieModal"}],optIn:[{click:'button[name="user_acceptCookie"]'}],optOut:[{hide:".euCookieModal"}]},{name:"youtube-desktop",prehideSelectors:["tp-yt-iron-overlay-backdrop.opened","ytd-consent-bump-v2-lightbox"],detectCmp:[{exists:"ytd-consent-bump-v2-lightbox tp-yt-paper-dialog"},{exists:'ytd-consent-bump-v2-lightbox tp-yt-paper-dialog a[href^="https://consent.youtube.com/"]'}],detectPopup:[{visible:"ytd-consent-bump-v2-lightbox tp-yt-paper-dialog"}],optIn:[{waitForThenClick:"ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:last-child #button,ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:last-child button"},{wait:500}],optOut:[{waitForThenClick:"ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:first-child #button,ytd-consent-bump-v2-lightbox .eom-buttons .eom-button-row:first-child ytd-button-renderer:first-child button"},{wait:500}],test:[{wait:500},{eval:"EVAL_YOUTUBE_DESKTOP_0"}]},{name:"youtube-mobile",prehideSelectors:[".consent-bump-v2-lightbox"],detectCmp:[{exists:"ytm-consent-bump-v2-renderer"}],detectPopup:[{visible:"ytm-consent-bump-v2-renderer"}],optIn:[{waitForThenClick:"ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons c3-material-button:first-child button, ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons ytm-button-renderer:first-child button"},{wait:500}],optOut:[{waitForThenClick:"ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons c3-material-button:nth-child(2) button, ytm-consent-bump-v2-renderer .privacy-terms + .one-col-dialog-buttons ytm-button-renderer:nth-child(2) button"},{wait:500}],test:[{wait:500},{eval:"EVAL_YOUTUBE_MOBILE_0"}]},{name:"zdf",prehideSelectors:["#zdf-cmp-banner-sdk"],detectCmp:[{exists:"#zdf-cmp-banner-sdk"}],detectPopup:[{visible:"#zdf-cmp-main.zdf-cmp-show"}],optIn:[{waitForThenClick:"#zdf-cmp-main #zdf-cmp-accept-btn"}],optOut:[{waitForThenClick:"#zdf-cmp-main #zdf-cmp-deny-btn"}],test:[]},{name:"zentralruf-de",runContext:{urlPattern:"^https://(www\\.)?zentralruf\\.de"},prehideSelectors:["#cookie_modal_wrapper"],detectCmp:[{exists:"#cookie_modal_wrapper"}],detectPopup:[{visible:"#cookie_modal_wrapper"}],optIn:[{waitForThenClick:"#cookie_modal_wrapper #cookie_modal_button_consent_all"}],optOut:[{waitForThenClick:"#cookie_modal_wrapper #cookie_modal_button_choose"}]}],_e={"didomi.io":{detectors:[{presentMatcher:{target:{selector:"#didomi-host, #didomi-notice"},type:"css"},showingMatcher:{target:{selector:"body.didomi-popup-open, .didomi-notice-banner"},type:"css"}}],methods:[{action:{target:{selector:".didomi-popup-notice-buttons .didomi-button:not(.didomi-button-highlight), .didomi-notice-banner .didomi-learn-more-button"},type:"click"},name:"OPEN_OPTIONS"},{action:{actions:[{retries:50,target:{selector:"#didomi-purpose-cookies"},type:"waitcss",waitTime:50},{consents:[{description:"Share (everything) with others",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-share_whith_others]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-share_whith_others]:last-child"},type:"click"},type:"X"},{description:"Information storage and access",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-cookies]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-cookies]:last-child"},type:"click"},type:"D"},{description:"Content selection, offers and marketing",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-CL-T1Rgm7]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-CL-T1Rgm7]:last-child"},type:"click"},type:"E"},{description:"Analytics",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-analytics]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-analytics]:last-child"},type:"click"},type:"B"},{description:"Analytics",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-M9NRHJe3G]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-M9NRHJe3G]:last-child"},type:"click"},type:"B"},{description:"Ad and content selection",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-advertising_personalization]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-advertising_personalization]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection",falseAction:{parent:{childFilter:{target:{selector:"#didomi-purpose-pub-ciblee"}},selector:".didomi-consent-popup-data-processing, .didomi-components-accordion-label-container"},target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-pub-ciblee]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-pub-ciblee]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - basics",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-q4zlJqdcD]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-q4zlJqdcD]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - partners and subsidiaries",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-partenaire-cAsDe8jC]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-partenaire-cAsDe8jC]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - social networks",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-p4em9a8m]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-p4em9a8m]:last-child"},type:"click"},type:"F"},{description:"Ad and content selection - others",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-autres-pub]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-autres-pub]:last-child"},type:"click"},type:"F"},{description:"Social networks",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-reseauxsociaux]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-reseauxsociaux]:last-child"},type:"click"},type:"A"},{description:"Social networks",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-social_media]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-social_media]:last-child"},type:"click"},type:"A"},{description:"Content selection",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-content_personalization]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-content_personalization]:last-child"},type:"click"},type:"E"},{description:"Ad delivery",falseAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-ad_delivery]:first-child"},type:"click"},trueAction:{target:{selector:".didomi-components-radio__option[aria-describedby=didomi-purpose-ad_delivery]:last-child"},type:"click"},type:"F"}],type:"consent"},{action:{consents:[{matcher:{childFilter:{target:{selector:":not(.didomi-components-radio__option--selected)"}},type:"css"},trueAction:{target:{selector:":nth-child(2)"},type:"click"},falseAction:{target:{selector:":first-child"},type:"click"},type:"X"}],type:"consent"},target:{selector:".didomi-components-radio"},type:"foreach"}],type:"list"},name:"DO_CONSENT"},{action:{parent:{selector:".didomi-consent-popup-footer .didomi-consent-popup-actions"},target:{selector:".didomi-components-button:first-child"},type:"click"},name:"SAVE_CONSENT"}]},oil:{detectors:[{presentMatcher:{target:{selector:".as-oil-content-overlay"},type:"css"},showingMatcher:{target:{selector:".as-oil-content-overlay"},type:"css"}}],methods:[{action:{actions:[{target:{selector:".as-js-advanced-settings"},type:"click"},{retries:"10",target:{selector:".as-oil-cpc__purpose-container"},type:"waitcss",waitTime:"250"}],type:"list"},name:"OPEN_OPTIONS"},{action:{actions:[{consents:[{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Information storage and access","Opbevaring af og adgang til oplysninger på din enhed"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Information storage and access","Opbevaring af og adgang til oplysninger på din enhed"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"D"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personlige annoncer","Personalisation"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personlige annoncer","Personalisation"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"E"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Annoncevalg, levering og rapportering","Ad selection, delivery, reporting"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Annoncevalg, levering og rapportering","Ad selection, delivery, reporting"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"F"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personalisering af indhold","Content selection, delivery, reporting"]},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:["Personalisering af indhold","Content selection, delivery, reporting"]},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"E"},{matcher:{parent:{childFilter:{target:{selector:".as-oil-cpc__purpose-header",textFilter:["Måling","Measurement"]}},selector:".as-oil-cpc__purpose-container"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{childFilter:{target:{selector:".as-oil-cpc__purpose-header",textFilter:["Måling","Measurement"]}},selector:".as-oil-cpc__purpose-container"},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"B"},{matcher:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:"Google"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".as-oil-cpc__purpose-container",textFilter:"Google"},target:{selector:".as-oil-cpc__switch"},type:"click"},type:"F"}],type:"consent"}],type:"list"},name:"DO_CONSENT"},{action:{target:{selector:".as-oil__btn-optin"},type:"click"},name:"SAVE_CONSENT"},{action:{target:{selector:"div.as-oil"},type:"hide"},name:"HIDE_CMP"}]},optanon:{detectors:[{presentMatcher:{target:{selector:"#optanon-menu, .optanon-alert-box-wrapper"},type:"css"},showingMatcher:{target:{displayFilter:!0,selector:".optanon-alert-box-wrapper"},type:"css"}}],methods:[{action:{actions:[{target:{selector:".optanon-alert-box-wrapper .optanon-toggle-display, a[onclick*='OneTrust.ToggleInfoDisplay()'], a[onclick*='Optanon.ToggleInfoDisplay()']"},type:"click"}],type:"list"},name:"OPEN_OPTIONS"},{action:{actions:[{target:{selector:".preference-menu-item #Your-privacy"},type:"click"},{target:{selector:"#optanon-vendor-consent-text"},type:"click"},{action:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"X"}],type:"consent"},target:{selector:"#optanon-vendor-consent-list .vendor-item"},type:"foreach"},{target:{selector:".vendor-consent-back-link"},type:"click"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-performance"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-performance"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-functional"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-functional"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-advertising"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-advertising"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-social"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-social"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Social Media Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Social Media Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalisation"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalisation"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Site monitoring cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Site monitoring cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Third party privacy-enhanced content"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Third party privacy-enhanced content"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"X"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Performance & Advertising Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Performance & Advertising Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Information storage and access"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Information storage and access"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"D"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad selection, delivery, reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad selection, delivery, reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content selection, delivery, reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content selection, delivery, reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Measurement"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Measurement"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Recommended Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Recommended Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"X"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Unclassified Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Unclassified Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"X"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Analytical Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Analytical Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"B"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Marketing Cookies"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Marketing Cookies"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalization"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Personalization"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad Selection, Delivery & Reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Ad Selection, Delivery & Reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},type:"ifcss"},{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content Selection, Delivery & Reporting"},trueAction:{actions:[{parent:{selector:"#optanon-menu, .optanon-menu"},target:{selector:".menu-item-necessary",textFilter:"Content Selection, Delivery & Reporting"},type:"click"},{consents:[{matcher:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status input"},type:"checkbox"},toggleAction:{parent:{selector:"#optanon-popup-body-right"},target:{selector:".optanon-status label"},type:"click"},type:"E"}],type:"consent"}],type:"list"},type:"ifcss"}],type:"list"},name:"DO_CONSENT"},{action:{parent:{selector:".optanon-save-settings-button"},target:{selector:".optanon-white-button-middle"},type:"click"},name:"SAVE_CONSENT"},{action:{actions:[{target:{selector:"#optanon-popup-wrapper"},type:"hide"},{target:{selector:"#optanon-popup-bg"},type:"hide"},{target:{selector:".optanon-alert-box-wrapper"},type:"hide"}],type:"list"},name:"HIDE_CMP"}]},quantcast2:{detectors:[{presentMatcher:{target:{selector:"[data-tracking-opt-in-overlay]"},type:"css"},showingMatcher:{target:{selector:"[data-tracking-opt-in-overlay] [data-tracking-opt-in-learn-more]"},type:"css"}}],methods:[{action:{target:{selector:"[data-tracking-opt-in-overlay] [data-tracking-opt-in-learn-more]"},type:"click"},name:"OPEN_OPTIONS"},{action:{actions:[{type:"wait",waitTime:500},{action:{actions:[{target:{selector:"div",textFilter:["Information storage and access"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"D"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Personalization"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"F"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Ad selection, delivery, reporting"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"F"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Content selection, delivery, reporting"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"E"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Measurement"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"B"}],type:"consent"},type:"ifcss"},{target:{selector:"div",textFilter:["Other Partners"]},trueAction:{consents:[{matcher:{target:{selector:"input"},type:"checkbox"},toggleAction:{target:{selector:"label"},type:"click"},type:"X"}],type:"consent"},type:"ifcss"}],type:"list"},parent:{childFilter:{target:{selector:"input"}},selector:"[data-tracking-opt-in-overlay] > div > div"},target:{childFilter:{target:{selector:"input"}},selector:":scope > div"},type:"foreach"}],type:"list"},name:"DO_CONSENT"},{action:{target:{selector:"[data-tracking-opt-in-overlay] [data-tracking-opt-in-save]"},type:"click"},name:"SAVE_CONSENT"}]},springer:{detectors:[{presentMatcher:{parent:null,target:{selector:".cmp-app_gdpr"},type:"css"},showingMatcher:{parent:null,target:{displayFilter:!0,selector:".cmp-popup_popup"},type:"css"}}],methods:[{action:{actions:[{target:{selector:".cmp-intro_rejectAll"},type:"click"},{type:"wait",waitTime:250},{target:{selector:".cmp-purposes_purposeItem:not(.cmp-purposes_selectedPurpose)"},type:"click"}],type:"list"},name:"OPEN_OPTIONS"},{action:{consents:[{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Przechowywanie informacji na urządzeniu lub dostęp do nich",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Przechowywanie informacji na urządzeniu lub dostęp do nich",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"D"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór podstawowych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór podstawowych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"F"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"F"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"E"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Tworzenie profilu spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"E"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Wybór spersonalizowanych treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"B"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności reklam",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"B"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Pomiar wydajności treści",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"B"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Stosowanie badań rynkowych w celu generowania opinii odbiorców",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Stosowanie badań rynkowych w celu generowania opinii odbiorców",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"X"},{matcher:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Opracowywanie i ulepszanie produktów",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch .cmp-switch_isSelected"},type:"css"},toggleAction:{parent:{selector:".cmp-purposes_detailHeader",textFilter:"Opracowywanie i ulepszanie produktów",childFilter:{target:{selector:".cmp-switch_switch"}}},target:{selector:".cmp-switch_switch:not(.cmp-switch_isSelected)"},type:"click"},type:"X"}],type:"consent"},name:"DO_CONSENT"},{action:{target:{selector:".cmp-details_save"},type:"click"},name:"SAVE_CONSENT"}]},wordpressgdpr:{detectors:[{presentMatcher:{parent:null,target:{selector:".wpgdprc-consent-bar"},type:"css"},showingMatcher:{parent:null,target:{displayFilter:!0,selector:".wpgdprc-consent-bar"},type:"css"}}],methods:[{action:{parent:null,target:{selector:".wpgdprc-consent-bar .wpgdprc-consent-bar__settings",textFilter:null},type:"click"},name:"OPEN_OPTIONS"},{action:{actions:[{target:{selector:".wpgdprc-consent-modal .wpgdprc-button",textFilter:"Eyeota"},type:"click"},{consents:[{description:"Eyeota Cookies",matcher:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Eyeota"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Eyeota"},target:{selector:"label"},type:"click"},type:"X"}],type:"consent"},{target:{selector:".wpgdprc-consent-modal .wpgdprc-button",textFilter:"Advertising"},type:"click"},{consents:[{description:"Advertising Cookies",matcher:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Advertising"},target:{selector:"input"},type:"checkbox"},toggleAction:{parent:{selector:".wpgdprc-consent-modal__description",textFilter:"Advertising"},target:{selector:"label"},type:"click"},type:"F"}],type:"consent"}],type:"list"},name:"DO_CONSENT"},{action:{parent:null,target:{selector:".wpgdprc-button",textFilter:"Save my settings"},type:"click"},name:"SAVE_CONSENT"}]}},ye={autoconsent:ge,consentomatic:_e},we=Object.freeze({__proto__:null,autoconsent:ge,consentomatic:_e,default:ye}); /*! Bundled license information: @ghostery/adblocker/dist/esm/codebooks/cosmetic-selector.js: @@ -442,4 +442,4 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. *) - */const hn=new class{constructor(e,t=null,o=null){if(this.id=c(),this.rules=[],this.foundCmp=null,this.state={cosmeticFiltersOn:!1,filterListReported:!1,lifecycle:"loading",prehideOn:!1,findCmpAttempts:0,detectedCmps:[],detectedPopups:[],selfTest:null},a.sendContentMessage=e,this.sendContentMessage=e,this.rules=[],this.updateState({lifecycle:"loading"}),this.addDynamicRules(),t)this.initialize(t,o);else{o&&this.parseDeclarativeRules(o);e({type:"init",url:window.location.href}),this.updateState({lifecycle:"waitingForInitResponse"})}this.domActions=new _(this)}initialize(e,t){const o=b(e);if(o.logs.lifecycle&&console.log("autoconsent init",window.location.href),this.config=o,o.enabled){if(t&&this.parseDeclarativeRules(t),e.enableFilterList){try{an&&an.length>0&&(this.filtersEngine=nn.deserialize(an))}catch(e){console.error("Error parsing filter list",e)}"loading"===document.readyState?window.addEventListener("DOMContentLoaded",(()=>{this.applyCosmeticFilters()})):this.applyCosmeticFilters()}if(this.rules=function(e,t){return e.filter((e=>(!t.disabledCmps||!t.disabledCmps.includes(e.name))&&(t.enableCosmeticRules||!e.isCosmetic)))}(this.rules,o),e.enablePrehide)if(document.documentElement)this.prehideElements();else{const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.prehideElements()};window.addEventListener("DOMContentLoaded",e)}if("loading"===document.readyState){const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.start()};window.addEventListener("DOMContentLoaded",e)}else this.start();this.updateState({lifecycle:"initialized"})}else o.logs.lifecycle&&console.log("autoconsent is disabled")}addDynamicRules(){v.forEach((e=>{this.rules.push(new e(this))}))}parseDeclarativeRules(e){e.consentomatic&&Object.keys(e.consentomatic).forEach((t=>{this.addConsentomaticCMP(t,e.consentomatic[t])})),e.autoconsent&&e.autoconsent.forEach((e=>{this.addDeclarativeCMP(e)}))}addDeclarativeCMP(e){this.rules.push(new u(e,this))}addConsentomaticCMP(e,t){this.rules.push(new h(`com_${e}`,t))}start(){!function(e,t=500){globalThis.requestIdleCallback?requestIdleCallback(e,{timeout:t}):setTimeout(e,0)}((()=>this._start()))}async _start(){const e=this.config.logs;e.lifecycle&&console.log(`Detecting CMPs on ${window.location.href}`),this.updateState({lifecycle:"started"});const t=await this.findCmp(this.config.detectRetries);if(this.updateState({detectedCmps:t.map((e=>e.name))}),0===t.length)return e.lifecycle&&console.log("no CMP found",location.href),this.config.enablePrehide&&this.undoPrehide(),this.filterListFallback();this.updateState({lifecycle:"cmpDetected"});const o=[],i=[];for(const e of t)e.isCosmetic?i.push(e):o.push(e);let n=!1,s=await this.detectPopups(o,(async e=>{n=await this.handlePopup(e)}));if(0===s.length&&(s=await this.detectPopups(i,(async e=>{n=await this.handlePopup(e)}))),0===s.length)return e.lifecycle&&console.log("no popup found"),this.config.enablePrehide&&this.undoPrehide(),!1;if(s.length>1){const t={msg:"Found multiple CMPs, check the detection rules.",cmps:s.map((e=>e.name))};e.errors&&console.warn(t.msg,t.cmps),this.sendContentMessage({type:"autoconsentError",details:t})}return n}async findCmp(e){const t=this.config.logs;this.updateState({findCmpAttempts:this.state.findCmpAttempts+1});const o=[];for(const e of this.rules)try{if(!e.checkRunContext())continue;await e.detectCmp()&&(t.lifecycle&&console.log(`Found CMP: ${e.name} ${window.location.href}`),this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:e.name}),o.push(e))}catch(o){t.errors&&console.warn(`error detecting ${e.name}`,o)}return 0===o.length&&e>0?(await this.domActions.wait(500),this.findCmp(e-1)):o}async detectPopup(e){if(await this.waitForPopup(e).catch((t=>(this.config.logs.errors&&console.warn(`error waiting for a popup for ${e.name}`,t),!1))))return this.updateState({detectedPopups:this.state.detectedPopups.concat([e.name])}),this.sendContentMessage({type:"popupFound",cmp:e.name,url:location.href}),e;throw new Error("Popup is not shown")}async detectPopups(e,t){const o=e.map((e=>this.detectPopup(e)));await Promise.any(o).then((e=>{t(e)})).catch((()=>null));const i=await Promise.allSettled(o),n=[];for(const e of i)"fulfilled"===e.status&&n.push(e.value);return n}async handlePopup(e){return this.updateState({lifecycle:"openPopupDetected"}),this.config.enablePrehide&&!this.state.prehideOn&&this.prehideElements(),this.state.cosmeticFiltersOn&&this.undoCosmetics(),this.foundCmp=e,"optOut"===this.config.autoAction?await this.doOptOut():"optIn"===this.config.autoAction?await this.doOptIn():(this.config.logs.lifecycle&&console.log("waiting for opt-out signal...",location.href),!0)}async doOptOut(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptOut"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt out on ${window.location.href}`),t=await this.foundCmp.optOut(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt out result ${t}`)):(e.errors&&console.log("no CMP to opt out"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optOutResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:this.foundCmp&&this.foundCmp.hasSelfTest,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optOutSucceeded":"optOutFailed"}),t}async doOptIn(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptIn"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt in on ${window.location.href}`),t=await this.foundCmp.optIn(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt in result ${t}`)):(e.errors&&console.log("no CMP to opt in"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optInResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:!1,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optInSucceeded":"optInFailed"}),t}async doSelfTest(){const e=this.config.logs;let t;return this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: self-test on ${window.location.href}`),t=await this.foundCmp.test()):(e.errors&&console.log("no CMP to self test"),t=!1),this.sendContentMessage({type:"selfTestResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,url:location.href}),this.updateState({selfTest:t}),t}async waitForPopup(e,t=5,o=500){const i=this.config.logs;i.lifecycle&&console.log("checking if popup is open...",e.name);const n=await e.detectPopup().catch((t=>(i.errors&&console.warn(`error detecting popup for ${e.name}`,t),!1)));return!n&&t>0?(await this.domActions.wait(o),this.waitForPopup(e,t-1,o)):(i.lifecycle&&console.log(e.name,"popup is "+(n?"open":"not open")),n)}prehideElements(){const e=this.config.logs,t=this.rules.filter((e=>e.prehideSelectors&&e.checkRunContext())).reduce(((e,t)=>[...e,...t.prehideSelectors]),["#didomi-popup,.didomi-popup-container,.didomi-popup-notice,.didomi-consent-popup-preferences,#didomi-notice,.didomi-popup-backdrop,.didomi-screen-medium"]);return this.updateState({prehideOn:!0}),setTimeout((()=>{this.config.enablePrehide&&this.state.prehideOn&&!["runningOptOut","runningOptIn"].includes(this.state.lifecycle)&&(e.lifecycle&&console.log("Process is taking too long, unhiding elements"),this.undoPrehide())}),this.config.prehideTimeout||2e3),this.domActions.prehide(t.join(","))}undoPrehide(){return this.updateState({prehideOn:!1}),this.domActions.undoPrehide()}async applyCosmeticFilters(e){if(!this.filtersEngine)return!1;const t=this.config?.logs;e||(e=cn(this.filtersEngine)),setTimeout((()=>{if(this.state.cosmeticFiltersOn&&!this.state.filterListReported){this.domActions.elementVisible(rn(e),"any")?(t?.lifecycle&&console.log("Prehide cosmetic filters matched",location.href),this.reportFilterlist()):t?.lifecycle&&console.log("Prehide cosmetic filters didn't match",location.href)}}),1e3),this.updateState({cosmeticFiltersOn:!0});try{this.cosmeticStyleSheet=await this.domActions.createOrUpdateStyleSheet(e,this.cosmeticStyleSheet),t?.lifecycle&&console.log("[cosmetics]",this.cosmeticStyleSheet,location.href),document.adoptedStyleSheets.push(this.cosmeticStyleSheet)}catch(e){return this.config.logs&&console.error("Error applying cosmetic filters",e),!1}return!0}undoCosmetics(){this.updateState({cosmeticFiltersOn:!1}),this.config.logs.lifecycle&&console.log("[undocosmetics]",this.cosmeticStyleSheet,location.href),this.domActions.removeStyleSheet(this.cosmeticStyleSheet)}reportFilterlist(){this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:"filterList"}),this.sendContentMessage({type:"popupFound",cmp:"filterList",url:location.href}),this.updateState({filterListReported:!0})}filterListFallback(){if(!this.filtersEngine)return this.updateState({lifecycle:"nothingDetected"}),!1;const e=cn(this.filtersEngine),t=this.domActions.elementVisible(rn(e),"any"),o=this.config?.logs;return t?(this.applyCosmeticFilters(e),o?.lifecycle&&console.log("Keeping cosmetic filters",location.href),this.updateState({lifecycle:"cosmeticFiltersDetected"}),this.state.filterListReported||this.reportFilterlist(),this.sendContentMessage({type:"optOutResult",cmp:"filterList",result:!0,scheduleSelfTest:!1,url:location.href}),this.updateState({lifecycle:"done"}),this.sendContentMessage({type:"autoconsentDone",cmp:"filterList",isCosmetic:!0,url:location.href}),!0):(o?.lifecycle&&console.log("Cosmetic filters didn't work, removing them",location.href),this.undoCosmetics(),this.updateState({lifecycle:"nothingDetected"}),!1)}updateState(e){Object.assign(this.state,e),this.sendContentMessage({type:"report",instanceId:this.id,url:window.location.href,mainFrame:window.top===window.self,state:this.state})}async receiveMessageCallback(e){const t=this.config?.logs;switch(t?.messages&&console.log("received from background",e,window.location.href),e.type){case"initResp":this.initialize(e.config,e.rules);break;case"optIn":await this.doOptIn();break;case"optOut":await this.doOptOut();break;case"selfTest":await this.doSelfTest();break;case"evalResp":!function(e,t){const o=a.pending.get(e);o?(a.pending.delete(e),o.timer&&window.clearTimeout(o.timer),o.resolve(t)):console.warn("no eval #",e)}(e.id,e.result)}}}((e=>{AutoconsentAndroid.process(JSON.stringify(e))}),null,un);window.autoconsentMessageCallback=e=>{hn.receiveMessageCallback(e)}}(); + */const Ce=new class{constructor(e,t=null,o=null){if(this.id=a(),this.rules=[],this.foundCmp=null,this.state={cosmeticFiltersOn:!1,filterListReported:!1,lifecycle:"loading",prehideOn:!1,findCmpAttempts:0,detectedCmps:[],detectedPopups:[],heuristicPatterns:[],heuristicSnippets:[],selfTest:null},r.sendContentMessage=e,this.sendContentMessage=e,this.rules=[],this.updateState({lifecycle:"loading"}),this.addDynamicRules(),t)this.initialize(t,o);else{o&&this.parseDeclarativeRules(o);e({type:"init",url:window.location.href}),this.updateState({lifecycle:"waitingForInitResponse"})}this.domActions=new C(this)}initialize(e,t){const o=g(e);if(o.logs.lifecycle&&console.log("autoconsent init",window.location.href),this.config=o,o.enabled){if(t&&this.parseDeclarativeRules(t),e.enableFilterList){try{0}catch(e){console.error("Error parsing filter list",e)}"loading"===document.readyState?window.addEventListener("DOMContentLoaded",(()=>{this.applyCosmeticFilters()})):this.applyCosmeticFilters()}if(this.rules=function(e,t){return e.filter((e=>(!t.disabledCmps||!t.disabledCmps.includes(e.name))&&(t.enableCosmeticRules||!e.isCosmetic)))}(this.rules,o),e.enablePrehide)if(document.documentElement)this.prehideElements();else{const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.prehideElements()};window.addEventListener("DOMContentLoaded",e)}if("loading"===document.readyState){const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.start()};window.addEventListener("DOMContentLoaded",e)}else this.start();this.updateState({lifecycle:"initialized"})}else o.logs.lifecycle&&console.log("autoconsent is disabled")}addDynamicRules(){w.forEach((e=>{this.rules.push(new e(this))}))}parseDeclarativeRules(e){e.consentomatic&&Object.keys(e.consentomatic).forEach((t=>{this.addConsentomaticCMP(t,e.consentomatic[t])})),e.autoconsent&&e.autoconsent.forEach((e=>{this.addDeclarativeCMP(e)}))}addDeclarativeCMP(e){this.rules.push(new u(e,this))}addConsentomaticCMP(e,t){this.rules.push(new m(`com_${e}`,t))}start(){!function(e,t=500){globalThis.requestIdleCallback?requestIdleCallback(e,{timeout:t}):setTimeout(e,0)}((()=>this._start()))}async _start(){const e=this.config.logs;e.lifecycle&&console.log(`Detecting CMPs on ${window.location.href}`),this.updateState({lifecycle:"started"});const t=await this.findCmp(this.config.detectRetries);if(this.updateState({detectedCmps:t.map((e=>e.name))}),0===t.length)return e.lifecycle&&console.log("no CMP found",location.href),this.config.enablePrehide&&this.undoPrehide(),this.filterListFallback();this.updateState({lifecycle:"cmpDetected"});const o=[],i=[];for(const e of t)e.isCosmetic?i.push(e):o.push(e);let c=!1,n=await this.detectPopups(o,(async e=>{c=await this.handlePopup(e)}));if(0===n.length&&(n=await this.detectPopups(i,(async e=>{c=await this.handlePopup(e)}))),0===n.length)return e.lifecycle&&console.log("no popup found"),this.config.enablePrehide&&this.undoPrehide(),!1;if(n.length>1){const t={msg:"Found multiple CMPs, check the detection rules.",cmps:n.map((e=>e.name))};e.errors&&console.warn(t.msg,t.cmps),this.sendContentMessage({type:"autoconsentError",details:t})}return c}async findCmp(e){const t=this.config.logs;this.updateState({findCmpAttempts:this.state.findCmpAttempts+1});const o=[];for(const e of this.rules)try{if(!e.checkRunContext())continue;await e.detectCmp()&&(t.lifecycle&&console.log(`Found CMP: ${e.name} ${window.location.href}`),this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:e.name}),o.push(e))}catch(o){t.errors&&console.warn(`error detecting ${e.name}`,o)}return this.detectHeuristics(),0===o.length&&e>0?(await this.domActions.wait(500),this.findCmp(e-1)):o}detectHeuristics(){if(this.config.enableHeuristicDetection){const{patterns:e,snippets:t}=function(){const e=document.documentElement.innerText,t=[],o=[];for(const i of be){const c=e.match(i);c&&(t.push(i.toString()),o.push(...c.map((e=>e.substring(0,200)))))}return{patterns:t,snippets:o}}();e.length>0&&(e.length!==this.state.heuristicPatterns.length||this.state.heuristicPatterns.some(((t,o)=>t!==e[o])))&&(this.config.logs.lifecycle&&console.log("Heuristic patterns found",e,t),this.updateState({heuristicPatterns:e,heuristicSnippets:t}))}}async detectPopup(e){if(await this.waitForPopup(e).catch((t=>(this.config.logs.errors&&console.warn(`error waiting for a popup for ${e.name}`,t),!1))))return this.updateState({detectedPopups:this.state.detectedPopups.concat([e.name])}),this.sendContentMessage({type:"popupFound",cmp:e.name,url:location.href}),e;throw new Error("Popup is not shown")}async detectPopups(e,t){const o=e.map((e=>this.detectPopup(e)));await Promise.any(o).then((e=>{this.detectHeuristics(),t(e)})).catch((()=>null));const i=await Promise.allSettled(o),c=[];for(const e of i)"fulfilled"===e.status&&c.push(e.value);return c}async handlePopup(e){return this.updateState({lifecycle:"openPopupDetected"}),this.config.enablePrehide&&!this.state.prehideOn&&this.prehideElements(),this.state.cosmeticFiltersOn&&this.undoCosmetics(),this.foundCmp=e,"optOut"===this.config.autoAction?await this.doOptOut():"optIn"===this.config.autoAction?await this.doOptIn():(this.config.logs.lifecycle&&console.log("waiting for opt-out signal...",location.href),!0)}async doOptOut(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptOut"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt out on ${window.location.href}`),t=await this.foundCmp.optOut(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt out result ${t}`)):(e.errors&&console.log("no CMP to opt out"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optOutResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:this.foundCmp&&this.foundCmp.hasSelfTest,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optOutSucceeded":"optOutFailed"}),t}async doOptIn(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptIn"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt in on ${window.location.href}`),t=await this.foundCmp.optIn(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt in result ${t}`)):(e.errors&&console.log("no CMP to opt in"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optInResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:!1,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optInSucceeded":"optInFailed"}),t}async doSelfTest(){const e=this.config.logs;let t;return this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: self-test on ${window.location.href}`),t=await this.foundCmp.test()):(e.errors&&console.log("no CMP to self test"),t=!1),this.sendContentMessage({type:"selfTestResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,url:location.href}),this.updateState({selfTest:t}),t}async waitForPopup(e,t=5,o=500){const i=this.config.logs;i.lifecycle&&console.log("checking if popup is open...",e.name);const c=await e.detectPopup().catch((t=>(i.errors&&console.warn(`error detecting popup for ${e.name}`,t),!1)));return!c&&t>0?(await this.domActions.wait(o),this.waitForPopup(e,t-1,o)):(i.lifecycle&&console.log(e.name,"popup is "+(c?"open":"not open")),c)}prehideElements(){const e=this.config.logs,t=this.rules.filter((e=>e.prehideSelectors&&e.checkRunContext())).reduce(((e,t)=>[...e,...t.prehideSelectors]),["#didomi-popup,.didomi-popup-container,.didomi-popup-notice,.didomi-consent-popup-preferences,#didomi-notice,.didomi-popup-backdrop,.didomi-screen-medium"]);return this.updateState({prehideOn:!0}),setTimeout((()=>{this.config.enablePrehide&&this.state.prehideOn&&!["runningOptOut","runningOptIn"].includes(this.state.lifecycle)&&(e.lifecycle&&console.log("Process is taking too long, unhiding elements"),this.undoPrehide())}),this.config.prehideTimeout||2e3),this.domActions.prehide(t.join(","))}undoPrehide(){return this.updateState({prehideOn:!1}),this.domActions.undoPrehide()}async applyCosmeticFilters(e){if(!this.filtersEngine)return!1;const t=this.config?.logs;setTimeout((()=>{if(this.state.cosmeticFiltersOn&&!this.state.filterListReported){const o=this.domActions.elementVisible(function(e){if(e)return e.replace(/\s*{[^\\}]*}\s*/g,",").replace(/,$/,"");return""}(e),"any");o?(t?.lifecycle&&console.log("Prehide cosmetic filters matched",location.href),this.reportFilterlist()):t?.lifecycle&&console.log("Prehide cosmetic filters didn't match",location.href)}}),2e3),this.updateState({cosmeticFiltersOn:!0});try{this.cosmeticStyleSheet=await this.domActions.createOrUpdateStyleSheet(e,this.cosmeticStyleSheet),t?.lifecycle&&console.log("[cosmetics]",this.cosmeticStyleSheet,location.href),document.adoptedStyleSheets.push(this.cosmeticStyleSheet)}catch(e){return this.config.logs&&console.error("Error applying cosmetic filters",e),!1}return!0}undoCosmetics(){this.updateState({cosmeticFiltersOn:!1}),this.config.logs.lifecycle&&console.log("[undocosmetics]",this.cosmeticStyleSheet,location.href),this.domActions.removeStyleSheet(this.cosmeticStyleSheet)}reportFilterlist(){this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:"filterList"}),this.sendContentMessage({type:"popupFound",cmp:"filterList",url:location.href}),this.updateState({filterListReported:!0})}filterListFallback(){return this.updateState({lifecycle:"nothingDetected"}),!1}updateState(e){Object.assign(this.state,e),this.sendContentMessage({type:"report",instanceId:this.id,url:window.location.href,mainFrame:window.top===window.self,state:this.state})}async receiveMessageCallback(e){const t=this.config?.logs;switch(t?.messages&&console.log("received from background",e,window.location.href),e.type){case"initResp":this.initialize(e.config,e.rules);break;case"optIn":await this.doOptIn();break;case"optOut":await this.doOptOut();break;case"selfTest":await this.doSelfTest();break;case"evalResp":!function(e,t){const o=r.pending.get(e);o?(r.pending.delete(e),o.timer&&window.clearTimeout(o.timer),o.resolve(t)):console.warn("no eval #",e)}(e.id,e.result)}}}((e=>{AutoconsentAndroid.process(JSON.stringify(e))}),null,we);window.autoconsentMessageCallback=e=>{Ce.receiveMessageCallback(e)}}(); diff --git a/package-lock.json b/package-lock.json index a4b60833644e..f331e7509a7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "ddg-android", "version": "1.0.0", "dependencies": { - "@duckduckgo/autoconsent": "^12.2.0", + "@duckduckgo/autoconsent": "^12.3.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#15.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", @@ -47,9 +47,9 @@ } }, "node_modules/@duckduckgo/autoconsent": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/@duckduckgo/autoconsent/-/autoconsent-12.2.0.tgz", - "integrity": "sha512-KhvkdhqTHqVxMxxmadWcW9E1WoGV06YIwVC2m8RIeJYk6AD2wIyO5MjP24moRG5OIvWohEhge8TU0OHeY0P6Tw==", + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@duckduckgo/autoconsent/-/autoconsent-12.3.0.tgz", + "integrity": "sha512-mOW11Ve9DRKDkjFtAjXAP3Jd5E22YqI+4+6NTPNnOud2/02QyhM8l1vK//hTR6cmXXWZiFknpuv6qckuwMKivw==", "license": "MPL-2.0", "dependencies": { "@ghostery/adblocker": "^2.0.4", diff --git a/package.json b/package.json index b39182b58080..52aeff559b23 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "rollup-plugin-terser": "^7.0.2" }, "dependencies": { - "@duckduckgo/autoconsent": "^12.2.0", + "@duckduckgo/autoconsent": "^12.3.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#15.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", From 50c92c1dc4b7579fbb3d8b36b94d10baa2412ce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gonz=C3=A1lez?= Date: Tue, 17 Dec 2024 13:47:04 +0100 Subject: [PATCH 09/32] Tab Manager: Origin pixels (#5396) Task/Issue URL: https://app.asana.com/0/1174433894299346/1208763092216879/f ### Description This PR adds an origin to the pixels sent when the tab manage is open ### Steps to test this PR _From SERP_ - [x] Open and and make any search - [x] Open Tab Manager - [x] Verify `m_tab_manager_open_from_serp` is fired _From any site_ - [x] Open and and visit any site - [x] Open Tab Manager - [x] Verify `m_tab_manager_open_from_website` is fired _From new tab_ - [x] Open New Tab - [x] Open Tab Manager - [ ] Verify `m_tab_manager_open_from_newtabpage` is fired --- .../app/browser/BrowserTabViewModelTest.kt | 49 +++++++++++++++++++ .../app/browser/BrowserTabFragment.kt | 1 - .../app/browser/BrowserTabViewModel.kt | 20 +++++++- .../com/duckduckgo/app/pixels/AppPixelName.kt | 3 ++ 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt index f871a63015af..33aac87fab64 100644 --- a/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt +++ b/app/src/androidTest/java/com/duckduckgo/app/browser/BrowserTabViewModelTest.kt @@ -5842,6 +5842,55 @@ class BrowserTabViewModelTest { verify(mockShowOnAppLaunchHandler).handleResolvedUrlStorage(eq("https://example.com"), any(), any()) } + @Test + fun whenTabSwitcherPressedAndUserOnSiteThenPixelIsSent() = runTest { + givenTabManagerData() + setBrowserShowing(true) + val domain = "https://www.example.com" + givenCurrentSite(domain) + + testee.userLaunchingTabSwitcher() + + verify(mockPixel).fire(AppPixelName.TAB_MANAGER_OPENED_FROM_SITE) + } + + @Test + fun whenTabSwitcherPressedAndUserOnSerpThenPixelIsSent() = runTest { + givenTabManagerData() + setBrowserShowing(false) + + testee.userLaunchingTabSwitcher() + + verify(mockPixel).fire(AppPixelName.TAB_MANAGER_OPENED_FROM_NEW_TAB) + } + + @Test + fun whenTabSwitcherPressedAndUserOnNewTabThenPixelIsSent() = runTest { + givenTabManagerData() + setBrowserShowing(true) + whenever(mockDuckDuckGoUrlDetector.isDuckDuckGoUrl(any())).thenReturn(true) + val domain = "https://duckduckgo.com/?q=test&atb=v395-1-wb&ia=web" + givenCurrentSite(domain) + + testee.userLaunchingTabSwitcher() + + verify(mockPixel).fire(AppPixelName.TAB_MANAGER_OPENED_FROM_SERP) + } + + private fun givenTabManagerData() = runTest { + val tabCount = "61-80" + val active7d = "21+" + val inactive1w = "11-20" + val inactive2w = "6-10" + val inactive3w = "0" + + whenever(mockTabStatsBucketing.getNumberOfOpenTabs()).thenReturn(tabCount) + whenever(mockTabStatsBucketing.getTabsActiveLastWeek()).thenReturn(active7d) + whenever(mockTabStatsBucketing.getTabsActiveOneWeekAgo()).thenReturn(inactive1w) + whenever(mockTabStatsBucketing.getTabsActiveTwoWeeksAgo()).thenReturn(inactive2w) + whenever(mockTabStatsBucketing.getTabsActiveMoreThanThreeWeeksAgo()).thenReturn(inactive3w) + } + private fun aCredential(): LoginCredentials { return LoginCredentials(domain = null, username = null, password = null) } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index d0e5ef7f8b14..8e374db5e616 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -907,7 +907,6 @@ class BrowserTabFragment : private fun onOmnibarNewTabRequested() { viewModel.userRequestedOpeningNewTab() - pixel.fire(AppPixelName.MENU_ACTION_NEW_TAB_PRESSED.pixelName) } private fun onOmnibarCustomTabClosed() { diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt index 7b75ddf6853a..4a0e7b4d7797 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt @@ -2633,12 +2633,15 @@ class BrowserTabViewModel @Inject constructor( } } - fun userRequestedOpeningNewTab(longPress: Boolean = false) { + fun userRequestedOpeningNewTab( + longPress: Boolean = false, + ) { command.value = GenerateWebViewPreviewImage command.value = LaunchNewTab if (longPress) { pixel.fire(AppPixelName.TAB_MANAGER_NEW_TAB_LONG_PRESSED) } + onUserDismissedCta(ctaViewState.value?.cta) } @@ -2852,6 +2855,20 @@ class BrowserTabViewModel @Inject constructor( command.value = LaunchTabSwitcher pixel.fire(AppPixelName.TAB_MANAGER_CLICKED) fireDailyLaunchPixel() + + if (!currentBrowserViewState().browserShowing) { + pixel.fire(AppPixelName.TAB_MANAGER_OPENED_FROM_NEW_TAB) + } else { + val url = site?.url + if (url != null) { + if (duckDuckGoUrlDetector.isDuckDuckGoUrl(url)) { + pixel.fire(AppPixelName.TAB_MANAGER_OPENED_FROM_SERP) + } else { + pixel.fire(AppPixelName.TAB_MANAGER_OPENED_FROM_SITE) + } + } + } + onUserDismissedCta(ctaViewState.value?.cta) } @@ -3539,6 +3556,7 @@ class BrowserTabViewModel @Inject constructor( "https://duckduckgo.com/pro?origin=funnel_pro_android_onboarding$cohortOrigin".toUri(), ) } + is DaxBubbleCta.DaxEndCta, is DaxBubbleCta.DaxExperimentEndCta -> { viewModelScope.launch { val updatedCta = refreshCta() diff --git a/app/src/main/java/com/duckduckgo/app/pixels/AppPixelName.kt b/app/src/main/java/com/duckduckgo/app/pixels/AppPixelName.kt index 632bac0f18d4..644bf3f81800 100644 --- a/app/src/main/java/com/duckduckgo/app/pixels/AppPixelName.kt +++ b/app/src/main/java/com/duckduckgo/app/pixels/AppPixelName.kt @@ -351,6 +351,9 @@ enum class AppPixelName(override val pixelName: String) : Pixel.PixelName { TAB_MANAGER_REARRANGE_TABS_DAILY("m_tab_manager_rearrange_tabs_daily"), TAB_MANAGER_GRID_VIEW_BUTTON_CLICKED("m_tab_manager_grid_view_button_clicked"), TAB_MANAGER_LIST_VIEW_BUTTON_CLICKED("m_tab_manager_list_view_button_clicked"), + TAB_MANAGER_OPENED_FROM_SERP("m_tab_manager_open_from_serp"), + TAB_MANAGER_OPENED_FROM_SITE("m_tab_manager_open_from_website"), + TAB_MANAGER_OPENED_FROM_NEW_TAB("m_tab_manager_open_from_newtabpage"), DUCK_PLAYER_SETTING_ALWAYS_OVERLAY_YOUTUBE("duckplayer_setting_always_overlay_youtube"), DUCK_PLAYER_SETTING_ALWAYS_SERP("duckplayer_setting_always_overlay_serp"), From 92f90695064672460815d0ad1c4802f1fd6ed4a7 Mon Sep 17 00:00:00 2001 From: Lukasz Macionczyk Date: Tue, 17 Dec 2024 14:13:04 +0100 Subject: [PATCH 10/32] Fix date format localization in subscription settings (#5399) Task/Issue URL: https://app.asana.com/0/1205648422731273/1208993054177524/f ### Description In subscription settings, we display a date when subscription expires or renews. It is currently using fixed pattern `MMMM dd, yyyy`, which is correct in USA, but potentially confusing or grammatically incorrect in other parts of the world. ### Steps to test this PR QA-optional ### UI changes | Before | After | | ------ | ----- | |![subs-active-date-format-broken](https://github.com/user-attachments/assets/afcc3342-d236-4a92-bc13-2dbf08a4b791)|![subs-active-date-format-fixed](https://github.com/user-attachments/assets/94e64c68-9179-4970-8240-7a29a38532d5)| |![subs-expired-date-format-broken](https://github.com/user-attachments/assets/57c2f37a-599e-415e-a6c4-1683ea2d22c6)|![subs-expired-date-format-fixed](https://github.com/user-attachments/assets/8b2f0f60-8f72-467c-b551-f16b63ebc12e)| --- .../subscriptions/impl/ui/SubscriptionSettingsViewModel.kt | 4 ++-- .../impl/ui/SubscriptionSettingsViewModelTest.kt | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt index d4996344be69..aeec41bb9839 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModel.kt @@ -17,6 +17,7 @@ package com.duckduckgo.subscriptions.impl.ui import android.annotation.SuppressLint +import android.icu.text.DateFormat import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel @@ -37,7 +38,6 @@ import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.Comman import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Monthly import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.SubscriptionDuration.Yearly import com.duckduckgo.subscriptions.impl.ui.SubscriptionSettingsViewModel.ViewState.Ready -import java.text.SimpleDateFormat import java.util.* import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST @@ -83,7 +83,7 @@ class SubscriptionSettingsViewModel @Inject constructor( val account = subscriptionsManager.getAccount() ?: return val subscription = subscriptionsManager.getSubscription() ?: return - val formatter = SimpleDateFormat("MMMM dd, yyyy", Locale.getDefault()) + val formatter = DateFormat.getInstanceForSkeleton("ddMMMMyyyy") val date = formatter.format(Date(subscription.expiresOrRenewsAt)) val type = when (subscription.productId) { MONTHLY_PLAN_US, MONTHLY_PLAN_ROW -> Monthly diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt index 50ed30f9f4cb..89d7953d7043 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionSettingsViewModelTest.kt @@ -1,5 +1,6 @@ package com.duckduckgo.subscriptions.impl.ui +import androidx.test.ext.junit.runners.AndroidJUnit4 import app.cash.turbine.test import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.subscriptions.api.PrivacyProUnifiedFeedback @@ -24,11 +25,13 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith import org.mockito.kotlin.any import org.mockito.kotlin.mock import org.mockito.kotlin.verify import org.mockito.kotlin.whenever +@RunWith(AndroidJUnit4::class) class SubscriptionSettingsViewModelTest { @get:Rule From ac5f7fc5833e5b987232846d2204ee989dfed78c Mon Sep 17 00:00:00 2001 From: Craig Russell Date: Wed, 18 Dec 2024 15:11:35 +0000 Subject: [PATCH 11/32] Wrap maestro UI tests inside a retry command (#5405) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task/Issue URL: https://app.asana.com/0/72649045549333/1209000807402387/f ### Description Wraps Maestro UI tests in a `retry` wrapper to minimize any noise from occasionally flakey tests (either from the test themselves or from flakiness in the testing infrastructure). Where we do spot flakiness in our tests, we should fix them and having the `retry` isn’t a substitute for aiming for properly deterministic tests. By default, all tests are being set with `maxRetries = 3` by default. ### 💡 Tip for reviewing the PR: - each test suite has a `retry` block added, and then the rest of the test steps have been indented. there are, therefore, mostly whitespace-only changes - if you want an easier time in the diff, **Hide whitespace:** Screenshot 2024-12-18 at 12 26 33 ### Steps to test this PR - QA optional - [x] Ensure end-to-end CI job passed: https://github.com/duckduckgo/Android/actions/runs/12392897145 Co-authored-by: Craig Russell <1336281+CDRussell@users.noreply.github.com> --- .github/workflows/end-to-end-robintest.yml | 13 +- ...provided_but_incorrect_dsl_not_needed.yaml | 91 ++--- ...t_a_domain_i.e.,_abcedf_u3_not_needed.yaml | 103 +++--- ...a_domain_i.e.,_abcedf__dsl_not_needed.yaml | 103 +++--- ...www.search-company-site_u3_not_needed.yaml | 103 +++--- ...w.search-company-site__dsl_not_needed.yaml | 103 +++--- ..._domain_param_u3_param_included_1_1_1.yaml | 91 ++--- ...d_domain_param_dsl_param_included_1_1.yaml | 91 ++--- ...omain_param,_but_missing_u3_param_1_1.yaml | 91 ++--- ...main_param,_but_missing_dsl_param_1_1.yaml | 91 ++--- ...ain_provided,_but_empty_u3_not_needed.yaml | 103 +++--- ...in_provided,_but_empty_dsl_not_needed.yaml | 91 ++--- ...ided_ad_domain_provided_u3_not_needed.yaml | 103 +++--- ...ded_ad_domain_provided_dsl_not_needed.yaml | 103 +++--- ..._provided_but_incorrect_u3_not_needed.yaml | 91 ++--- .../1-_design-system-components.yaml | 221 ++++++------ .maestro/app_tp/app_tp_onboarding.yaml | 101 +++--- .maestro/autofill/0_all.yaml | 1 - .../1_autofill_shown_in_overflow.yaml | 11 +- ...tofill_add_search_update_delete_creds.yaml | 198 ++++++----- ...tofill_prompted_to_save_creds_on_form.yaml | 74 ++-- .maestro/autofill/smoke.yaml | 10 +- ...re_bookmarks_can_be_added_and_deleted.yaml | 75 ++-- .../open_bookmark_and_navigate_back.yaml | 85 ++--- ..._bookmark_in_folder_and_navigate_back.yaml | 309 ++++++++-------- .maestro/browsing/visit_site.yaml | 31 +- .../custom_tabs/custom_tabs_navigation.yaml | 123 +++---- .../custom_tabs_navigation_new_tab.yaml | 135 +++---- .../favorites/favorites_bookmarks_add.yaml | 61 ++-- .../favorites/favorites_bookmarks_delete.yaml | 99 +++--- .../fire_button/fire_during_onboarding.yaml | 47 +-- .../1_-_permissions_allowed.yaml | 65 ++-- .../2_-_permissions_denied.yaml | 65 ++-- ...,_utm_source_and_1_standard_parameter.yaml | 33 +- ...Parameters,_utm_source_and_utm_medium.yaml | 33 +- ...d,_fb_source_and_1_standard_parameter.yaml | 33 +- ...s,_link_which_should_not_be_rewritten.yaml | 29 +- .../1_-_Single-site,_single-tab,_session.yaml | 253 ++++++------- .../2_-_Single-site,_new-tab,_session.yaml | 261 +++++++------- ...le-site,_new-tab,_session_variant_two.yaml | 261 +++++++------- .../4_-_Single-site,_multi-tab_session.yaml | 207 +++++------ .../5_-_Multi-site,_single-tab,_session.yaml | 277 ++++++++------- .maestro/privacy_tests/6_-_Multi-tab.yaml | 219 ++++++------ .../7_-_Browser_restart_mid-session.yaml | 267 +++++++------- .../8_-_Navigation_with_back_forward.yaml | 335 +++++++++--------- .../9_-_Navigation_with_refresh.yaml | 287 +++++++-------- .../1_-_AddressBarSpoof,_basicauth.yaml | 77 ++-- .../2_-_AddressBarSpoof,_aboutblank.yaml | 37 +- .../3_-_AddressBarSpoof,_appschemes.yaml | 51 +-- .../4_-_AddressBarSpoof,_b64_html.yaml | 35 +- .../5_-_AddressBarSpoof,_downloadpath.yaml | 61 ++-- .../6_-_AddressBarSpoof,_formaction.yaml | 31 +- .../7_-_AddressBarSpoof,_pagerewrite.yaml | 33 +- .maestro/tabs/open_multiple_tabs.yaml | 91 ++--- 54 files changed, 3078 insertions(+), 2915 deletions(-) diff --git a/.github/workflows/end-to-end-robintest.yml b/.github/workflows/end-to-end-robintest.yml index 95ebd25d3392..94ef3e5ed6a9 100644 --- a/.github/workflows/end-to-end-robintest.yml +++ b/.github/workflows/end-to-end-robintest.yml @@ -115,4 +115,15 @@ jobs: timeout: 120 app-file: apk/release.apk android-api-level: 33 - workspace: .maestro/notifications_permissions_android13_plus \ No newline at end of file + workspace: .maestro/notifications_permissions_android13_plus + + - name: Create Asana task when workflow failed + if: ${{ failure() }} + uses: honeycombio/gha-create-asana-task@main + with: + asana-secret: ${{ secrets.GH_ASANA_SECRET }} + asana-workspace-id: ${{ secrets.GH_ASANA_WORKSPACE_ID }} + asana-project-id: ${{ secrets.GH_ASANA_AOR_PROJECT_ID }} + asana-section-id: ${{ secrets.GH_ASANA_INCOMING_ID }} + asana-task-name: GH Workflow Failure - End to end tests (Robin) + asana-task-description: The end to end workflow has failed. See https://github.com/duckduckgo/Android/actions/runs/${{ github.run_id }} \ No newline at end of file diff --git a/.maestro/ad_click_detection_flows/10_-_m.js_bing-provided_ad_domain_provided_but_incorrect_dsl_not_needed.yaml b/.maestro/ad_click_detection_flows/10_-_m.js_bing-provided_ad_domain_provided_but_incorrect_dsl_not_needed.yaml index 8aec68aa04ea..e6c49caaf34f 100644 --- a/.maestro/ad_click_detection_flows/10_-_m.js_bing-provided_ad_domain_provided_but_incorrect_dsl_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/10_-_m.js_bing-provided_ad_domain_provided_but_incorrect_dsl_not_needed.yaml @@ -2,49 +2,52 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-10" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-10" -- tapOn: - id: "ad-id-10" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" + - inputText: "https://www.search-company.site/#ad-id-10" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-10" + - tapOn: + id: "ad-id-10" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" diff --git a/.maestro/ad_click_detection_flows/11_-_y.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf_u3_not_needed.yaml b/.maestro/ad_click_detection_flows/11_-_y.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf_u3_not_needed.yaml index 3ea65b724986..06c143b08522 100644 --- a/.maestro/ad_click_detection_flows/11_-_y.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf_u3_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/11_-_y.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf_u3_not_needed.yaml @@ -2,55 +2,58 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-11" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-11" -- tapOn: - id: "ad-id-11" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-11" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-11" + - tapOn: + id: "ad-id-11" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/12_-_m.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf__dsl_not_needed.yaml b/.maestro/ad_click_detection_flows/12_-_m.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf__dsl_not_needed.yaml index 60518d18cb23..b280f139a34d 100644 --- a/.maestro/ad_click_detection_flows/12_-_m.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf__dsl_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/12_-_m.js_bing-provided_ad_domain_provided_but_it's_not_a_domain_i.e.,_abcedf__dsl_not_needed.yaml @@ -2,55 +2,58 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-12" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-12" -- tapOn: - id: "ad-id-12" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-12" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-12" + - tapOn: + id: "ad-id-12" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/13_-_y.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site_u3_not_needed.yaml b/.maestro/ad_click_detection_flows/13_-_y.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site_u3_not_needed.yaml index 71a9bb7f7f89..189b6f456f80 100644 --- a/.maestro/ad_click_detection_flows/13_-_y.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site_u3_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/13_-_y.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site_u3_not_needed.yaml @@ -2,55 +2,58 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-13" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-13" -- tapOn: - id: "ad-id-13" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-13" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-13" + - tapOn: + id: "ad-id-13" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/14_-_m.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site__dsl_not_needed.yaml b/.maestro/ad_click_detection_flows/14_-_m.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site__dsl_not_needed.yaml index c56e646d6dfa..ed6052e15c9f 100644 --- a/.maestro/ad_click_detection_flows/14_-_m.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site__dsl_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/14_-_m.js_bing-provided_ad_domain_provided_but_it's_a_subdomain_of_advertiser_i.e.,_foo.www.search-company-site__dsl_not_needed.yaml @@ -2,55 +2,58 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-14" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-14" -- tapOn: - id: "ad-id-14" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-14" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-14" + - tapOn: + id: "ad-id-14" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/1_-_y.js_heuristic_no_ad_domain_param_u3_param_included_1_1_1.yaml b/.maestro/ad_click_detection_flows/1_-_y.js_heuristic_no_ad_domain_param_u3_param_included_1_1_1.yaml index 0ef176c05d60..6ad101d61dda 100644 --- a/.maestro/ad_click_detection_flows/1_-_y.js_heuristic_no_ad_domain_param_u3_param_included_1_1_1.yaml +++ b/.maestro/ad_click_detection_flows/1_-_y.js_heuristic_no_ad_domain_param_u3_param_included_1_1_1.yaml @@ -2,49 +2,52 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-1" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-1" -- tapOn: - id: "ad-id-1" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" + - inputText: "https://www.search-company.site/#ad-id-1" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-1" + - tapOn: + id: "ad-id-1" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" diff --git a/.maestro/ad_click_detection_flows/2_-_m.js_heuristic_no_ad_domain_param_dsl_param_included_1_1.yaml b/.maestro/ad_click_detection_flows/2_-_m.js_heuristic_no_ad_domain_param_dsl_param_included_1_1.yaml index 72a9657fc690..ac61a63644ce 100644 --- a/.maestro/ad_click_detection_flows/2_-_m.js_heuristic_no_ad_domain_param_dsl_param_included_1_1.yaml +++ b/.maestro/ad_click_detection_flows/2_-_m.js_heuristic_no_ad_domain_param_dsl_param_included_1_1.yaml @@ -2,49 +2,52 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-2" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-2" -- tapOn: - id: "ad-id-2" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" + - inputText: "https://www.search-company.site/#ad-id-2" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-2" + - tapOn: + id: "ad-id-2" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" diff --git a/.maestro/ad_click_detection_flows/3_-_y.js_heuristic_no_ad_domain_param,_but_missing_u3_param_1_1.yaml b/.maestro/ad_click_detection_flows/3_-_y.js_heuristic_no_ad_domain_param,_but_missing_u3_param_1_1.yaml index 8602adaf986a..10bc11130b05 100644 --- a/.maestro/ad_click_detection_flows/3_-_y.js_heuristic_no_ad_domain_param,_but_missing_u3_param_1_1.yaml +++ b/.maestro/ad_click_detection_flows/3_-_y.js_heuristic_no_ad_domain_param,_but_missing_u3_param_1_1.yaml @@ -2,49 +2,52 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-3" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-3" -- tapOn: - id: "ad-id-3" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" + - inputText: "https://www.search-company.site/#ad-id-3" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-3" + - tapOn: + id: "ad-id-3" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" diff --git a/.maestro/ad_click_detection_flows/4_-_m.js_heuristic_no_ad_domain_param,_but_missing_dsl_param_1_1.yaml b/.maestro/ad_click_detection_flows/4_-_m.js_heuristic_no_ad_domain_param,_but_missing_dsl_param_1_1.yaml index d01859f75c24..48c76ec862fb 100644 --- a/.maestro/ad_click_detection_flows/4_-_m.js_heuristic_no_ad_domain_param,_but_missing_dsl_param_1_1.yaml +++ b/.maestro/ad_click_detection_flows/4_-_m.js_heuristic_no_ad_domain_param,_but_missing_dsl_param_1_1.yaml @@ -2,49 +2,52 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-4" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-4" -- tapOn: - id: "ad-id-4" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" + - inputText: "https://www.search-company.site/#ad-id-4" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-4" + - tapOn: + id: "ad-id-4" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" diff --git a/.maestro/ad_click_detection_flows/5_-_y.js_heuristic_ad_domain_provided,_but_empty_u3_not_needed.yaml b/.maestro/ad_click_detection_flows/5_-_y.js_heuristic_ad_domain_provided,_but_empty_u3_not_needed.yaml index 77bfcdeb067f..d137ed560575 100644 --- a/.maestro/ad_click_detection_flows/5_-_y.js_heuristic_ad_domain_provided,_but_empty_u3_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/5_-_y.js_heuristic_ad_domain_provided,_but_empty_u3_not_needed.yaml @@ -2,55 +2,58 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/6_-_m.js_heuristic_ad_domain_provided,_but_empty_dsl_not_needed.yaml b/.maestro/ad_click_detection_flows/6_-_m.js_heuristic_ad_domain_provided,_but_empty_dsl_not_needed.yaml index 497894c02606..933a2e9879c5 100644 --- a/.maestro/ad_click_detection_flows/6_-_m.js_heuristic_ad_domain_provided,_but_empty_dsl_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/6_-_m.js_heuristic_ad_domain_provided,_but_empty_dsl_not_needed.yaml @@ -2,49 +2,52 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-6" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-6" -- tapOn: - id: "ad-id-6" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-6" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-6" + - tapOn: + id: "ad-id-6" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/7_-_y.js_bing-provided_ad_domain_provided_u3_not_needed.yaml b/.maestro/ad_click_detection_flows/7_-_y.js_bing-provided_ad_domain_provided_u3_not_needed.yaml index 03c5726d820f..10174331720f 100644 --- a/.maestro/ad_click_detection_flows/7_-_y.js_bing-provided_ad_domain_provided_u3_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/7_-_y.js_bing-provided_ad_domain_provided_u3_not_needed.yaml @@ -2,55 +2,58 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-6" # scroll until the ad-id-6 instead of ad-id-7 (context: https://app.asana.com/0/0/1204397066248823/1204415854211764/f) -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-7" -- tapOn: - id: "ad-id-7" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-6" # scroll until the ad-id-6 instead of ad-id-7 (context: https://app.asana.com/0/0/1204397066248823/1204415854211764/f) + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-7" + - tapOn: + id: "ad-id-7" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/8_-_m.js_bing-provided_ad_domain_provided_dsl_not_needed.yaml b/.maestro/ad_click_detection_flows/8_-_m.js_bing-provided_ad_domain_provided_dsl_not_needed.yaml index 1eed52397431..6498935baa13 100644 --- a/.maestro/ad_click_detection_flows/8_-_m.js_bing-provided_ad_domain_provided_dsl_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/8_-_m.js_bing-provided_ad_domain_provided_dsl_not_needed.yaml @@ -2,55 +2,58 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-8" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-8" -- tapOn: - id: "ad-id-8" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" + - inputText: "https://www.search-company.site/#ad-id-8" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-8" + - tapOn: + id: "ad-id-8" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/ad_click_detection_flows/9_-_y.js_bing-provided_ad_domain_provided_but_incorrect_u3_not_needed.yaml b/.maestro/ad_click_detection_flows/9_-_y.js_bing-provided_ad_domain_provided_but_incorrect_u3_not_needed.yaml index 89f7bd91f795..9b0b6f30f65d 100644 --- a/.maestro/ad_click_detection_flows/9_-_y.js_bing-provided_ad_domain_provided_but_incorrect_u3_not_needed.yaml +++ b/.maestro/ad_click_detection_flows/9_-_y.js_bing-provided_ad_domain_provided_but_incorrect_u3_not_needed.yaml @@ -2,49 +2,52 @@ appId: com.duckduckgo.mobile.android tags: - adClickTest --- -- launchApp: - clearState: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-9" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- tapOn: - text: "Got It" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconMenu" -- tapOn: - text: "Cancel" -- assertVisible: - id: "ad-id-9" -- tapOn: - id: "ad-id-9" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" + - inputText: "https://www.search-company.site/#ad-id-9" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - tapOn: + text: "Got It" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconMenu" + - tapOn: + text: "Cancel" + - assertVisible: + id: "ad-id-9" + - tapOn: + id: "ad-id-9" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" diff --git a/.maestro/ads_preview_flows/1-_design-system-components.yaml b/.maestro/ads_preview_flows/1-_design-system-components.yaml index 33e51feda1df..ecac0f908a7a 100644 --- a/.maestro/ads_preview_flows/1-_design-system-components.yaml +++ b/.maestro/ads_preview_flows/1-_design-system-components.yaml @@ -2,114 +2,117 @@ appId: com.duckduckgo.mobile.android tags: - androidDesignSystemTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "Settings" - index: 0 -- scrollUntilVisible: - element: - text: "Set of components designed following our Design System" - direction: DOWN -- assertVisible: "Set of components designed following our Design System" -- tapOn: "Android Design System Preview" -- assertVisible: "COLOR PALETTE" -- tapOn: "TYPOGRAPHY" -- scrollUntilVisible: - element: - text: "Text Appearance Caption" - direction: DOWN -- tapOn: "BUTTONS" -- tapOn: "Primary Large" -- tapOn: "Secondary Small" -- tapOn: "Destructive Small" -- tapOn: "TEXT INPUT" -- tapOn: "DIALOGS" -- tapOn: "Text Alert Dialog With Image" -- assertVisible: "Keep Using" -- tapOn: "Keep Using" -- tapOn: "Stacked Text Alert Dialog With 4 buttons" -- assertVisible: "Keep Using" -- tapOn: "Keep Using" -- scrollUntilVisible: - element: - text: "Promo Bottom Sheet with image" - direction: DOWN -- tapOn: "Action Bottom Sheet" -- assertVisible: "Primary Item" -- tapOn: "Primary Item" -- tapOn: - id: "com.duckduckgo.mobile.android:id/actionBottomSheetButtonWithTitle" -- tapOn: - id: "com.duckduckgo.mobile.android:id/item_container" - index: 0 -- tapOn: - id: "com.duckduckgo.mobile.android:id/promoBottomSheetButtonWithTitle" -- tapOn: - id: "com.duckduckgo.mobile.android:id/bottomSheetPromoPrimaryButton" -- scrollUntilVisible: - element: - text: "Cookie Consent dialog with animation" - direction: DOWN -- tapOn: - id: "com.duckduckgo.mobile.android:id/animated_button" -- tapOn: - id: "com.duckduckgo.mobile.android:id/primaryCta" -- tapOn: - id: "com.duckduckgo.mobile.android:id/no_hide_button" -- tapOn: - id: "com.duckduckgo.mobile.android:id/primaryCta" -- tapOn: "LAYOUTS" -- assertVisible: "Expandable Layout" -- tapOn: "INTERACTIVE" -- tapOn: - id: "com.duckduckgo.mobile.android:id/dax_switch_one" -- tapOn: - id: "com.duckduckgo.mobile.android:id/radio_button_two" -- tapOn: - id: "com.duckduckgo.mobile.android:id/checkbox_one" -- tapOn: - point: "50%,75%" -- tapOn: "MESSAGING" -- tapOn: - id: "com.duckduckgo.mobile.android:id/close" - index: 0 -- tapOn: - id: "com.duckduckgo.mobile.android:id/close" - index: 0 -- tapOn: - id: "com.duckduckgo.mobile.android:id/close" - index: 0 -- tapOn: - id: "com.duckduckgo.mobile.android:id/secondaryActionButton" - index: 0 -- tapOn: - id: "com.duckduckgo.mobile.android:id/primaryActionButton" - index: 0 -- tapOn: "LIST ITEMS" -- scrollUntilVisible: - element: - text: "With Beta Pill and Switch" - direction: DOWN -- tapOn: "Others" -- scrollUntilVisible: - element: - text: "Enable Dark Theme" - direction: UP -- tapOn: - id: "com.duckduckgo.mobile.android:id/trailingSwitch" -- tapOn: "Typography" -- tapOn: "BUTTONS" -- tapOn: "TEXT INPUT" -- tapOn: "DIALOGS" -- tapOn: "LAYOUTS" -- tapOn: "INTERACTIVE" -- tapOn: "MESSAGING" -- tapOn: "LIST ITEMS" -- tapOn: "OTHERS" \ No newline at end of file + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "Settings" + index: 0 + - scrollUntilVisible: + element: + text: "Set of components designed following our Design System" + direction: DOWN + - assertVisible: "Set of components designed following our Design System" + - tapOn: "Android Design System Preview" + - assertVisible: "COLOR PALETTE" + - tapOn: "TYPOGRAPHY" + - scrollUntilVisible: + element: + text: "Text Appearance Caption" + direction: DOWN + - tapOn: "BUTTONS" + - tapOn: "Primary Large" + - tapOn: "Secondary Small" + - tapOn: "Destructive Small" + - tapOn: "TEXT INPUT" + - tapOn: "DIALOGS" + - tapOn: "Text Alert Dialog With Image" + - assertVisible: "Keep Using" + - tapOn: "Keep Using" + - tapOn: "Stacked Text Alert Dialog With 4 buttons" + - assertVisible: "Keep Using" + - tapOn: "Keep Using" + - scrollUntilVisible: + element: + text: "Promo Bottom Sheet with image" + direction: DOWN + - tapOn: "Action Bottom Sheet" + - assertVisible: "Primary Item" + - tapOn: "Primary Item" + - tapOn: + id: "com.duckduckgo.mobile.android:id/actionBottomSheetButtonWithTitle" + - tapOn: + id: "com.duckduckgo.mobile.android:id/item_container" + index: 0 + - tapOn: + id: "com.duckduckgo.mobile.android:id/promoBottomSheetButtonWithTitle" + - tapOn: + id: "com.duckduckgo.mobile.android:id/bottomSheetPromoPrimaryButton" + - scrollUntilVisible: + element: + text: "Cookie Consent dialog with animation" + direction: DOWN + - tapOn: + id: "com.duckduckgo.mobile.android:id/animated_button" + - tapOn: + id: "com.duckduckgo.mobile.android:id/primaryCta" + - tapOn: + id: "com.duckduckgo.mobile.android:id/no_hide_button" + - tapOn: + id: "com.duckduckgo.mobile.android:id/primaryCta" + - tapOn: "LAYOUTS" + - assertVisible: "Expandable Layout" + - tapOn: "INTERACTIVE" + - tapOn: + id: "com.duckduckgo.mobile.android:id/dax_switch_one" + - tapOn: + id: "com.duckduckgo.mobile.android:id/radio_button_two" + - tapOn: + id: "com.duckduckgo.mobile.android:id/checkbox_one" + - tapOn: + point: "50%,75%" + - tapOn: "MESSAGING" + - tapOn: + id: "com.duckduckgo.mobile.android:id/close" + index: 0 + - tapOn: + id: "com.duckduckgo.mobile.android:id/close" + index: 0 + - tapOn: + id: "com.duckduckgo.mobile.android:id/close" + index: 0 + - tapOn: + id: "com.duckduckgo.mobile.android:id/secondaryActionButton" + index: 0 + - tapOn: + id: "com.duckduckgo.mobile.android:id/primaryActionButton" + index: 0 + - tapOn: "LIST ITEMS" + - scrollUntilVisible: + element: + text: "With Beta Pill and Switch" + direction: DOWN + - tapOn: "Others" + - scrollUntilVisible: + element: + text: "Enable Dark Theme" + direction: UP + - tapOn: + id: "com.duckduckgo.mobile.android:id/trailingSwitch" + - tapOn: "Typography" + - tapOn: "BUTTONS" + - tapOn: "TEXT INPUT" + - tapOn: "DIALOGS" + - tapOn: "LAYOUTS" + - tapOn: "INTERACTIVE" + - tapOn: "MESSAGING" + - tapOn: "LIST ITEMS" + - tapOn: "OTHERS" \ No newline at end of file diff --git a/.maestro/app_tp/app_tp_onboarding.yaml b/.maestro/app_tp/app_tp_onboarding.yaml index 42b5a8151bd8..2a325b35063d 100644 --- a/.maestro/app_tp/app_tp_onboarding.yaml +++ b/.maestro/app_tp/app_tp_onboarding.yaml @@ -3,54 +3,57 @@ name: "ReleaseTest: AppTP onboarding" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "Settings" - index: 0 -- assertVisible: "Block app trackers on your device" -- tapOn: "App Tracking Protection" -- assertVisible: "One easy step for better app privacy!" -- assertVisible: "Continue" -- tapOn: "Continue" -- assertVisible: "How does it work?" -- assertVisible: "Continue" -- tapOn: "Continue" -- assertVisible: "Who sees your data?" -- assertVisible: - text: "Enable App Tracking Protection" - index: 1 -- tapOn: - text: "Enable App Tracking Protection" - index: 1 -- tapOn: - text: "OK" - optional: true -- assertVisible: - text: "Good news! App Tracking Protection is now enabled.*" -- assertVisible: "Got it!" -- tapOn: "Got it!" -- assertVisible: - text: "Protection for some apps is automatically disabled. View apps" - optional: true -- assertVisible: "Blocked tracking attempts will appear here" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/activity_apps" - index: 0 -- assertVisible: - id: "com.duckduckgo.mobile.android:id/activity_apps" - index: 1 -- scroll -- assertVisible: "ABOUT" -- assertVisible: "What are app trackers?" -- assertVisible: "App Tracking Protection FAQ" -- assertVisible: "MANAGE" -- assertVisible: "Having Issues?" -- assertVisible: "View Apps" -- assertVisible: "Disable and Delete Data" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "Settings" + index: 0 + - assertVisible: "Block app trackers on your device" + - tapOn: "App Tracking Protection" + - assertVisible: "One easy step for better app privacy!" + - assertVisible: "Continue" + - tapOn: "Continue" + - assertVisible: "How does it work?" + - assertVisible: "Continue" + - tapOn: "Continue" + - assertVisible: "Who sees your data?" + - assertVisible: + text: "Enable App Tracking Protection" + index: 1 + - tapOn: + text: "Enable App Tracking Protection" + index: 1 + - tapOn: + text: "OK" + optional: true + - assertVisible: + text: "Good news! App Tracking Protection is now enabled.*" + - assertVisible: "Got it!" + - tapOn: "Got it!" + - assertVisible: + text: "Protection for some apps is automatically disabled. View apps" + optional: true + - assertVisible: "Blocked tracking attempts will appear here" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/activity_apps" + index: 0 + - assertVisible: + id: "com.duckduckgo.mobile.android:id/activity_apps" + index: 1 + - scroll + - assertVisible: "ABOUT" + - assertVisible: "What are app trackers?" + - assertVisible: "App Tracking Protection FAQ" + - assertVisible: "MANAGE" + - assertVisible: "Having Issues?" + - assertVisible: "View Apps" + - assertVisible: "Disable and Delete Data" diff --git a/.maestro/autofill/0_all.yaml b/.maestro/autofill/0_all.yaml index cd46b59351b2..8bd58bca9862 100644 --- a/.maestro/autofill/0_all.yaml +++ b/.maestro/autofill/0_all.yaml @@ -6,7 +6,6 @@ name: "Autofill: Run all tests" - launchApp: clearState: true -- runFlow: ../shared/onboarding.yaml - runFlow: 1_autofill_shown_in_overflow.yaml - runFlow: 2_autofill_add_search_update_delete_creds.yaml - runFlow: 3_autofill_prompted_to_save_creds_on_form.yaml \ No newline at end of file diff --git a/.maestro/autofill/1_autofill_shown_in_overflow.yaml b/.maestro/autofill/1_autofill_shown_in_overflow.yaml index ee5e95b38629..62d6ab813204 100644 --- a/.maestro/autofill/1_autofill_shown_in_overflow.yaml +++ b/.maestro/autofill/1_autofill_shown_in_overflow.yaml @@ -5,7 +5,10 @@ tags: --- # Pre-requisite: None (can be run whether auth is required or not) -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- runFlow: steps/access_passwords_screen.yaml \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - runFlow: steps/access_passwords_screen.yaml \ No newline at end of file diff --git a/.maestro/autofill/2_autofill_add_search_update_delete_creds.yaml b/.maestro/autofill/2_autofill_add_search_update_delete_creds.yaml index fb801b37349c..2415ee59d20c 100644 --- a/.maestro/autofill/2_autofill_add_search_update_delete_creds.yaml +++ b/.maestro/autofill/2_autofill_add_search_update_delete_creds.yaml @@ -4,101 +4,103 @@ tags: - autofillNoAuthTests --- # Pre-requisite: on an autofill-eligible device - -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- runFlow: steps/access_passwords_screen.yaml - -- assertVisible: - text: "No passwords saved yet" -- assertNotVisible: - id: searchLogins - -- runScript: steps/2_script.js - -- repeat: - while: - true: ${output.addLogins.counter < output.addLogins.domains.length} - commands: - - tapOn: - id: addLoginManually - - assertVisible: - text: Add Password - - assertNotVisible: - id: view_menu_save - - - scrollUntilVisible: - element: - id: usernameEditText - - tapOn: - id: usernameEditText - - inputText: "user" - - - assertVisible: - id: view_menu_save - - - scrollUntilVisible: - element: - id: passwordEditText - - tapOn: - id: passwordEditText - - inputText: "123" - - - scrollUntilVisible: - element: - id: domainEditText - - tapOn: - id: domainEditText - - inputText: "${output.addLogins.domains[output.addLogins.counter]}" - - - scrollUntilVisible: - element: - id: notesEditText - - tapOn: - id: notesEditText - - inputText: "a note" - - - tapOn: - id: view_menu_save - retryTapIfNoChange: false - - - scrollUntilVisible: - element: - text: "Last updated.*" - - assertVisible: "Last updated.*" - - - tapOn: "Navigate up" - - - assertVisible: - text: "Save and autofill passwords" - - evalScript: ${output.addLogins.counter++} - -- scrollUntilVisible: - element: - text: "#" -- assertVisible: - text: "#" - -- scrollUntilVisible: - element: - text: "a.example.com" -- assertVisible: - text: "a.example.com" - -- assertNotVisible: - text: "https://a.example.com" - -- scrollUntilVisible: - element: - text: "fill.dev" -- assertVisible: - text: "fill.dev" - -- assertNotVisible: - text: "fill.dev/example" - - -- runFlow: steps/search_logins.yaml -- runFlow: steps/manual_update.yaml -- runFlow: steps/delete_logins.yaml \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - runFlow: steps/access_passwords_screen.yaml + + - assertVisible: + text: "No passwords saved yet" + - assertNotVisible: + id: searchLogins + + - runScript: steps/2_script.js + + - repeat: + while: + true: ${output.addLogins.counter < output.addLogins.domains.length} + commands: + - tapOn: + id: addLoginManually + - assertVisible: + text: Add Password + - assertNotVisible: + id: view_menu_save + + - scrollUntilVisible: + element: + id: usernameEditText + - tapOn: + id: usernameEditText + - inputText: "user" + + - assertVisible: + id: view_menu_save + + - scrollUntilVisible: + element: + id: passwordEditText + - tapOn: + id: passwordEditText + - inputText: "123" + + - scrollUntilVisible: + element: + id: domainEditText + - tapOn: + id: domainEditText + - inputText: "${output.addLogins.domains[output.addLogins.counter]}" + + - scrollUntilVisible: + element: + id: notesEditText + - tapOn: + id: notesEditText + - inputText: "a note" + + - tapOn: + id: view_menu_save + retryTapIfNoChange: false + + - scrollUntilVisible: + element: + text: "Last updated.*" + - assertVisible: "Last updated.*" + + - tapOn: "Navigate up" + + - assertVisible: + text: "Save and autofill passwords" + - evalScript: ${output.addLogins.counter++} + + - scrollUntilVisible: + element: + text: "#" + - assertVisible: + text: "#" + + - scrollUntilVisible: + element: + text: "a.example.com" + - assertVisible: + text: "a.example.com" + + - assertNotVisible: + text: "https://a.example.com" + + - scrollUntilVisible: + element: + text: "fill.dev" + - assertVisible: + text: "fill.dev" + + - assertNotVisible: + text: "fill.dev/example" + + + - runFlow: steps/search_logins.yaml + - runFlow: steps/manual_update.yaml + - runFlow: steps/delete_logins.yaml \ No newline at end of file diff --git a/.maestro/autofill/3_autofill_prompted_to_save_creds_on_form.yaml b/.maestro/autofill/3_autofill_prompted_to_save_creds_on_form.yaml index 0c155b33ba97..bf0f7ff7ea66 100644 --- a/.maestro/autofill/3_autofill_prompted_to_save_creds_on_form.yaml +++ b/.maestro/autofill/3_autofill_prompted_to_save_creds_on_form.yaml @@ -4,44 +4,46 @@ tags: - autofillNoAuthTestsModernWebView --- # Pre-requisite: on an autofill-eligible device, including having a modern WebView +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml + - tapOn: + id: "omnibarTextInput" + - eraseText + - inputText: "fill.dev/form/login-simple" + - pressKey: enter -- tapOn: - id: "omnibarTextInput" -- eraseText -- inputText: "fill.dev/form/login-simple" -- pressKey: enter + - tapOn: + text: "Got it" + optional: true -- tapOn: - text: "Got it" - optional: true + - tapOn: + id: "username" + - inputText: "user" + - tapOn: + id: "password" + - inputText: "password1" + - tapOn: + text: "Login" + - assertVisible: "Save Password" + - tapOn: "Save Password" + - pressKey: back + - tapOn: "Close Autofill Dialog" + - tapOn: + id: "password" + - inputText: "password2" + - tapOn: + text: "Login" + - assertVisible: "Update Password" + - tapOn: "Update Password" -- tapOn: - id: "username" -- inputText: "user" -- tapOn: - id: "password" -- inputText: "password1" -- tapOn: - text: "Login" -- assertVisible: "Save Password" -- tapOn: "Save Password" -- pressKey: back -- tapOn: "Close Autofill Dialog" -- tapOn: - id: "password" -- inputText: "password2" -- tapOn: - text: "Login" -- assertVisible: "Update Password" -- tapOn: "Update Password" + - runFlow: steps/access_passwords_screen.yaml -- runFlow: steps/access_passwords_screen.yaml - -- tapOn: "user" -- tapOn: - id: "internal_password_icon" -- assertVisible: "password2" \ No newline at end of file + - tapOn: "user" + - tapOn: + id: "internal_password_icon" + - assertVisible: "password2" \ No newline at end of file diff --git a/.maestro/autofill/smoke.yaml b/.maestro/autofill/smoke.yaml index 18fdc0f7428f..9df1041442e1 100644 --- a/.maestro/autofill/smoke.yaml +++ b/.maestro/autofill/smoke.yaml @@ -3,7 +3,9 @@ name: "ReleaseTest: Autofill screen is reachable from overflow menu" tags: - releaseTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- runFlow: 1_autofill_shown_in_overflow.yaml \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: 1_autofill_shown_in_overflow.yaml \ No newline at end of file diff --git a/.maestro/bookmarks/ensure_bookmarks_can_be_added_and_deleted.yaml b/.maestro/bookmarks/ensure_bookmarks_can_be_added_and_deleted.yaml index a9b2faf1acf8..d2cdc5c0dc21 100644 --- a/.maestro/bookmarks/ensure_bookmarks_can_be_added_and_deleted.yaml +++ b/.maestro/bookmarks/ensure_bookmarks_can_be_added_and_deleted.yaml @@ -3,41 +3,44 @@ name: "ReleaseTest: Bookmarks can be added and deleted" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://privacy-test-pages.site" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "add bookmark" -- tapOn: - text: "add bookmark" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "bookmarks" -- tapOn: - text: "bookmarks" -- assertVisible: - text: "Privacy Test Pages - Home" -- tapOn: - id: "com.duckduckgo.mobile.android:id/trailingIcon" -- assertVisible: - text: "Delete" -- tapOn: - text: "delete" -- assertNotVisible: - text: "Privacy Test Pages - Home" -- assertVisible: - text: "No bookmarks added yet" + - tapOn: + text: "search or type URL" + - inputText: "https://privacy-test-pages.site" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "add bookmark" + - tapOn: + text: "add bookmark" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "bookmarks" + - tapOn: + text: "bookmarks" + - assertVisible: + text: "Privacy Test Pages - Home" + - tapOn: + id: "com.duckduckgo.mobile.android:id/trailingIcon" + - assertVisible: + text: "Delete" + - tapOn: + text: "delete" + - assertNotVisible: + text: "Privacy Test Pages - Home" + - assertVisible: + text: "No bookmarks added yet" diff --git a/.maestro/bookmarks/open_bookmark_and_navigate_back.yaml b/.maestro/bookmarks/open_bookmark_and_navigate_back.yaml index f45e58c04b89..04b0f670df2d 100644 --- a/.maestro/bookmarks/open_bookmark_and_navigate_back.yaml +++ b/.maestro/bookmarks/open_bookmark_and_navigate_back.yaml @@ -3,46 +3,49 @@ name: "ReleaseTest: Bookmark open and back navigation" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://www.search-company.site/" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- assertVisible: - text: "Search engine" -- tapOn: - text: "https://www.search-company.site/" -- inputText: "https://privacy-test-pages.site" -- pressKey: Enter -- assertVisible: - text: "Privacy Test Pages" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "add bookmark" -- tapOn: - text: "add bookmark" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "bookmarks" -- tapOn: - text: "bookmarks" -- assertVisible: - text: "Privacy Test Pages - Home" -- tapOn: - text: "Privacy Test Pages - Home" -- assertVisible: - text: "Privacy Test Pages" -- action: back -- assertVisible: - text: "Search engine" + - tapOn: + text: "search or type URL" + - inputText: "https://www.search-company.site/" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - assertVisible: + text: "Search engine" + - tapOn: + text: "https://www.search-company.site/" + - inputText: "https://privacy-test-pages.site" + - pressKey: Enter + - assertVisible: + text: "Privacy Test Pages" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "add bookmark" + - tapOn: + text: "add bookmark" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "bookmarks" + - tapOn: + text: "bookmarks" + - assertVisible: + text: "Privacy Test Pages - Home" + - tapOn: + text: "Privacy Test Pages - Home" + - assertVisible: + text: "Privacy Test Pages" + - action: back + - assertVisible: + text: "Search engine" diff --git a/.maestro/bookmarks/open_bookmark_in_folder_and_navigate_back.yaml b/.maestro/bookmarks/open_bookmark_in_folder_and_navigate_back.yaml index e04af6151ec1..9a1ffdbf62d2 100644 --- a/.maestro/bookmarks/open_bookmark_in_folder_and_navigate_back.yaml +++ b/.maestro/bookmarks/open_bookmark_in_folder_and_navigate_back.yaml @@ -3,158 +3,161 @@ name: "ReleaseTest: Bookmark open in folder and back navigation" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://privacy-test-pages.site/" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- assertVisible: - text: "Privacy Test Pages" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "add bookmark" -- tapOn: - text: "add bookmark" -- tapOn: - text: "https://privacy-test-pages.site/" -- inputText: "https://www.search-company.site/" -- pressKey: Enter -- assertVisible: - text: "Search engine" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "bookmarks" -- tapOn: - text: "bookmarks" -- assertVisible: - text: "Privacy Test Pages - Home" -- tapOn: - id: "com.duckduckgo.mobile.android:id/trailingIcon" -- assertVisible: - text: "Edit" -- tapOn: - text: "edit" -- assertVisible: - text: "Location" -- assertVisible: - text: "Bookmarks" -- tapOn: - text: "bookmarks" -- assertVisible: - text: "Select Location" -- assertVisible: - text: "Bookmarks" -- tapOn: - id: "com.duckduckgo.mobile.android:id/action_add_folder" -- assertVisible: - text: "Add Folder" -- assertVisible: - text: "Bookmarks" -- tapOn: - id: "com.duckduckgo.mobile.android:id/titleInput" -- inputText: "Folder1" -- tapOn: - id: "com.duckduckgo.mobile.android:id/action_confirm_changes" -- assertVisible: - text: "Select Location" -- assertVisible: - text: "Bookmarks" -- assertVisible: - text: "Folder1" -- tapOn: - text: "Folder1" -- assertVisible: - text: "Edit Bookmark" -- assertVisible: - text: "Folder1" -- tapOn: - text: "Folder1" -- tapOn: - id: "com.duckduckgo.mobile.android:id/action_add_folder" -- assertVisible: - text: "Add Folder" -- assertVisible: - text: "Bookmarks" -- inputText: "Folder2" -- tapOn: - text: "Bookmarks" -- assertVisible: - text: "Select Location" -- assertVisible: - text: "Bookmarks" -- assertVisible: - text: "Folder1" -- tapOn: - text: "Folder1" -- assertVisible: - text: "Add Folder" -- assertVisible: - text: "Folder2" -- assertVisible: - text: "Folder1" -- tapOn: - id: "com.duckduckgo.mobile.android:id/action_confirm_changes" -- assertVisible: - text: "Select Location" -- assertVisible: - text: "Bookmarks" -- assertVisible: - text: "Folder1" -- tapOn: - text: "Folder1" -- assertVisible: - text: "Edit Bookmark" -- assertVisible: - text: "Folder1" -- tapOn: - text: "Folder1" -- assertVisible: - text: "Select Location" -- assertVisible: - text: "Folder1" -- assertVisible: - text: "Folder2" -- tapOn: - text: "Folder2" -- assertVisible: - text: "Edit Bookmark" -- assertVisible: - text: "Folder2" -- tapOn: - id: "com.duckduckgo.mobile.android:id/action_confirm_changes" -- assertVisible: - text: "Bookmarks" -- assertVisible: - text: "Folder1" -- assertNotVisible: - text: "Privacy Test Pages - Home" -- tapOn: - text: "Folder1" -- assertVisible: - text: "Folder2" -- tapOn: - text: "Folder1" -- assertVisible: - text: "Folder2" -- tapOn: - text: "Folder2" -- assertVisible: - text: "Privacy Test Pages - Home" -- tapOn: - text: "Privacy Test Pages - Home" -- assertVisible: - text: "Privacy Test Pages" -- action: back -- assertVisible: - text: "Search engine" + - tapOn: + text: "search or type URL" + - inputText: "https://privacy-test-pages.site/" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - assertVisible: + text: "Privacy Test Pages" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "add bookmark" + - tapOn: + text: "add bookmark" + - tapOn: + text: "https://privacy-test-pages.site/" + - inputText: "https://www.search-company.site/" + - pressKey: Enter + - assertVisible: + text: "Search engine" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "bookmarks" + - tapOn: + text: "bookmarks" + - assertVisible: + text: "Privacy Test Pages - Home" + - tapOn: + id: "com.duckduckgo.mobile.android:id/trailingIcon" + - assertVisible: + text: "Edit" + - tapOn: + text: "edit" + - assertVisible: + text: "Location" + - assertVisible: + text: "Bookmarks" + - tapOn: + text: "bookmarks" + - assertVisible: + text: "Select Location" + - assertVisible: + text: "Bookmarks" + - tapOn: + id: "com.duckduckgo.mobile.android:id/action_add_folder" + - assertVisible: + text: "Add Folder" + - assertVisible: + text: "Bookmarks" + - tapOn: + id: "com.duckduckgo.mobile.android:id/titleInput" + - inputText: "Folder1" + - tapOn: + id: "com.duckduckgo.mobile.android:id/action_confirm_changes" + - assertVisible: + text: "Select Location" + - assertVisible: + text: "Bookmarks" + - assertVisible: + text: "Folder1" + - tapOn: + text: "Folder1" + - assertVisible: + text: "Edit Bookmark" + - assertVisible: + text: "Folder1" + - tapOn: + text: "Folder1" + - tapOn: + id: "com.duckduckgo.mobile.android:id/action_add_folder" + - assertVisible: + text: "Add Folder" + - assertVisible: + text: "Bookmarks" + - inputText: "Folder2" + - tapOn: + text: "Bookmarks" + - assertVisible: + text: "Select Location" + - assertVisible: + text: "Bookmarks" + - assertVisible: + text: "Folder1" + - tapOn: + text: "Folder1" + - assertVisible: + text: "Add Folder" + - assertVisible: + text: "Folder2" + - assertVisible: + text: "Folder1" + - tapOn: + id: "com.duckduckgo.mobile.android:id/action_confirm_changes" + - assertVisible: + text: "Select Location" + - assertVisible: + text: "Bookmarks" + - assertVisible: + text: "Folder1" + - tapOn: + text: "Folder1" + - assertVisible: + text: "Edit Bookmark" + - assertVisible: + text: "Folder1" + - tapOn: + text: "Folder1" + - assertVisible: + text: "Select Location" + - assertVisible: + text: "Folder1" + - assertVisible: + text: "Folder2" + - tapOn: + text: "Folder2" + - assertVisible: + text: "Edit Bookmark" + - assertVisible: + text: "Folder2" + - tapOn: + id: "com.duckduckgo.mobile.android:id/action_confirm_changes" + - assertVisible: + text: "Bookmarks" + - assertVisible: + text: "Folder1" + - assertNotVisible: + text: "Privacy Test Pages - Home" + - tapOn: + text: "Folder1" + - assertVisible: + text: "Folder2" + - tapOn: + text: "Folder1" + - assertVisible: + text: "Folder2" + - tapOn: + text: "Folder2" + - assertVisible: + text: "Privacy Test Pages - Home" + - tapOn: + text: "Privacy Test Pages - Home" + - assertVisible: + text: "Privacy Test Pages" + - action: back + - assertVisible: + text: "Search engine" diff --git a/.maestro/browsing/visit_site.yaml b/.maestro/browsing/visit_site.yaml index 3044962deb83..8461b797a5c9 100644 --- a/.maestro/browsing/visit_site.yaml +++ b/.maestro/browsing/visit_site.yaml @@ -3,19 +3,22 @@ name: "ReleaseTest: General website browsing works" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://privacy-test-pages.site" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- assertVisible: - text: ".*Privacy Test Pages.*" + - tapOn: + text: "search or type URL" + - inputText: "https://privacy-test-pages.site" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - assertVisible: + text: ".*Privacy Test Pages.*" diff --git a/.maestro/custom_tabs/custom_tabs_navigation.yaml b/.maestro/custom_tabs/custom_tabs_navigation.yaml index b17a0c86cca7..d5afd2b94886 100644 --- a/.maestro/custom_tabs/custom_tabs_navigation.yaml +++ b/.maestro/custom_tabs/custom_tabs_navigation.yaml @@ -3,66 +3,69 @@ name: "Custom Tabs navigation" tags: - customTabsTest --- -- launchApp: - clearState: true - stopApp: true - -- assertVisible: - text: ".*Ready for a better, more private internet?.*" -- tapOn: "let's do it!" -- assertVisible: - text: ".*Privacy protections activated.*" -- tapOn: "choose your browser" -- runFlow: - when: - visible: "set as default" +- retry: + maxRetries: 3 commands: - - tapOn: "duckduckgo" - - tapOn: "set as default" + - launchApp: + clearState: true + stopApp: true + + - assertVisible: + text: ".*Ready for a better, more private internet?.*" + - tapOn: "let's do it!" - assertVisible: - text: ".*Awesome! Welcome to the duck side.*" - - tapOn: "start browsing" + text: ".*Privacy protections activated.*" + - tapOn: "choose your browser" + - runFlow: + when: + visible: "set as default" + commands: + - tapOn: "duckduckgo" + - tapOn: "set as default" + - assertVisible: + text: ".*Awesome! Welcome to the duck side.*" + - tapOn: "start browsing" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "settings" -- scrollUntilVisible: - element: - text: "developer settings" - direction: DOWN -- tapOn: - text: "developer settings" -- scrollUntilVisible: - element: - text: "custom tabs" - direction: DOWN -- tapOn: - text: "custom tabs" -- tapOn: - text: "add your url here" -- inputText: "https://www.search-company.site" -- tapOn: - text: "load custom tab" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "running in duckduckgo" -- action: back -- tapOn: - text: "[Ad 1] SERP Ad (heuristic)" -- action: back -- tapOn: - text: "[Ad 1] SERP Ad (heuristic)" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - id: "com.duckduckgo.mobile.android:id/backMenuItem" -- assertVisible: - text: "Search engine" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - id: "com.duckduckgo.mobile.android:id/forwardMenuItem" -- assertVisible: - text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "settings" + - scrollUntilVisible: + element: + text: "developer settings" + direction: DOWN + - tapOn: + text: "developer settings" + - scrollUntilVisible: + element: + text: "custom tabs" + direction: DOWN + - tapOn: + text: "custom tabs" + - tapOn: + text: "add your url here" + - inputText: "https://www.search-company.site" + - tapOn: + text: "load custom tab" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "running in duckduckgo" + - action: back + - tapOn: + text: "[Ad 1] SERP Ad (heuristic)" + - action: back + - tapOn: + text: "[Ad 1] SERP Ad (heuristic)" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + id: "com.duckduckgo.mobile.android:id/backMenuItem" + - assertVisible: + text: "Search engine" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + id: "com.duckduckgo.mobile.android:id/forwardMenuItem" + - assertVisible: + text: "Publisher site" diff --git a/.maestro/custom_tabs/custom_tabs_navigation_new_tab.yaml b/.maestro/custom_tabs/custom_tabs_navigation_new_tab.yaml index 84bb91b15edf..4e17baef3c1a 100644 --- a/.maestro/custom_tabs/custom_tabs_navigation_new_tab.yaml +++ b/.maestro/custom_tabs/custom_tabs_navigation_new_tab.yaml @@ -3,72 +3,75 @@ name: "Custom Tabs navigation in new tab" tags: - customTabsTest --- -- launchApp: - clearState: true - stopApp: true - -- assertVisible: - text: ".*Ready for a better, more private internet?.*" -- tapOn: "let's do it!" -- assertVisible: - text: ".*Privacy protections activated.*" -- tapOn: "choose your browser" -- runFlow: - when: - visible: "set as default" +- retry: + maxRetries: 3 commands: - - tapOn: "duckduckgo" - - tapOn: "set as default" + - launchApp: + clearState: true + stopApp: true + - assertVisible: - text: ".*Awesome! Welcome to the duck side.*" - - tapOn: "start browsing" + text: ".*Ready for a better, more private internet?.*" + - tapOn: "let's do it!" + - assertVisible: + text: ".*Privacy protections activated.*" + - tapOn: "choose your browser" + - runFlow: + when: + visible: "set as default" + commands: + - tapOn: "duckduckgo" + - tapOn: "set as default" + - assertVisible: + text: ".*Awesome! Welcome to the duck side.*" + - tapOn: "start browsing" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "settings" -- scrollUntilVisible: - element: - text: "developer settings" - direction: DOWN -- tapOn: - text: "developer settings" -- scrollUntilVisible: - element: - text: "custom tabs" - direction: DOWN -- tapOn: - text: "custom tabs" -- tapOn: - text: "add your url here" -- inputText: "https://www.search-company.site" -- tapOn: - text: "load custom tab" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "running in duckduckgo" -- action: back -- tapOn: - text: "[Ad 2] Shopping Tab Ad (heuristic)" -- assertVisible: - text: "Publisher site" -- action: back -- tapOn: - text: "[Ad 2] Shopping Tab Ad (heuristic)" -- tapOn: - text: "Red shoes" -- assertVisible: - text: "Checkout" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - id: "com.duckduckgo.mobile.android:id/backMenuItem" -- assertVisible: - text: "Red shoes" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - id: "com.duckduckgo.mobile.android:id/forwardMenuItem" -- assertVisible: - text: "Checkout" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "settings" + - scrollUntilVisible: + element: + text: "developer settings" + direction: DOWN + - tapOn: + text: "developer settings" + - scrollUntilVisible: + element: + text: "custom tabs" + direction: DOWN + - tapOn: + text: "custom tabs" + - tapOn: + text: "add your url here" + - inputText: "https://www.search-company.site" + - tapOn: + text: "load custom tab" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "running in duckduckgo" + - action: back + - tapOn: + text: "[Ad 2] Shopping Tab Ad (heuristic)" + - assertVisible: + text: "Publisher site" + - action: back + - tapOn: + text: "[Ad 2] Shopping Tab Ad (heuristic)" + - tapOn: + text: "Red shoes" + - assertVisible: + text: "Checkout" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + id: "com.duckduckgo.mobile.android:id/backMenuItem" + - assertVisible: + text: "Red shoes" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + id: "com.duckduckgo.mobile.android:id/forwardMenuItem" + - assertVisible: + text: "Checkout" diff --git a/.maestro/favorites/favorites_bookmarks_add.yaml b/.maestro/favorites/favorites_bookmarks_add.yaml index 85bb8ce36f63..42963e457186 100644 --- a/.maestro/favorites/favorites_bookmarks_add.yaml +++ b/.maestro/favorites/favorites_bookmarks_add.yaml @@ -3,34 +3,37 @@ name: "ReleaseTest: Can add favorite from bookmark screen" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://privacy-test-pages.site" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "add bookmark" -# Navigate to bookmarks screen -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "bookmarks" -# Add favorite from bookmarks screen -- tapOn: - id: "com.duckduckgo.mobile.android:id/trailingIcon" - index: 0 -- tapOn: - text: "add to favorites" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/favoriteStar" + - tapOn: + text: "search or type URL" + - inputText: "https://privacy-test-pages.site" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "add bookmark" + # Navigate to bookmarks screen + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "bookmarks" + # Add favorite from bookmarks screen + - tapOn: + id: "com.duckduckgo.mobile.android:id/trailingIcon" + index: 0 + - tapOn: + text: "add to favorites" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/favoriteStar" diff --git a/.maestro/favorites/favorites_bookmarks_delete.yaml b/.maestro/favorites/favorites_bookmarks_delete.yaml index cee02049cbbd..8fc03e3f8d10 100644 --- a/.maestro/favorites/favorites_bookmarks_delete.yaml +++ b/.maestro/favorites/favorites_bookmarks_delete.yaml @@ -3,53 +3,56 @@ name: "ReleaseTest: Deleting a favorite does not delete bookmark" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://privacy-test-pages.site" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "add bookmark" -- tapOn: - text: "add bookmark" -# Add favorite from edit saved site -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "edit bookmark" -- tapOn: - text: "edit bookmark" -- assertVisible: - text: "add to favorites" -- tapOn: - text: "add to favorites" -- tapOn: - id: "com.duckduckgo.mobile.android:id/action_confirm_changes" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- assertVisible: - text: "bookmarks" -- tapOn: - text: "bookmarks" -# Remove favorite from bookmarks screen -- tapOn: - id: "com.duckduckgo.mobile.android:id/trailingIcon" - index: 0 -- assertVisible: - text: "remove from favorites" -- tapOn: - text: "remove from favorites" -# When a favorite is removed, it still stays as Bookmark -- assertVisible: - text: "Privacy Test Pages - Home" + - tapOn: + text: "search or type URL" + - inputText: "https://privacy-test-pages.site" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "add bookmark" + - tapOn: + text: "add bookmark" + # Add favorite from edit saved site + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "edit bookmark" + - tapOn: + text: "edit bookmark" + - assertVisible: + text: "add to favorites" + - tapOn: + text: "add to favorites" + - tapOn: + id: "com.duckduckgo.mobile.android:id/action_confirm_changes" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - assertVisible: + text: "bookmarks" + - tapOn: + text: "bookmarks" + # Remove favorite from bookmarks screen + - tapOn: + id: "com.duckduckgo.mobile.android:id/trailingIcon" + index: 0 + - assertVisible: + text: "remove from favorites" + - tapOn: + text: "remove from favorites" + # When a favorite is removed, it still stays as Bookmark + - assertVisible: + text: "Privacy Test Pages - Home" diff --git a/.maestro/fire_button/fire_during_onboarding.yaml b/.maestro/fire_button/fire_during_onboarding.yaml index 2d8f970f9c9d..59b0b6e1328e 100644 --- a/.maestro/fire_button/fire_during_onboarding.yaml +++ b/.maestro/fire_button/fire_during_onboarding.yaml @@ -3,27 +3,30 @@ name: "ReleaseTest: Fire button is working" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://privacy-test-pages.site" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- assertVisible: - text: ".*browsing activity with the fire button.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconImageView" -- tapOn: "Cancel" -- assertNotVisible: ".*browsing activity with the Fire Button.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/fireIconImageView" -- tapOn: "Clear All Tabs And Data" -- assertVisible: "You've got this!.*" \ No newline at end of file + - tapOn: + text: "search or type URL" + - inputText: "https://privacy-test-pages.site" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - assertVisible: + text: ".*browsing activity with the fire button.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconImageView" + - tapOn: "Cancel" + - assertNotVisible: ".*browsing activity with the Fire Button.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/fireIconImageView" + - tapOn: "Clear All Tabs And Data" + - assertVisible: "You've got this!.*" \ No newline at end of file diff --git a/.maestro/notifications_permissions_android13_plus/1_-_permissions_allowed.yaml b/.maestro/notifications_permissions_android13_plus/1_-_permissions_allowed.yaml index e77d22ea7d72..9a9965f1add2 100644 --- a/.maestro/notifications_permissions_android13_plus/1_-_permissions_allowed.yaml +++ b/.maestro/notifications_permissions_android13_plus/1_-_permissions_allowed.yaml @@ -1,33 +1,36 @@ appId: com.duckduckgo.mobile.android --- -- launchApp: - clearState: true - stopApp: true - permissions: { all: unset } -- assertVisible: - text: ".*Allow DuckDuckGo to send you notifications.*" -- tapOn: "Allow" -- assertVisible: - text: ".*Welcome to DuckDuckGo!.*" - optional: true -- assertVisible: - text: ".*Ready for a better, more private internet?.*" -- tapOn: "let's do it!" -- assertVisible: - text: ".*Privacy protections activated.*" -- tapOn: "choose your browser" -- tapOn: "cancel" -- assertVisible: - text: ".*Try a search!.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "Downloads" -- assertVisible: - text: ".*No files downloaded yet.*" -- assertNotVisible: - text: ".*Find out when downloads are ready.*" -- assertNotVisible: - text: ".*Get a notification when downloads complete.*" -- assertNotVisible: - text: ".*Notify Me.*" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true + permissions: { all: unset } + - assertVisible: + text: ".*Allow DuckDuckGo to send you notifications.*" + - tapOn: "Allow" + - assertVisible: + text: ".*Welcome to DuckDuckGo!.*" + optional: true + - assertVisible: + text: ".*Ready for a better, more private internet?.*" + - tapOn: "let's do it!" + - assertVisible: + text: ".*Privacy protections activated.*" + - tapOn: "choose your browser" + - tapOn: "cancel" + - assertVisible: + text: ".*Try a search!.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "Downloads" + - assertVisible: + text: ".*No files downloaded yet.*" + - assertNotVisible: + text: ".*Find out when downloads are ready.*" + - assertNotVisible: + text: ".*Get a notification when downloads complete.*" + - assertNotVisible: + text: ".*Notify Me.*" diff --git a/.maestro/notifications_permissions_android13_plus/2_-_permissions_denied.yaml b/.maestro/notifications_permissions_android13_plus/2_-_permissions_denied.yaml index fa3f2d62cdb2..008508a86bc7 100644 --- a/.maestro/notifications_permissions_android13_plus/2_-_permissions_denied.yaml +++ b/.maestro/notifications_permissions_android13_plus/2_-_permissions_denied.yaml @@ -1,33 +1,36 @@ appId: com.duckduckgo.mobile.android --- -- launchApp: - clearState: true - stopApp: true - permissions: { all: unset } -- assertVisible: - text: ".*Allow DuckDuckGo to send you notifications.*" -- tapOn: "Don’t allow" -- assertVisible: - text: ".*Welcome to DuckDuckGo!.*" - optional: true -- assertVisible: - text: ".*Ready for a better, more private internet?.*" -- tapOn: "let's do it!" -- assertVisible: - text: ".*Privacy protections activated.*" -- tapOn: "choose your browser" -- tapOn: "cancel" -- assertVisible: - text: ".*Try a search!.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenuImageView" -- tapOn: - text: "Downloads" -- assertVisible: - text: ".*Find out when downloads are ready.*" -- assertVisible: - text: ".*Get a notification when downloads complete.*" -- assertVisible: - text: ".*Notify Me.*" -- assertVisible: - text: ".*No files downloaded yet.*" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true + permissions: { all: unset } + - assertVisible: + text: ".*Allow DuckDuckGo to send you notifications.*" + - tapOn: "Don’t allow" + - assertVisible: + text: ".*Welcome to DuckDuckGo!.*" + optional: true + - assertVisible: + text: ".*Ready for a better, more private internet?.*" + - tapOn: "let's do it!" + - assertVisible: + text: ".*Privacy protections activated.*" + - tapOn: "choose your browser" + - tapOn: "cancel" + - assertVisible: + text: ".*Try a search!.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenuImageView" + - tapOn: + text: "Downloads" + - assertVisible: + text: ".*Find out when downloads are ready.*" + - assertVisible: + text: ".*Get a notification when downloads complete.*" + - assertVisible: + text: ".*Notify Me.*" + - assertVisible: + text: ".*No files downloaded yet.*" diff --git a/.maestro/privacy_tests/10_-_Query_Parameters,_utm_source_and_1_standard_parameter.yaml b/.maestro/privacy_tests/10_-_Query_Parameters,_utm_source_and_1_standard_parameter.yaml index b9fdf8a9c1ef..17225ccd08fb 100644 --- a/.maestro/privacy_tests/10_-_Query_Parameters,_utm_source_and_1_standard_parameter.yaml +++ b/.maestro/privacy_tests/10_-_Query_Parameters,_utm_source_and_1_standard_parameter.yaml @@ -2,18 +2,21 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - text: "Link with utm_source and 1 standard parameter" -- tapOn: - text: "Link with utm_source and 1 standard parameter" -- assertNotVisible: - text: "utm_source=something&q=other" -- assertVisible: - text: "q=other" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + text: "Link with utm_source and 1 standard parameter" + - tapOn: + text: "Link with utm_source and 1 standard parameter" + - assertNotVisible: + text: "utm_source=something&q=other" + - assertVisible: + text: "q=other" diff --git a/.maestro/privacy_tests/11_-_Query_Parameters,_utm_source_and_utm_medium.yaml b/.maestro/privacy_tests/11_-_Query_Parameters,_utm_source_and_utm_medium.yaml index cf82b9c50670..9f66b053755c 100644 --- a/.maestro/privacy_tests/11_-_Query_Parameters,_utm_source_and_utm_medium.yaml +++ b/.maestro/privacy_tests/11_-_Query_Parameters,_utm_source_and_utm_medium.yaml @@ -2,18 +2,21 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - text: "Link with utm_source and utm_medium" -- tapOn: - text: "Link with utm_source and utm_medium" -- assertNotVisible: - text: "utm_source=something&utm_medium=somethingelse" -- assertVisible: - text: "" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + text: "Link with utm_source and utm_medium" + - tapOn: + text: "Link with utm_source and utm_medium" + - assertNotVisible: + text: "utm_source=something&utm_medium=somethingelse" + - assertVisible: + text: "" diff --git a/.maestro/privacy_tests/12_-_Query_Parameters,_fbclid,_fb_source_and_1_standard_parameter.yaml b/.maestro/privacy_tests/12_-_Query_Parameters,_fbclid,_fb_source_and_1_standard_parameter.yaml index 4f83e6a142f4..c3018a63ee25 100644 --- a/.maestro/privacy_tests/12_-_Query_Parameters,_fbclid,_fb_source_and_1_standard_parameter.yaml +++ b/.maestro/privacy_tests/12_-_Query_Parameters,_fbclid,_fb_source_and_1_standard_parameter.yaml @@ -2,18 +2,21 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - text: "Link with fbclid, fb_source and 1 standard parameter" -- tapOn: - text: "Link with fbclid, fb_source and 1 standard parameter" -- assertNotVisible: - text: "fbclid=12345&fb_source=someting&u=14" -- assertVisible: - text: "u=14" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + text: "Link with fbclid, fb_source and 1 standard parameter" + - tapOn: + text: "Link with fbclid, fb_source and 1 standard parameter" + - assertNotVisible: + text: "fbclid=12345&fb_source=someting&u=14" + - assertVisible: + text: "u=14" diff --git a/.maestro/privacy_tests/13_-_Query_Parameters,_link_which_should_not_be_rewritten.yaml b/.maestro/privacy_tests/13_-_Query_Parameters,_link_which_should_not_be_rewritten.yaml index b13c29934dd9..6b6e117dda4f 100644 --- a/.maestro/privacy_tests/13_-_Query_Parameters,_link_which_should_not_be_rewritten.yaml +++ b/.maestro/privacy_tests/13_-_Query_Parameters,_link_which_should_not_be_rewritten.yaml @@ -2,16 +2,19 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - text: "Link which should not be rewritten" -- tapOn: - text: "Link which should not be rewritten" -- assertVisible: - text: "q=something&id=1234" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://privacy-test-pages.site/privacy-protections/query-parameters/" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + text: "Link which should not be rewritten" + - tapOn: + text: "Link which should not be rewritten" + - assertVisible: + text: "q=something&id=1234" diff --git a/.maestro/privacy_tests/1_-_Single-site,_single-tab,_session.yaml b/.maestro/privacy_tests/1_-_Single-site,_single-tab,_session.yaml index ed353acc275f..19703901f808 100644 --- a/.maestro/privacy_tests/1_-_Single-site,_single-tab,_session.yaml +++ b/.maestro/privacy_tests/1_-_Single-site,_single-tab,_session.yaml @@ -2,130 +2,133 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Checkout" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- assertVisible: - text: ".*Order complete.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Checkout" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - assertVisible: + text: ".*Order complete.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - diff --git a/.maestro/privacy_tests/2_-_Single-site,_new-tab,_session.yaml b/.maestro/privacy_tests/2_-_Single-site,_new-tab,_session.yaml index 513cde79094d..f8b8dce37f0a 100644 --- a/.maestro/privacy_tests/2_-_Single-site,_new-tab,_session.yaml +++ b/.maestro/privacy_tests/2_-_Single-site,_new-tab,_session.yaml @@ -2,134 +2,137 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- longPressOn: - id: "ad-id-5" -- assertVisible: - text: "Open in New Tab" -- tapOn: - text: "Open in New Tab" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Checkout" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- assertVisible: - text: ".*Order complete.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - longPressOn: + id: "ad-id-5" + - assertVisible: + text: "Open in New Tab" + - tapOn: + text: "Open in New Tab" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Checkout" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - assertVisible: + text: ".*Order complete.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - diff --git a/.maestro/privacy_tests/3_-_Single-site,_new-tab,_session_variant_two.yaml b/.maestro/privacy_tests/3_-_Single-site,_new-tab,_session_variant_two.yaml index 3df9866959f8..24ec2787fb4c 100644 --- a/.maestro/privacy_tests/3_-_Single-site,_new-tab,_session_variant_two.yaml +++ b/.maestro/privacy_tests/3_-_Single-site,_new-tab,_session_variant_two.yaml @@ -2,134 +2,137 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- longPressOn: - id: "buy-now" -- assertVisible: - text: "Open in New Tab" -- tapOn: - text: "Open in New Tab" -- assertVisible: - text: "Checkout" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- assertVisible: - text: ".*Order complete.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - longPressOn: + id: "buy-now" + - assertVisible: + text: "Open in New Tab" + - tapOn: + text: "Open in New Tab" + - assertVisible: + text: "Checkout" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - assertVisible: + text: ".*Order complete.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - diff --git a/.maestro/privacy_tests/4_-_Single-site,_multi-tab_session.yaml b/.maestro/privacy_tests/4_-_Single-site,_multi-tab_session.yaml index 7d1cf8490672..1e36751d2c7e 100644 --- a/.maestro/privacy_tests/4_-_Single-site,_multi-tab_session.yaml +++ b/.maestro/privacy_tests/4_-_Single-site,_multi-tab_session.yaml @@ -2,107 +2,110 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Publisher site" -- tapOn: - text: "Publisher site" -- assertVisible: - text: "Green T-shirt" -- assertVisible: - id: "product-link-1" -- tapOn: - id: "product-link-1" -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Pay" -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- assertVisible: - text: ".*Order complete.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Publisher site" + - tapOn: + text: "Publisher site" + - assertVisible: + text: "Green T-shirt" + - assertVisible: + id: "product-link-1" + - tapOn: + id: "product-link-1" + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Pay" + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - assertVisible: + text: ".*Order complete.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - diff --git a/.maestro/privacy_tests/5_-_Multi-site,_single-tab,_session.yaml b/.maestro/privacy_tests/5_-_Multi-site,_single-tab,_session.yaml index 8b82d4288268..5dde49b144ea 100644 --- a/.maestro/privacy_tests/5_-_Multi-site,_single-tab,_session.yaml +++ b/.maestro/privacy_tests/5_-_Multi-site,_single-tab,_session.yaml @@ -2,142 +2,145 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Publisher site" -- tapOn: - text: "Publisher site" -- assertVisible: - text: "Green T-shirt" -- assertVisible: - id: "product-link-1" -- tapOn: - id: "product-link-1" -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Pay with payment-company!" -- assertVisible: - id: "payment-company" -- tapOn: - id: "payment-company" -- assertVisible: - text: "Pay First Party" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" -- action: back -- action: back -- assertVisible: - text: "Pay" -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- assertVisible: - text: "Order complete.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Publisher site" + - tapOn: + text: "Publisher site" + - assertVisible: + text: "Green T-shirt" + - assertVisible: + id: "product-link-1" + - tapOn: + id: "product-link-1" + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Pay with payment-company!" + - assertVisible: + id: "payment-company" + - tapOn: + id: "payment-company" + - assertVisible: + text: "Pay First Party" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" + - action: back + - action: back + - assertVisible: + text: "Pay" + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - assertVisible: + text: "Order complete.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - diff --git a/.maestro/privacy_tests/6_-_Multi-tab.yaml b/.maestro/privacy_tests/6_-_Multi-tab.yaml index e82e3c8eb39f..9d41273c9695 100644 --- a/.maestro/privacy_tests/6_-_Multi-tab.yaml +++ b/.maestro/privacy_tests/6_-_Multi-tab.yaml @@ -2,113 +2,116 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Publisher site" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/tabsMenu" -- tapOn: - id: "com.duckduckgo.mobile.android:id/tabsMenu" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/close" -- tapOn: - id: "com.duckduckgo.mobile.android:id/close" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/newTab" -- tapOn: - id: "com.duckduckgo.mobile.android:id/newTab" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/omnibarTextInput" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarTextInput" -- inputText: "https://www.publisher-company.site/product.html?p=200" -- pressKey: Enter -- assertVisible: - text: "Red shoes" -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Pay" -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- assertVisible: - text: ".*Order complete.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Publisher site" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/tabsMenu" + - tapOn: + id: "com.duckduckgo.mobile.android:id/tabsMenu" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/close" + - tapOn: + id: "com.duckduckgo.mobile.android:id/close" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/newTab" + - tapOn: + id: "com.duckduckgo.mobile.android:id/newTab" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/omnibarTextInput" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarTextInput" + - inputText: "https://www.publisher-company.site/product.html?p=200" + - pressKey: Enter + - assertVisible: + text: "Red shoes" + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Pay" + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - assertVisible: + text: ".*Order complete.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" + - diff --git a/.maestro/privacy_tests/7_-_Browser_restart_mid-session.yaml b/.maestro/privacy_tests/7_-_Browser_restart_mid-session.yaml index 38d54770393e..aa65288b15f2 100644 --- a/.maestro/privacy_tests/7_-_Browser_restart_mid-session.yaml +++ b/.maestro/privacy_tests/7_-_Browser_restart_mid-session.yaml @@ -2,136 +2,139 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Publisher site" -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Pay" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- killApp -- launchApp: - clearState: false -- assertVisible: - text: "Pay" -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- assertVisible: - text: ".*Order complete.*" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" - +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Publisher site" + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Pay" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - killApp + - launchApp: + clearState: false + - assertVisible: + text: "Pay" + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - assertVisible: + text: ".*Order complete.*" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + diff --git a/.maestro/privacy_tests/8_-_Navigation_with_back_forward.yaml b/.maestro/privacy_tests/8_-_Navigation_with_back_forward.yaml index 6008c45fea9c..40aaad2e6d0b 100644 --- a/.maestro/privacy_tests/8_-_Navigation_with_back_forward.yaml +++ b/.maestro/privacy_tests/8_-_Navigation_with_back_forward.yaml @@ -2,169 +2,172 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Publisher site" -- tapOn: - text: "Publisher site" -- assertVisible: - text: "Green T-shirt" -- assertVisible: - id: "product-link-1" -- tapOn: - id: "product-link-1" -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Pay with payment-company!" -- assertVisible: - id: "payment-company" -- tapOn: - id: "payment-company" -- assertVisible: - text: "Pay First Party" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" -- action: back -- action: back -- assertVisible: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/backMenuItem" -- tapOn: - id: "com.duckduckgo.mobile.android:id/backMenuItem" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/backMenuItem" -- tapOn: - id: "com.duckduckgo.mobile.android:id/backMenuItem" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/forwardMenuItem" -- tapOn: - id: "com.duckduckgo.mobile.android:id/forwardMenuItem" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/forwardMenuItem" -- tapOn: - id: "com.duckduckgo.mobile.android:id/forwardMenuItem" -- assertVisible: - text: "Pay" -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Publisher site" + - tapOn: + text: "Publisher site" + - assertVisible: + text: "Green T-shirt" + - assertVisible: + id: "product-link-1" + - tapOn: + id: "product-link-1" + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Pay with payment-company!" + - assertVisible: + id: "payment-company" + - tapOn: + id: "payment-company" + - assertVisible: + text: "Pay First Party" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" + - action: back + - action: back + - assertVisible: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/backMenuItem" + - tapOn: + id: "com.duckduckgo.mobile.android:id/backMenuItem" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/backMenuItem" + - tapOn: + id: "com.duckduckgo.mobile.android:id/backMenuItem" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/forwardMenuItem" + - tapOn: + id: "com.duckduckgo.mobile.android:id/forwardMenuItem" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/forwardMenuItem" + - tapOn: + id: "com.duckduckgo.mobile.android:id/forwardMenuItem" + - assertVisible: + text: "Pay" + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/privacy_tests/9_-_Navigation_with_refresh.yaml b/.maestro/privacy_tests/9_-_Navigation_with_refresh.yaml index e8767fa87122..7c5e5896bfd4 100644 --- a/.maestro/privacy_tests/9_-_Navigation_with_refresh.yaml +++ b/.maestro/privacy_tests/9_-_Navigation_with_refresh.yaml @@ -2,145 +2,148 @@ appId: com.duckduckgo.mobile.android tags: - privacyTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- inputText: "https://www.search-company.site/#ad-id-5" -- pressKey: Enter -- assertVisible: - text: ".*Got It.*" -- assertVisible: - id: "ad-id-5" -- tapOn: - id: "ad-id-5" -- assertVisible: - text: "Publisher site" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- action: back -- assertVisible: - text: "Publisher site" -- tapOn: - text: "Publisher site" -- assertVisible: - text: "Green T-shirt" -- assertVisible: - id: "product-link-1" -- tapOn: - id: "product-link-1" -- assertVisible: - text: "Buy now" -- assertVisible: - id: "buy-now" -- tapOn: - id: "buy-now" -- assertVisible: - text: "Pay with payment-company!" -- assertVisible: - id: "payment-company" -- tapOn: - id: "payment-company" -- assertVisible: - text: "Pay First Party" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- assertVisible: - text: "convert.ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "We did not identify any requests from third-party domains." -- assertVisible: - text: "About our Web Tracking Protections" -- action: back -- action: back -- assertVisible: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- tapOn: - id: "com.duckduckgo.mobile.android:id/browserMenu" -- assertVisible: - id: "com.duckduckgo.mobile.android:id/refreshMenuItem" -- tapOn: - id: "com.duckduckgo.mobile.android:id/refreshMenuItem" -- assertVisible: - text: "Pay" -- assertVisible: - id: "pay-button" -- tapOn: - id: "pay-button" -- tapOn: - id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" -- assertVisible: - text: "View Tracker Companies" -- tapOn: - text: "View Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "ad-company.site" -- action: back -- assertVisible: - text: "View Non-Tracker Companies" -- tapOn: - text: "View Non-Tracker Companies" -- assertVisible: - text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." -- assertVisible: - text: "About our Web Tracking Protections" -- assertVisible: - text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." -- assertVisible: - text: "How our search ads impact our protections" -- assertVisible: - text: ".*Ad Company" -- assertVisible: - text: "convert.ad-company.site" +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - inputText: "https://www.search-company.site/#ad-id-5" + - pressKey: Enter + - assertVisible: + text: ".*Got It.*" + - assertVisible: + id: "ad-id-5" + - tapOn: + id: "ad-id-5" + - assertVisible: + text: "Publisher site" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - action: back + - assertVisible: + text: "Publisher site" + - tapOn: + text: "Publisher site" + - assertVisible: + text: "Green T-shirt" + - assertVisible: + id: "product-link-1" + - tapOn: + id: "product-link-1" + - assertVisible: + text: "Buy now" + - assertVisible: + id: "buy-now" + - tapOn: + id: "buy-now" + - assertVisible: + text: "Pay with payment-company!" + - assertVisible: + id: "payment-company" + - tapOn: + id: "payment-company" + - assertVisible: + text: "Pay First Party" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - assertVisible: + text: "convert.ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "We did not identify any requests from third-party domains." + - assertVisible: + text: "About our Web Tracking Protections" + - action: back + - action: back + - assertVisible: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - tapOn: + id: "com.duckduckgo.mobile.android:id/browserMenu" + - assertVisible: + id: "com.duckduckgo.mobile.android:id/refreshMenuItem" + - tapOn: + id: "com.duckduckgo.mobile.android:id/refreshMenuItem" + - assertVisible: + text: "Pay" + - assertVisible: + id: "pay-button" + - tapOn: + id: "pay-button" + - tapOn: + id: "com.duckduckgo.mobile.android:id/omnibarIconContainer" + - assertVisible: + text: "View Tracker Companies" + - tapOn: + text: "View Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were blocked from loading because they were identified as tracking requests. If a company's requests are loaded, it can allow them to profile you." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "ad-company.site" + - action: back + - assertVisible: + text: "View Non-Tracker Companies" + - tapOn: + text: "View Non-Tracker Companies" + - assertVisible: + text: "The following third-party domains’ requests were loaded. If a company's requests are loaded, it can allow them to profile you, though our other web tracking protections still apply." + - assertVisible: + text: "About our Web Tracking Protections" + - assertVisible: + text: "The following domain’s requests were loaded because a publisher-company.site ad on DuckDuckGo was recently clicked. These requests help evaluate ad effectiveness. All ads on DuckDuckGo are non-profiling." + - assertVisible: + text: "How our search ads impact our protections" + - assertVisible: + text: ".*Ad Company" + - assertVisible: + text: "convert.ad-company.site" diff --git a/.maestro/security_tests/1_-_AddressBarSpoof,_basicauth.yaml b/.maestro/security_tests/1_-_AddressBarSpoof,_basicauth.yaml index 49c4bd48bad1..672f9ffa6a8b 100644 --- a/.maestro/security_tests/1_-_AddressBarSpoof,_basicauth.yaml +++ b/.maestro/security_tests/1_-_AddressBarSpoof,_basicauth.yaml @@ -2,40 +2,43 @@ appId: com.duckduckgo.mobile.android tags: - securityTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- doubleTapOn: - id: "omnibarTextInput" -- pressKey: Backspace -# Test 1 - using \u2028 character -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-basicauth-2028.html" -- pressKey: Enter -- tapOn: "Got It" -- tapOn: "run" -- assertVisible: "Example Domain" -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText.indexOf("https://www.google.com") != 0} -- tapOn: - id: "omnibarTextInput" -# Test 2 - using \u2029 character -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-basicauth-2029.html" -- pressKey: Enter -- tapOn: "run" -- assertVisible: "Example Domain" -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText.indexOf("https://www.google.com") != 0} -- tapOn: - id: "omnibarTextInput" -# Test 3 - using repeated " " space character -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-basicauth-whitespace.html" -- pressKey: Enter -- tapOn: "run" -- assertVisible: "Example Domain" -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText.indexOf("https://www.google.com") != 0} -- tapOn: - id: "omnibarTextInput" \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - doubleTapOn: + id: "omnibarTextInput" + - pressKey: Backspace + # Test 1 - using \u2028 character + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-basicauth-2028.html" + - pressKey: Enter + - tapOn: "Got It" + - tapOn: "run" + - assertVisible: "Example Domain" + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText.indexOf("https://www.google.com") != 0} + - tapOn: + id: "omnibarTextInput" + # Test 2 - using \u2029 character + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-basicauth-2029.html" + - pressKey: Enter + - tapOn: "run" + - assertVisible: "Example Domain" + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText.indexOf("https://www.google.com") != 0} + - tapOn: + id: "omnibarTextInput" + # Test 3 - using repeated " " space character + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-basicauth-whitespace.html" + - pressKey: Enter + - tapOn: "run" + - assertVisible: "Example Domain" + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText.indexOf("https://www.google.com") != 0} + - tapOn: + id: "omnibarTextInput" \ No newline at end of file diff --git a/.maestro/security_tests/2_-_AddressBarSpoof,_aboutblank.yaml b/.maestro/security_tests/2_-_AddressBarSpoof,_aboutblank.yaml index f5e8af78fce1..b7de901a5d08 100644 --- a/.maestro/security_tests/2_-_AddressBarSpoof,_aboutblank.yaml +++ b/.maestro/security_tests/2_-_AddressBarSpoof,_aboutblank.yaml @@ -2,20 +2,23 @@ appId: com.duckduckgo.mobile.android tags: - securityTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -- doubleTapOn: - id: "omnibarTextInput" -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-about-blank-rewrite.html" -- pressKey: Enter -- tapOn: "Got It" -- tapOn: "Start" -# This test is expected to load "about:blank" then duckduckgo.com, not remain on the current page with spoofed content. -- extendedWaitUntil: - notVisible: "Not DDG." # Spoofed content not visible - timeout: 10000 -- tapOn: "Got it!" -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText == "about:blank" || maestro.copiedText == "https://duckduckgo.com/"} \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + - doubleTapOn: + id: "omnibarTextInput" + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-about-blank-rewrite.html" + - pressKey: Enter + - tapOn: "Got It" + - tapOn: "Start" + # This test is expected to load "about:blank" then duckduckgo.com, not remain on the current page with spoofed content. + - extendedWaitUntil: + notVisible: "Not DDG." # Spoofed content not visible + timeout: 10000 + - tapOn: "Got it!" + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText == "about:blank" || maestro.copiedText == "https://duckduckgo.com/"} \ No newline at end of file diff --git a/.maestro/security_tests/3_-_AddressBarSpoof,_appschemes.yaml b/.maestro/security_tests/3_-_AddressBarSpoof,_appschemes.yaml index 2e07b6b95db7..f9e92fb1b254 100644 --- a/.maestro/security_tests/3_-_AddressBarSpoof,_appschemes.yaml +++ b/.maestro/security_tests/3_-_AddressBarSpoof,_appschemes.yaml @@ -2,27 +2,30 @@ appId: com.duckduckgo.mobile.android tags: - securityTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -# Test 1 -- doubleTapOn: - id: "omnibarTextInput" -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-application-scheme.html" -- pressKey: Enter -- tapOn: "Got It" -- tapOn: "Start" -# This test is expected to load spreadprivacy.com, not remain on the current page with spoofed content. -- assertVisible: "Spread Privacy" # DuckDuckGo blog homepage -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText == "https://spreadprivacy.com/"} # DuckDuckGo blog home page -- tapOn: - id: "omnibarTextInput" -# Test 2 -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-unsupported-scheme.html" -- pressKey: Enter -- tapOn: "Start" -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText == "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-unsupported-scheme.html"} +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + # Test 1 + - doubleTapOn: + id: "omnibarTextInput" + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-application-scheme.html" + - pressKey: Enter + - tapOn: "Got It" + - tapOn: "Start" + # This test is expected to load spreadprivacy.com, not remain on the current page with spoofed content. + - assertVisible: "Spread Privacy" # DuckDuckGo blog homepage + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText == "https://spreadprivacy.com/"} # DuckDuckGo blog home page + - tapOn: + id: "omnibarTextInput" + # Test 2 + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-unsupported-scheme.html" + - pressKey: Enter + - tapOn: "Start" + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText == "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-unsupported-scheme.html"} diff --git a/.maestro/security_tests/4_-_AddressBarSpoof,_b64_html.yaml b/.maestro/security_tests/4_-_AddressBarSpoof,_b64_html.yaml index 809053faf68f..cc5fd6d975ff 100644 --- a/.maestro/security_tests/4_-_AddressBarSpoof,_b64_html.yaml +++ b/.maestro/security_tests/4_-_AddressBarSpoof,_b64_html.yaml @@ -2,19 +2,22 @@ appId: com.duckduckgo.mobile.android tags: - securityTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -# Test 1 -- doubleTapOn: - id: "omnibarTextInput" -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-open-b64-html.html" -- pressKey: Enter -- tapOn: "Got It" -- tapOn: "Start" -# This test is expected to open a new tab with empty origin ("") and then prompt to open the link in another app -- assertVisible: "Open in another app" -- tapOn: "Cancel" -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText.indexOf("duckduckgo.com") == -1} +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + # Test 1 + - doubleTapOn: + id: "omnibarTextInput" + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-open-b64-html.html" + - pressKey: Enter + - tapOn: "Got It" + - tapOn: "Start" + # This test is expected to open a new tab with empty origin ("") and then prompt to open the link in another app + - assertVisible: "Open in another app" + - tapOn: "Cancel" + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText.indexOf("duckduckgo.com") == -1} diff --git a/.maestro/security_tests/5_-_AddressBarSpoof,_downloadpath.yaml b/.maestro/security_tests/5_-_AddressBarSpoof,_downloadpath.yaml index f9c2433d83a3..2edbd8387b6b 100644 --- a/.maestro/security_tests/5_-_AddressBarSpoof,_downloadpath.yaml +++ b/.maestro/security_tests/5_-_AddressBarSpoof,_downloadpath.yaml @@ -2,32 +2,35 @@ appId: com.duckduckgo.mobile.android tags: - securityTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -# Test 1 -- doubleTapOn: - id: "omnibarTextInput" -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-js-download-url.html" -- pressKey: Enter -- tapOn: "Got It" -- tapOn: "Start" -# Download Acceptance Flow: -- extendedWaitUntil: - visible: "Save to Downloads" - timeout: 10000 -- tapOn: "Save to Downloads" -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText == "Search or type URL"} # Downloads should occur in empty origin. -- pressKey: Back -# Download Cancel Flow: -- tapOn: "Start" -- extendedWaitUntil: - visible: "Cancel" - timeout: 10000 -- tapOn: "Cancel" -# Should redirect back to the last page. -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText.indexOf("https://staticcdn.duckduckgo.com") == -1} \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + # Test 1 + - doubleTapOn: + id: "omnibarTextInput" + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-js-download-url.html" + - pressKey: Enter + - tapOn: "Got It" + - tapOn: "Start" + # Download Acceptance Flow: + - extendedWaitUntil: + visible: "Save to Downloads" + timeout: 10000 + - tapOn: "Save to Downloads" + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText == "Search or type URL"} # Downloads should occur in empty origin. + - pressKey: Back + # Download Cancel Flow: + - tapOn: "Start" + - extendedWaitUntil: + visible: "Cancel" + timeout: 10000 + - tapOn: "Cancel" + # Should redirect back to the last page. + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText.indexOf("https://staticcdn.duckduckgo.com") == -1} \ No newline at end of file diff --git a/.maestro/security_tests/6_-_AddressBarSpoof,_formaction.yaml b/.maestro/security_tests/6_-_AddressBarSpoof,_formaction.yaml index d15e27a856a4..704ace3933f5 100644 --- a/.maestro/security_tests/6_-_AddressBarSpoof,_formaction.yaml +++ b/.maestro/security_tests/6_-_AddressBarSpoof,_formaction.yaml @@ -2,17 +2,20 @@ appId: com.duckduckgo.mobile.android tags: - securityTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -# Test 1 -- doubleTapOn: - id: "omnibarTextInput" -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-form-action.html" -- pressKey: Enter -- tapOn: "Got It" -- tapOn: "run" -# Should do nothing - the navigation should be prevented. -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText == "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-form-action.html"} \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + # Test 1 + - doubleTapOn: + id: "omnibarTextInput" + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-form-action.html" + - pressKey: Enter + - tapOn: "Got It" + - tapOn: "run" + # Should do nothing - the navigation should be prevented. + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText == "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-form-action.html"} \ No newline at end of file diff --git a/.maestro/security_tests/7_-_AddressBarSpoof,_pagerewrite.yaml b/.maestro/security_tests/7_-_AddressBarSpoof,_pagerewrite.yaml index b07f63daa86f..3fc77d54f087 100644 --- a/.maestro/security_tests/7_-_AddressBarSpoof,_pagerewrite.yaml +++ b/.maestro/security_tests/7_-_AddressBarSpoof,_pagerewrite.yaml @@ -2,18 +2,21 @@ appId: com.duckduckgo.mobile.android tags: - securityTest --- -- launchApp: - clearState: true -- runFlow: ../shared/onboarding.yaml -# Test 1 -- doubleTapOn: - id: "omnibarTextInput" -- inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-js-page-rewrite.html" -- pressKey: Enter -- tapOn: "Got It" -- tapOn: "Start" -# Now check the address bar hasn't been updated too early resulting in spoofed content -- copyTextFrom: - id: "omnibarTextInput" -- assertTrue: ${maestro.copiedText == "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-js-page-rewrite.html"} -- assertNotVisible: "DDG." \ No newline at end of file +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + - runFlow: ../shared/onboarding.yaml + # Test 1 + - doubleTapOn: + id: "omnibarTextInput" + - inputText: "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-js-page-rewrite.html" + - pressKey: Enter + - tapOn: "Got It" + - tapOn: "Start" + # Now check the address bar hasn't been updated too early resulting in spoofed content + - copyTextFrom: + id: "omnibarTextInput" + - assertTrue: ${maestro.copiedText == "https://privacy-test-pages.site/security/address-bar-spoofing/spoof-js-page-rewrite.html"} + - assertNotVisible: "DDG." \ No newline at end of file diff --git a/.maestro/tabs/open_multiple_tabs.yaml b/.maestro/tabs/open_multiple_tabs.yaml index 768481d613e6..56b880d227f1 100644 --- a/.maestro/tabs/open_multiple_tabs.yaml +++ b/.maestro/tabs/open_multiple_tabs.yaml @@ -3,49 +3,52 @@ name: "ReleaseTest: Multiple tabs can be opened" tags: - releaseTest --- -- launchApp: - clearState: true - stopApp: true +- retry: + maxRetries: 3 + commands: + - launchApp: + clearState: true + stopApp: true -- runFlow: ../shared/onboarding.yaml + - runFlow: ../shared/onboarding.yaml -- tapOn: - text: "search or type URL" -- inputText: "https://privacy-test-pages.site" -- pressKey: Enter -- assertVisible: - text: ".*keep browsing.*" -- tapOn: - text: "got it" -- tapOn: - id: "com.duckduckgo.mobile.android:id/tabCount" -- assertVisible: - text: "Privacy Test Pages - Home" -- tapOn: "New Tab" -- assertVisible: - text: "Search or type URL" -- inputText: "https://www.search-company.site" -- pressKey: Enter -- assertVisible: - text: "Search engine" -- tapOn: - id: "com.duckduckgo.mobile.android:id/tabCount" -- assertVisible: - text: "Ad Click Flow" -- assertVisible: - text: "Privacy Test Pages - Home" -- tapOn: - text: "Privacy Test Pages - Home" -- assertNotVisible: - text: "Ad Click Flow" -- assertVisible: - text: "Privacy Test Pages - Home" -- tapOn: - id: "com.duckduckgo.mobile.android:id/tabCount" -- assertVisible: - text: "Ad Click Flow" -- tapOn: - id: "com.duckduckgo.mobile.android:id/close" - rightOf: "Ad Click Flow" -- assertNotVisible: - text: "Ad Click Flow" + - tapOn: + text: "search or type URL" + - inputText: "https://privacy-test-pages.site" + - pressKey: Enter + - assertVisible: + text: ".*keep browsing.*" + - tapOn: + text: "got it" + - tapOn: + id: "com.duckduckgo.mobile.android:id/tabCount" + - assertVisible: + text: "Privacy Test Pages - Home" + - tapOn: "New Tab" + - assertVisible: + text: "Search or type URL" + - inputText: "https://www.search-company.site" + - pressKey: Enter + - assertVisible: + text: "Search engine" + - tapOn: + id: "com.duckduckgo.mobile.android:id/tabCount" + - assertVisible: + text: "Ad Click Flow" + - assertVisible: + text: "Privacy Test Pages - Home" + - tapOn: + text: "Privacy Test Pages - Home" + - assertNotVisible: + text: "Ad Click Flow" + - assertVisible: + text: "Privacy Test Pages - Home" + - tapOn: + id: "com.duckduckgo.mobile.android:id/tabCount" + - assertVisible: + text: "Ad Click Flow" + - tapOn: + id: "com.duckduckgo.mobile.android:id/close" + rightOf: "Ad Click Flow" + - assertNotVisible: + text: "Ad Click Flow" From e8aa0f8c23a6f0b304dfdce7edb42445dfe47083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gonz=C3=A1lez?= Date: Wed, 18 Dec 2024 16:44:48 +0100 Subject: [PATCH 12/32] GHA: Update PR notifications (#5395) Task/Issue URL: https://app.asana.com/0/1174433894299346/1208984904365490 ### Description This PR updates the workflow that interacts with Asana after a PR has been reviewed. More details in the task. --- .github/workflows/pr-review-notifications.yaml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/pr-review-notifications.yaml diff --git a/.github/workflows/pr-review-notifications.yaml b/.github/workflows/pr-review-notifications.yaml new file mode 100644 index 000000000000..fc2c2b9d745c --- /dev/null +++ b/.github/workflows/pr-review-notifications.yaml @@ -0,0 +1,14 @@ +name: Pull Request Reviewed -> Asana Sync + +on: + pull_request_review: + types: [submitted] + +jobs: + pr-reviewed: + name: Update Asana task -> PR reviewed + uses: duckduckgo/native-github-asana-sync/.github/workflows/pr-review-notifications.yml@david/improve-pr-notifications + with: + trigger-phrase: "Task/Issue URL:" + secrets: + asana_pat: ${{ secrets.GH_ASANA_SECRET }} \ No newline at end of file From 524e21690536cd52f24c3812023c580331a794be Mon Sep 17 00:00:00 2001 From: Dax Mobile <44842493+daxmobile@users.noreply.github.com> Date: Thu, 19 Dec 2024 05:04:06 +1100 Subject: [PATCH 13/32] Update autofill to 16.1.0 (#5407) Task/Issue URL: https://app.asana.com/0/1209009001482464/1209009001482464 Autofill Release: https://github.com/duckduckgo/duckduckgo-autofill/releases/tag/16.1.0 ## Description Updates Autofill to version [16.1.0](https://github.com/duckduckgo/duckduckgo-autofill/releases/tag/16.1.0). ### Autofill 16.1.0 release notes ## What's Changed * [DeviceInterface] Call closeautofillparent only after openManage calls by @dbajpeyi in https://github.com/duckduckgo/duckduckgo-autofill/pull/718 * [CredentialsImport] Call credentials flow call first, and then close parent by @dbajpeyi in https://github.com/duckduckgo/duckduckgo-autofill/pull/723 * [FeatureToggle] Add new autofill config for partial save trigger by @dbajpeyi in https://github.com/duckduckgo/duckduckgo-autofill/pull/724 **Full Changelog**: https://github.com/duckduckgo/duckduckgo-autofill/compare/16.0.0...16.1.0 ## Steps to test This release has been tested during autofill development. For smoke test steps see [this task](https://app.asana.com/0/1198964220583541/1200583647142330/f). Co-authored-by: dbajpeyi <3018923+dbajpeyi@users.noreply.github.com> --- .../autofill/dist/autofill-debug.js | 1142 ++++++++++------- .../@duckduckgo/autofill/dist/autofill.js | 708 +++++----- package-lock.json | 4 +- package.json | 2 +- 4 files changed, 1087 insertions(+), 769 deletions(-) diff --git a/node_modules/@duckduckgo/autofill/dist/autofill-debug.js b/node_modules/@duckduckgo/autofill/dist/autofill-debug.js index b02ab092e3a5..a3ad7f79835a 100644 --- a/node_modules/@duckduckgo/autofill/dist/autofill-debug.js +++ b/node_modules/@duckduckgo/autofill/dist/autofill-debug.js @@ -138,6 +138,11 @@ class ZodError extends Error { processError(this); return fieldErrors; } + static assert(value) { + if (!(value instanceof ZodError)) { + throw new Error(`Not a ZodError: ${value}`); + } + } toString() { return this.message; } @@ -267,6 +272,13 @@ const makeIssue = params => { ...issueData, path: fullPath }; + if (issueData.message !== undefined) { + return { + ...issueData, + path: fullPath, + message: issueData.message + }; + } let errorMessage = ""; const maps = errorMaps.filter(m => !!m).slice().reverse(); for (const map of maps) { @@ -278,17 +290,18 @@ const makeIssue = params => { return { ...issueData, path: fullPath, - message: issueData.message || errorMessage + message: errorMessage }; }; exports.makeIssue = makeIssue; exports.EMPTY_PATH = []; function addIssueToContext(ctx, issueData) { + const overrideMap = (0, errors_1.getErrorMap)(); const issue = (0, exports.makeIssue)({ issueData: issueData, data: ctx.data, path: ctx.path, - errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, (0, errors_1.getErrorMap)(), en_1.default // then global default map + errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, overrideMap, overrideMap === en_1.default ? undefined : en_1.default // then global default map ].filter(x => !!x) }); ctx.common.issues.push(issue); @@ -319,9 +332,11 @@ class ParseStatus { static async mergeObjectAsync(status, pairs) { const syncPairs = []; for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; syncPairs.push({ - key: await pair.key, - value: await pair.value + key, + value }); } return ParseStatus.mergeObjectSync(status, syncPairs); @@ -632,11 +647,23 @@ exports.default = errorMap; },{"../ZodError":2,"../helpers/util":8}],11:[function(require,module,exports){ "use strict"; +var __classPrivateFieldGet = void 0 && (void 0).__classPrivateFieldGet || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __classPrivateFieldSet = void 0 && (void 0).__classPrivateFieldSet || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; +}; +var _ZodEnum_cache, _ZodNativeEnum_cache; Object.defineProperty(exports, "__esModule", { value: true }); -exports.date = exports.boolean = exports.bigint = exports.array = exports.any = exports.coerce = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodReadonly = exports.ZodPipeline = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodCatch = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.ZodType = void 0; -exports.NEVER = exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.symbol = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.pipeline = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = exports.discriminatedUnion = void 0; +exports.boolean = exports.bigint = exports.array = exports.any = exports.coerce = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodReadonly = exports.ZodPipeline = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodCatch = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.datetimeRegex = exports.ZodType = void 0; +exports.NEVER = exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.symbol = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.pipeline = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = exports.discriminatedUnion = exports.date = void 0; const errors_1 = require("./errors"); const errorUtil_1 = require("./helpers/errorUtil"); const parseUtil_1 = require("./helpers/parseUtil"); @@ -698,16 +725,25 @@ function processCreateParams(params) { description }; const customMap = (iss, ctx) => { - if (iss.code !== "invalid_type") return { - message: ctx.defaultError - }; + var _a, _b; + const { + message + } = params; + if (iss.code === "invalid_enum_value") { + return { + message: message !== null && message !== void 0 ? message : ctx.defaultError + }; + } if (typeof ctx.data === "undefined") { return { - message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError + message: (_a = message !== null && message !== void 0 ? message : required_error) !== null && _a !== void 0 ? _a : ctx.defaultError }; } + if (iss.code !== "invalid_type") return { + message: ctx.defaultError + }; return { - message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError + message: (_b = message !== null && message !== void 0 ? message : invalid_type_error) !== null && _b !== void 0 ? _b : ctx.defaultError }; }; return { @@ -977,11 +1013,13 @@ exports.ZodType = ZodType; exports.Schema = ZodType; exports.ZodSchema = ZodType; const cuidRegex = /^c[^\s-]{8,}$/i; -const cuid2Regex = /^[a-z][a-z0-9]*$/; +const cuid2Regex = /^[0-9a-z]+$/; const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/; // const uuidRegex = // /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i; const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i; +const nanoidRegex = /^[a-z0-9_-]{21}$/i; +const durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/; // from https://stackoverflow.com/a/46181/1550155 // old version: too slow, didn't support unicode // const emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; @@ -994,36 +1032,47 @@ const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA- // /^[a-zA-Z0-9\.\!\#\$\%\&\'\*\+\/\=\?\^\_\`\{\|\}\~\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; // const emailRegex = // /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i; -const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; +const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; // const emailRegex = // /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9\-]+)*$/i; // from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression const _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`; let emojiRegex; -const ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/; +// faster, simpler, safer +const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/; const ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/; -// Adapted from https://stackoverflow.com/a/3143231 -const datetimeRegex = args => { +// https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript +const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; +// simple +// const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; +// no leap year validation +// const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\d|2\\d))`; +// with leap year validation +const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`; +const dateRegex = new RegExp(`^${dateRegexSource}$`); +function timeRegexSource(args) { + // let regex = `\\d{2}:\\d{2}:\\d{2}`; + let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`; if (args.precision) { - if (args.offset) { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}(([+-]\\d{2}(:?\\d{2})?)|Z)$`); - } else { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}Z$`); - } - } else if (args.precision === 0) { - if (args.offset) { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(([+-]\\d{2}(:?\\d{2})?)|Z)$`); - } else { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$`); - } - } else { - if (args.offset) { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}(:?\\d{2})?)|Z)$`); - } else { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$`); - } + regex = `${regex}\\.\\d{${args.precision}}`; + } else if (args.precision == null) { + regex = `${regex}(\\.\\d+)?`; } -}; + return regex; +} +function timeRegex(args) { + return new RegExp(`^${timeRegexSource(args)}$`); +} +// Adapted from https://stackoverflow.com/a/3143231 +function datetimeRegex(args) { + let regex = `${dateRegexSource}T${timeRegexSource(args)}`; + const opts = []; + opts.push(args.local ? `Z?` : `Z`); + if (args.offset) opts.push(`([+-]\\d{2}:?\\d{2})`); + regex = `${regex}(${opts.join("|")})`; + return new RegExp(`^${regex}$`); +} +exports.datetimeRegex = datetimeRegex; function isValidIP(ip, version) { if ((version === "v4" || !version) && ipv4Regex.test(ip)) { return true; @@ -1045,10 +1094,7 @@ class ZodString extends ZodType { code: ZodError_1.ZodIssueCode.invalid_type, expected: util_1.ZodParsedType.string, received: ctx.parsedType - } - // - ); - + }); return parseUtil_1.INVALID; } const status = new parseUtil_1.ParseStatus(); @@ -1139,6 +1185,16 @@ class ZodString extends ZodType { }); status.dirty(); } + } else if (check.kind === "nanoid") { + if (!nanoidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + validation: "nanoid", + code: ZodError_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } } else if (check.kind === "cuid") { if (!cuidRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); @@ -1247,6 +1303,38 @@ class ZodString extends ZodType { }); status.dirty(); } + } else if (check.kind === "date") { + const regex = dateRegex; + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + code: ZodError_1.ZodIssueCode.invalid_string, + validation: "date", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "time") { + const regex = timeRegex(check); + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + code: ZodError_1.ZodIssueCode.invalid_string, + validation: "time", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "duration") { + if (!durationRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + validation: "duration", + code: ZodError_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } } else if (check.kind === "ip") { if (!isValidIP(input.data, check.version)) { ctx = this._getOrReturnCtx(input, ctx); @@ -1257,6 +1345,16 @@ class ZodString extends ZodType { }); status.dirty(); } + } else if (check.kind === "base64") { + if (!base64Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + validation: "base64", + code: ZodError_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } } else { util_1.util.assertNever(check); } @@ -1303,6 +1401,12 @@ class ZodString extends ZodType { ...errorUtil_1.errorUtil.errToObj(message) }); } + nanoid(message) { + return this._addCheck({ + kind: "nanoid", + ...errorUtil_1.errorUtil.errToObj(message) + }); + } cuid(message) { return this._addCheck({ kind: "cuid", @@ -1321,6 +1425,12 @@ class ZodString extends ZodType { ...errorUtil_1.errorUtil.errToObj(message) }); } + base64(message) { + return this._addCheck({ + kind: "base64", + ...errorUtil_1.errorUtil.errToObj(message) + }); + } ip(options) { return this._addCheck({ kind: "ip", @@ -1328,12 +1438,13 @@ class ZodString extends ZodType { }); } datetime(options) { - var _a; + var _a, _b; if (typeof options === "string") { return this._addCheck({ kind: "datetime", precision: null, offset: false, + local: false, message: options }); } @@ -1341,9 +1452,36 @@ class ZodString extends ZodType { kind: "datetime", precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision, offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false, + local: (_b = options === null || options === void 0 ? void 0 : options.local) !== null && _b !== void 0 ? _b : false, + ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message) + }); + } + date(message) { + return this._addCheck({ + kind: "date", + message + }); + } + time(options) { + if (typeof options === "string") { + return this._addCheck({ + kind: "time", + precision: null, + message: options + }); + } + return this._addCheck({ + kind: "time", + precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision, ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message) }); } + duration(message) { + return this._addCheck({ + kind: "duration", + ...errorUtil_1.errorUtil.errToObj(message) + }); + } regex(regex, message) { return this._addCheck({ kind: "regex", @@ -1428,6 +1566,15 @@ class ZodString extends ZodType { get isDatetime() { return !!this._def.checks.find(ch => ch.kind === "datetime"); } + get isDate() { + return !!this._def.checks.find(ch => ch.kind === "date"); + } + get isTime() { + return !!this._def.checks.find(ch => ch.kind === "time"); + } + get isDuration() { + return !!this._def.checks.find(ch => ch.kind === "duration"); + } get isEmail() { return !!this._def.checks.find(ch => ch.kind === "email"); } @@ -1440,6 +1587,9 @@ class ZodString extends ZodType { get isUUID() { return !!this._def.checks.find(ch => ch.kind === "uuid"); } + get isNANOID() { + return !!this._def.checks.find(ch => ch.kind === "nanoid"); + } get isCUID() { return !!this._def.checks.find(ch => ch.kind === "cuid"); } @@ -1452,6 +1602,9 @@ class ZodString extends ZodType { get isIP() { return !!this._def.checks.find(ch => ch.kind === "ip"); } + get isBase64() { + return !!this._def.checks.find(ch => ch.kind === "base64"); + } get minLength() { let min = null; for (const ch of this._def.checks) { @@ -2442,9 +2595,10 @@ class ZodObject extends ZodType { const syncPairs = []; for (const pair of pairs) { const key = await pair.key; + const value = await pair.value; syncPairs.push({ key, - value: await pair.value, + value, alwaysSet: pair.alwaysSet }); } @@ -2814,15 +2968,25 @@ const getDiscriminator = type => { return type.options; } else if (type instanceof ZodNativeEnum) { // eslint-disable-next-line ban/ban - return Object.keys(type.enum); + return util_1.util.objectValues(type.enum); } else if (type instanceof ZodDefault) { return getDiscriminator(type._def.innerType); } else if (type instanceof ZodUndefined) { return [undefined]; } else if (type instanceof ZodNull) { return [null]; + } else if (type instanceof ZodOptional) { + return [undefined, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodNullable) { + return [null, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodBranded) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodReadonly) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodCatch) { + return getDiscriminator(type._def.innerType); } else { - return null; + return []; } }; class ZodDiscriminatedUnion extends ZodType { @@ -2886,7 +3050,7 @@ class ZodDiscriminatedUnion extends ZodType { // try { for (const type of options) { const discriminatorValues = getDiscriminator(type.shape[discriminator]); - if (!discriminatorValues) { + if (!discriminatorValues.length) { throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`); } for (const value of discriminatorValues) { @@ -3123,7 +3287,8 @@ class ZodRecord extends ZodType { for (const key in ctx.data) { pairs.push({ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), - value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)) + value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)), + alwaysSet: key in ctx.data }); } if (ctx.common.async) { @@ -3511,6 +3676,10 @@ function createZodEnum(values, params) { }); } class ZodEnum extends ZodType { + constructor() { + super(...arguments); + _ZodEnum_cache.set(this, void 0); + } _parse(input) { if (typeof input.data !== "string") { const ctx = this._getOrReturnCtx(input); @@ -3522,7 +3691,10 @@ class ZodEnum extends ZodType { }); return parseUtil_1.INVALID; } - if (this._def.values.indexOf(input.data) === -1) { + if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f")) { + __classPrivateFieldSet(this, _ZodEnum_cache, new Set(this._def.values), "f"); + } + if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f").has(input.data)) { const ctx = this._getOrReturnCtx(input); const expectedValues = this._def.values; (0, parseUtil_1.addIssueToContext)(ctx, { @@ -3559,15 +3731,28 @@ class ZodEnum extends ZodType { return enumValues; } extract(values) { - return ZodEnum.create(values); + let newDef = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._def; + return ZodEnum.create(values, { + ...this._def, + ...newDef + }); } exclude(values) { - return ZodEnum.create(this.options.filter(opt => !values.includes(opt))); + let newDef = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._def; + return ZodEnum.create(this.options.filter(opt => !values.includes(opt)), { + ...this._def, + ...newDef + }); } } exports.ZodEnum = ZodEnum; +_ZodEnum_cache = new WeakMap(); ZodEnum.create = createZodEnum; class ZodNativeEnum extends ZodType { + constructor() { + super(...arguments); + _ZodNativeEnum_cache.set(this, void 0); + } _parse(input) { const nativeEnumValues = util_1.util.getValidEnumValues(this._def.values); const ctx = this._getOrReturnCtx(input); @@ -3580,7 +3765,10 @@ class ZodNativeEnum extends ZodType { }); return parseUtil_1.INVALID; } - if (nativeEnumValues.indexOf(input.data) === -1) { + if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f")) { + __classPrivateFieldSet(this, _ZodNativeEnum_cache, new Set(util_1.util.getValidEnumValues(this._def.values)), "f"); + } + if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f").has(input.data)) { const expectedValues = util_1.util.objectValues(nativeEnumValues); (0, parseUtil_1.addIssueToContext)(ctx, { received: ctx.data, @@ -3596,6 +3784,7 @@ class ZodNativeEnum extends ZodType { } } exports.ZodNativeEnum = ZodNativeEnum; +_ZodNativeEnum_cache = new WeakMap(); ZodNativeEnum.create = (values, params) => { return new ZodNativeEnum({ values: values, @@ -3665,32 +3854,34 @@ class ZodEffects extends ZodType { checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); if (effect.type === "preprocess") { const processed = effect.transform(ctx.data, checkCtx); - if (ctx.common.issues.length) { - return { - status: "dirty", - value: ctx.data - }; - } if (ctx.common.async) { - return Promise.resolve(processed).then(processed => { - return this._def.schema._parseAsync({ + return Promise.resolve(processed).then(async processed => { + if (status.value === "aborted") return parseUtil_1.INVALID; + const result = await this._def.schema._parseAsync({ data: processed, path: ctx.path, parent: ctx }); + if (result.status === "aborted") return parseUtil_1.INVALID; + if (result.status === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + if (status.value === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + return result; }); } else { - return this._def.schema._parseSync({ + if (status.value === "aborted") return parseUtil_1.INVALID; + const result = this._def.schema._parseSync({ data: processed, path: ctx.path, parent: ctx }); + if (result.status === "aborted") return parseUtil_1.INVALID; + if (result.status === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + if (status.value === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + return result; } } if (effect.type === "refinement") { - const executeRefinement = (acc - // effect: RefinementEffect - ) => { + const executeRefinement = acc => { const result = effect.refinement(acc, checkCtx); if (ctx.common.async) { return Promise.resolve(result); @@ -4013,10 +4204,16 @@ exports.ZodPipeline = ZodPipeline; class ZodReadonly extends ZodType { _parse(input) { const result = this._def.innerType._parse(input); - if ((0, parseUtil_1.isValid)(result)) { - result.value = Object.freeze(result.value); - } - return result; + const freeze = data => { + if ((0, parseUtil_1.isValid)(data)) { + data.value = Object.freeze(data.value); + } + return data; + }; + return (0, parseUtil_1.isAsync)(result) ? result.then(data => freeze(data)) : freeze(result); + } + unwrap() { + return this._def.innerType; } } exports.ZodReadonly = ZodReadonly; @@ -4027,7 +4224,7 @@ ZodReadonly.create = (type, params) => { ...processCreateParams(params) }); }; -const custom = function (check) { +function custom(check) { let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; let /** @@ -4059,7 +4256,7 @@ const custom = function (check) { } }); return ZodAny.create(); -}; +} exports.custom = custom; exports.late = { object: ZodObject.lazycreate @@ -4113,7 +4310,7 @@ cls) { let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { message: `Input not instance of ${cls.name}` }; - return (0, exports.custom)(data => data instanceof cls, params); + return custom(data => data instanceof cls, params); }; exports.instanceof = instanceOfType; const stringType = ZodString.create; @@ -4435,8 +4632,8 @@ class SchemaValidationError extends Error { } case 'invalid_union': { - for (let unionError of issue.unionErrors) { - for (let issue1 of unionError.issues) { + for (const unionError of issue.unionErrors) { + for (const issue1 of unionError.issues) { log(issue1); } } @@ -4448,7 +4645,7 @@ class SchemaValidationError extends Error { } } } - for (let error of errors) { + for (const error of errors) { log(error); } const message = [heading, 'please see the details above'].join('\n '); @@ -4571,8 +4768,8 @@ class DeviceApi { */ async request(deviceApiCall, options) { deviceApiCall.validateParams(); - let result = await this.transport.send(deviceApiCall, options); - let processed = deviceApiCall.preResultValidation(result); + const result = await this.transport.send(deviceApiCall, options); + const processed = deviceApiCall.preResultValidation(result); return deviceApiCall.validateResult(processed); } /** @@ -4660,44 +4857,44 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.transport = getTransport(config); } /** - * Send a 'fire-and-forget' message. - * @throws {Error} - * {@link MissingHandler} - * - * @example - * - * ``` - * const messaging = new Messaging(config) - * messaging.notify("foo", {bar: "baz"}) - * ``` - * @param {string} name - * @param {Record} [data] - */ + * Send a 'fire-and-forget' message. + * @throws {Error} + * {@link MissingHandler} + * + * @example + * + * ``` + * const messaging = new Messaging(config) + * messaging.notify("foo", {bar: "baz"}) + * ``` + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.transport.notify(name, data); } /** - * Send a request, and wait for a response - * @throws {Error} - * {@link MissingHandler} - * - * @example - * ``` - * const messaging = new Messaging(config) - * const response = await messaging.request("foo", {bar: "baz"}) - * ``` - * - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * Send a request, and wait for a response + * @throws {Error} + * {@link MissingHandler} + * + * @example + * ``` + * const messaging = new Messaging(config) + * const response = await messaging.request("foo", {bar: "baz"}) + * ``` + * + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.transport.request(name, data); @@ -4710,20 +4907,20 @@ class Messaging { exports.Messaging = Messaging; class MessagingTransport { /** - * @param {string} name - * @param {Record} [data] - * @returns {void} - */ + * @param {string} name + * @param {Record} [data] + * @returns {void} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; throw new Error("must implement 'notify'"); } /** - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -4748,9 +4945,9 @@ function getTransport(config) { */ class MissingHandler extends Error { /** - * @param {string} message - * @param {string} handlerName - */ + * @param {string} message + * @param {string} handlerName + */ constructor(message, handlerName) { super(message); this.handlerName = handlerName; @@ -4856,8 +5053,8 @@ class WebkitMessagingTransport { config; globals; /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.config = config; this.globals = captureGlobals(); @@ -4866,11 +5063,11 @@ class WebkitMessagingTransport { } } /** - * Sends message to the webkit layer (fire and forget) - * @param {String} handler - * @param {*} data - * @internal - */ + * Sends message to the webkit layer (fire and forget) + * @param {String} handler + * @param {*} data + * @internal + */ wkSend(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!(handler in this.globals.window.webkit.messageHandlers)) { @@ -4894,12 +5091,12 @@ class WebkitMessagingTransport { } /** - * Sends message to the webkit layer and waits for the specified response - * @param {String} handler - * @param {*} data - * @returns {Promise<*>} - * @internal - */ + * Sends message to the webkit layer and waits for the specified response + * @param {String} handler + * @param {*} data + * @returns {Promise<*>} + * @internal + */ async wkSendAndWait(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (this.config.hasModernWebkitAPI) { @@ -4940,27 +5137,27 @@ class WebkitMessagingTransport { } } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.wkSend(name, data); } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.wkSendAndWait(name, data); } /** - * Generate a random method name and adds it to the global scope - * The native layer will use this method to send the response - * @param {string | number} randomMethodName - * @param {Function} callback - */ + * Generate a random method name and adds it to the global scope + * The native layer will use this method to send the response + * @param {string | number} randomMethodName + * @param {Function} callback + */ generateRandomMethod(randomMethodName, callback) { var _this = this; this.globals.ObjectDefineProperty(this.globals.window, randomMethodName, { @@ -4969,8 +5166,8 @@ class WebkitMessagingTransport { configurable: true, writable: false, /** - * @param {any[]} args - */ + * @param {any[]} args + */ value: function () { callback(...arguments); // @ts-ignore - we want this to throw if it fails as it would indicate a fatal error. @@ -4986,16 +5183,16 @@ class WebkitMessagingTransport { } /** - * @type {{name: string, length: number}} - */ + * @type {{name: string, length: number}} + */ algoObj = { name: 'AES-GCM', length: 256 }; /** - * @returns {Promise} - */ + * @returns {Promise} + */ async createRandKey() { const key = await this.globals.generateKey(this.algoObj, true, ['encrypt', 'decrypt']); const exportedKey = await this.globals.exportKey('raw', key); @@ -5003,44 +5200,44 @@ class WebkitMessagingTransport { } /** - * @returns {Uint8Array} - */ + * @returns {Uint8Array} + */ createRandIv() { return this.globals.getRandomValues(new this.globals.Uint8Array(12)); } /** - * @param {BufferSource} ciphertext - * @param {BufferSource} key - * @param {Uint8Array} iv - * @returns {Promise} - */ + * @param {BufferSource} ciphertext + * @param {BufferSource} key + * @param {Uint8Array} iv + * @returns {Promise} + */ async decrypt(ciphertext, key, iv) { const cryptoKey = await this.globals.importKey('raw', key, 'AES-GCM', false, ['decrypt']); const algo = { name: 'AES-GCM', iv }; - let decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); - let dec = new this.globals.TextDecoder(); + const decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); + const dec = new this.globals.TextDecoder(); return dec.decode(decrypted); } /** - * When required (such as on macos 10.x), capture the `postMessage` method on - * each webkit messageHandler - * - * @param {string[]} handlerNames - */ + * When required (such as on macos 10.x), capture the `postMessage` method on + * each webkit messageHandler + * + * @param {string[]} handlerNames + */ captureWebkitHandlers(handlerNames) { const handlers = window.webkit.messageHandlers; if (!handlers) throw new _messaging.MissingHandler('window.webkit.messageHandlers was absent', 'all'); - for (let webkitMessageHandlerName of handlerNames) { + for (const webkitMessageHandlerName of handlerNames) { if (typeof handlers[webkitMessageHandlerName]?.postMessage === 'function') { /** - * `bind` is used here to ensure future calls to the captured - * `postMessage` have the correct `this` context - */ + * `bind` is used here to ensure future calls to the captured + * `postMessage` have the correct `this` context + */ const original = handlers[webkitMessageHandlerName]; const bound = handlers[webkitMessageHandlerName].postMessage?.bind(original); this.globals.capturedWebkitHandlers[webkitMessageHandlerName] = bound; @@ -5069,11 +5266,11 @@ class WebkitMessagingTransport { exports.WebkitMessagingTransport = WebkitMessagingTransport; class WebkitMessagingConfig { /** - * @param {object} params - * @param {boolean} params.hasModernWebkitAPI - * @param {string[]} params.webkitMessageHandlerNames - * @param {string} params.secret - */ + * @param {object} params + * @param {boolean} params.hasModernWebkitAPI + * @param {string[]} params.webkitMessageHandlerNames + * @param {string} params.secret + */ constructor(params) { /** * Whether or not the current WebKit Platform supports secure messaging @@ -5081,13 +5278,13 @@ class WebkitMessagingConfig { */ this.hasModernWebkitAPI = params.hasModernWebkitAPI; /** - * A list of WebKit message handler names that a user script can send - */ + * A list of WebKit message handler names that a user script can send + */ this.webkitMessageHandlerNames = params.webkitMessageHandlerNames; /** - * A string provided by native platforms to be sent with future outgoing - * messages - */ + * A string provided by native platforms to be sent with future outgoing + * messages + */ this.secret = params.secret; } } @@ -5099,28 +5296,28 @@ class WebkitMessagingConfig { exports.WebkitMessagingConfig = WebkitMessagingConfig; class SecureMessagingParams { /** - * @param {object} params - * @param {string} params.methodName - * @param {string} params.secret - * @param {number[]} params.key - * @param {number[]} params.iv - */ + * @param {object} params + * @param {string} params.methodName + * @param {string} params.secret + * @param {number[]} params.key + * @param {number[]} params.iv + */ constructor(params) { /** * The method that's been appended to `window` to be called later */ this.methodName = params.methodName; /** - * The secret used to ensure message sender validity - */ + * The secret used to ensure message sender validity + */ this.secret = params.secret; /** - * The CipherKey as number[] - */ + * The CipherKey as number[] + */ this.key = params.key; /** - * The Initial Vector as number[] - */ + * The Initial Vector as number[] + */ this.iv = params.iv; } } @@ -5331,7 +5528,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && * }} PasswordParameters */ const defaults = Object.freeze({ - SCAN_SET_ORDER: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\\"'<>,.?/ ]", + SCAN_SET_ORDER: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\"\'<>,.?/ ]', defaultUnambiguousCharacters: 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789', defaultPasswordLength: _constants.constants.DEFAULT_MIN_LENGTH, defaultPasswordRules: _constants.constants.DEFAULT_PASSWORD_RULES, @@ -5458,7 +5655,7 @@ class Password { _requirementsFromRules(passwordRules) { /** @type {Requirements} */ const requirements = {}; - for (let rule of passwordRules) { + for (const rule of passwordRules) { if (rule.name === parser.RuleName.ALLOWED) { console.assert(!('PasswordAllowedCharacters' in requirements)); const chars = this._charactersFromCharactersClasses(rule.value); @@ -5789,7 +5986,7 @@ class Password { */ _charactersFromCharactersClasses(characterClasses) { const output = []; - for (let characterClass of characterClasses) { + for (const characterClass of characterClasses) { output.push(...this._scanSetFromCharacterClass(characterClass)); } return output; @@ -5803,9 +6000,9 @@ class Password { if (!characters.length) { return ''; } - let shadowCharacters = Array.prototype.slice.call(characters); + const shadowCharacters = Array.prototype.slice.call(characters); shadowCharacters.sort((a, b) => this.options.SCAN_SET_ORDER.indexOf(a) - this.options.SCAN_SET_ORDER.indexOf(b)); - let uniqueCharacters = [shadowCharacters[0]]; + const uniqueCharacters = [shadowCharacters[0]]; for (let i = 1, length = shadowCharacters.length; i < length; ++i) { if (shadowCharacters[i] === shadowCharacters[i - 1]) { continue; @@ -5845,6 +6042,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.SHOULD_NOT_BE_REACHED = exports.RuleName = exports.Rule = exports.ParserError = exports.NamedCharacterClass = exports.Identifier = exports.CustomCharacterClass = void 0; exports.parsePasswordRules = parsePasswordRules; +/* eslint-disable no-var */ // Copyright (c) 2019 - 2020 Apple Inc. Licensed under MIT License. /* @@ -5897,7 +6095,6 @@ class Rule { } } exports.Rule = Rule; -; class NamedCharacterClass { constructor(name) { console.assert(_isValidRequiredOrAllowedPropertyValueIdentifier(name)); @@ -5914,10 +6111,8 @@ class NamedCharacterClass { } } exports.NamedCharacterClass = NamedCharacterClass; -; class ParserError extends Error {} exports.ParserError = ParserError; -; class CustomCharacterClass { constructor(characters) { console.assert(characters instanceof Array); @@ -5933,14 +6128,11 @@ class CustomCharacterClass { return `[${this._characters.join('').replace('"', '"')}]`; } } -exports.CustomCharacterClass = CustomCharacterClass; -; // MARK: Lexer functions - +exports.CustomCharacterClass = CustomCharacterClass; function _isIdentifierCharacter(c) { console.assert(c.length === 1); - // eslint-disable-next-line no-mixed-operators return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-'; } function _isASCIIDigit(c) { @@ -5986,14 +6178,14 @@ function _markBitsForNamedCharacterClass(bitSet, namedCharacterClass) { } } function _markBitsForCustomCharacterClass(bitSet, customCharacterClass) { - for (let character of customCharacterClass.characters) { + for (const character of customCharacterClass.characters) { bitSet[_bitSetIndexForCharacter(character)] = true; } } function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFormatCompliant) { // @ts-ignore - let asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); - for (let propertyValue of propertyValues) { + const asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); + for (const propertyValue of propertyValues) { if (propertyValue instanceof NamedCharacterClass) { if (propertyValue.name === Identifier.UNICODE) { return [new NamedCharacterClass(Identifier.UNICODE)]; @@ -6008,32 +6200,32 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo } let charactersSeen = []; function checkRange(start, end) { - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(start); i <= _bitSetIndexForCharacter(end); ++i) { if (asciiPrintableBitSet[i]) { temp.push(_characterAtBitSetIndex(i)); } } - let result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; + const result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; if (!result) { charactersSeen = charactersSeen.concat(temp); } return result; } - let hasAllUpper = checkRange('A', 'Z'); - let hasAllLower = checkRange('a', 'z'); - let hasAllDigits = checkRange('0', '9'); + const hasAllUpper = checkRange('A', 'Z'); + const hasAllLower = checkRange('a', 'z'); + const hasAllDigits = checkRange('0', '9'); // Check for special characters, accounting for characters that are given special treatment (i.e. '-' and ']') let hasAllSpecial = false; let hasDash = false; let hasRightSquareBracket = false; - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(' '); i <= _bitSetIndexForCharacter('/'); ++i) { if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === '-') { hasDash = true; } else { @@ -6049,7 +6241,7 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === ']') { hasRightSquareBracket = true; } else { @@ -6067,12 +6259,12 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (hasRightSquareBracket) { temp.push(']'); } - let numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); + const numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); hasAllSpecial = temp.length === numberOfSpecialCharacters; if (!hasAllSpecial) { charactersSeen = charactersSeen.concat(temp); } - let result = []; + const result = []; if (hasAllUpper && hasAllLower && hasAllDigits && hasAllSpecial) { return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]; } @@ -6100,7 +6292,7 @@ function _indexOfNonWhitespaceCharacter(input) { let position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; console.assert(position >= 0); console.assert(position <= input.length); - let length = input.length; + const length = input.length; while (position < length && _isASCIIWhitespace(input[position])) { ++position; } @@ -6110,10 +6302,10 @@ function _parseIdentifier(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - let seenIdentifiers = []; + const length = input.length; + const seenIdentifiers = []; do { - let c = input[position]; + const c = input[position]; if (!_isIdentifierCharacter(c)) { break; } @@ -6129,16 +6321,16 @@ function _parseCustomCharacterClass(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(input[position] === CHARACTER_CLASS_START_SENTINEL); - let length = input.length; + const length = input.length; ++position; if (position >= length) { // console.error('Found end-of-line instead of character class character') return [null, position]; } - let initialPosition = position; - let result = []; + const initialPosition = position; + const result = []; do { - let c = input[position]; + const c = input[position]; if (!_isASCIIPrintableCharacter(c)) { ++position; continue; @@ -6174,11 +6366,11 @@ function _parseCustomCharacterClass(input, position) { function _parsePasswordRequiredOrAllowedPropertyValue(input, position) { console.assert(position >= 0); console.assert(position < input.length); - let length = input.length; - let propertyValues = []; + const length = input.length; + const propertyValues = []; while (true) { if (_isIdentifierCharacter(input[position])) { - let identifierStartPosition = position; + const identifierStartPosition = position; // eslint-disable-next-line no-redeclare var [propertyValue, position] = _parseIdentifier(input, position); if (!_isValidRequiredOrAllowedPropertyValueIdentifier(propertyValue)) { @@ -6225,8 +6417,8 @@ function _parsePasswordRule(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - var mayBeIdentifierStartPosition = position; + const length = input.length; + const mayBeIdentifierStartPosition = position; // eslint-disable-next-line no-redeclare var [identifier, position] = _parseIdentifier(input, position); if (!Object.values(RuleName).includes(identifier)) { @@ -6241,7 +6433,7 @@ function _parsePasswordRule(input, position) { // console.error('Failed to find start of property value: ' + input.substr(position)) return [null, position, undefined]; } - let property = { + const property = { name: identifier, value: null }; @@ -6297,7 +6489,7 @@ function _parseInteger(input, position) { // console.error('Failed to parse value of type integer; not a number: ' + input.substr(position)) return [null, position]; } - let length = input.length; + const length = input.length; // let initialPosition = position let result = 0; do { @@ -6318,8 +6510,8 @@ function _parseInteger(input, position) { * @private */ function _parsePasswordRulesInternal(input) { - let parsedProperties = []; - let length = input.length; + const parsedProperties = []; + const length = input.length; var position = _indexOfNonWhitespaceCharacter(input); while (position < length) { if (!_isIdentifierCharacter(input[position])) { @@ -6356,7 +6548,7 @@ function _parsePasswordRulesInternal(input) { * @returns {Rule[]} */ function parsePasswordRules(input, formatRulesForMinifiedVersion) { - let [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); + const [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); if (!passwordRules) { throw new ParserError(maybeMessage); } @@ -6366,13 +6558,13 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { // When formatting rules for minified version, we should keep the formatted rules // as similar to the input as possible. Avoid copying required rules to allowed rules. - let suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; - let requiredRules = []; + const suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; + const requiredRules = []; let newAllowedValues = []; let minimumMaximumConsecutiveCharacters = null; let maximumMinLength = 0; let minimumMaxLength = null; - for (let rule of passwordRules) { + for (const rule of passwordRules) { switch (rule.name) { case RuleName.MAX_CONSECUTIVE: minimumMaximumConsecutiveCharacters = minimumMaximumConsecutiveCharacters ? Math.min(rule.value, minimumMaximumConsecutiveCharacters) : rule.value; @@ -6405,10 +6597,10 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { if (minimumMaximumConsecutiveCharacters !== null) { newPasswordRules.push(new Rule(RuleName.MAX_CONSECUTIVE, minimumMaximumConsecutiveCharacters)); } - let sortedRequiredRules = requiredRules.sort(function (a, b) { + const sortedRequiredRules = requiredRules.sort(function (a, b) { const namedCharacterClassOrder = [Identifier.LOWER, Identifier.UPPER, Identifier.DIGIT, Identifier.SPECIAL, Identifier.ASCII_PRINTABLE, Identifier.UNICODE]; - let aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; - let bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; + const aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; + const bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; if (aIsJustOneNamedCharacterClass && !bIsJustOneNamedCharacterClass) { return -1; } @@ -6416,8 +6608,8 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return 1; } if (aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { - let aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); - let bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); + const aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); + const bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); return aIndex - bIndex; } return 0; @@ -7062,6 +7254,9 @@ module.exports={ "keldoc.com": { "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*];" }, + "kennedy-center.org": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&*?@];" + }, "key.harvard.edu": { "password-rules": "minlength: 10; maxlength: 100; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^[']];" }, @@ -7574,8 +7769,8 @@ class CredentialsImport { activeInput?.focus(); } async started() { - this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); this.device.deviceApi.notify(new _deviceApiCalls.StartCredentialsImportFlowCall({})); + this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); } async dismissed() { this.device.deviceApi.notify(new _deviceApiCalls.CredentialsImportFlowPermanentlyDismissedCall(null)); @@ -7619,7 +7814,7 @@ function createDevice() { }; // Create the DeviceAPI + Setting - let deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); + const deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); const settings = new _Settings.Settings(globalConfig, deviceApi); if (globalConfig.isWindows) { if (globalConfig.isTopFrame) { @@ -7753,9 +7948,9 @@ class AndroidInterface extends _InterfacePrototype.default { } /** - * Used by the email web app - * Provides functionality to log the user out - */ + * Used by the email web app + * Provides functionality to log the user out + */ removeUserData() { try { return window.EmailInterface.removeCredentials(); @@ -9024,14 +9219,16 @@ class InterfacePrototype { }); break; default: - // Also fire pixel when filling an identity with the personal duck address from an email field - const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; - if (checks.every(Boolean)) { - this.firePixel({ - pixelName: 'autofill_personal_address' - }); + { + // Also fire pixel when filling an identity with the personal duck address from an email field + const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; + if (checks.every(Boolean)) { + this.firePixel({ + pixelName: 'autofill_personal_address' + }); + } + break; } - break; } } // some platforms do not include a `success` object, why? @@ -9279,13 +9476,15 @@ class InterfacePrototype { postSubmit(values, form) { if (!form.form) return; if (!form.hasValues(values)) return; - const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated]; + const shouldTriggerPartialSave = Object.keys(values?.credentials || {}).length === 1 && Boolean(values?.credentials?.username) && this.settings.featureToggles.partial_form_saves; + const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated, shouldTriggerPartialSave]; if (checks.some(Boolean)) { const formData = (0, _Credentials.appendGeneratedKey)(values, { password: this.passwordGenerator.password, username: this.emailProtection.lastGenerated }); - this.storeFormData(formData, 'formSubmission'); + const trigger = shouldTriggerPartialSave ? 'partialSave' : 'formSubmission'; + this.storeFormData(formData, trigger); } } @@ -9706,6 +9905,7 @@ function initFormSubmissionsApi(forms, matching) { // @ts-ignore if (btns.find(btn => btn.contains(realTarget))) return true; + return false; }); matchingForm?.submitHandler('global pointerdown event + matching form'); if (!matchingForm) { @@ -9801,7 +10001,7 @@ function overlayApi(device) { * @returns {Promise} */ async selectedDetail(data, type) { - let detailsEntries = Object.entries(data).map(_ref => { + const detailsEntries = Object.entries(data).map(_ref => { let [key, value] = _ref; return [key, String(value)]; }); @@ -10064,7 +10264,7 @@ class Form { */ getValuesReadyForStorage() { const formValues = this.getRawValues(); - return (0, _formatters.prepareFormValuesForStorage)(formValues); + return (0, _formatters.prepareFormValuesForStorage)(formValues, this.device.settings.featureToggles.partial_form_saves); } /** @@ -10095,7 +10295,7 @@ class Form { if (!input.classList.contains('ddg-autofilled')) return; (0, _autofillUtils.removeInlineStyles)(input, (0, _inputStyles.getIconStylesAutofilled)(input, this)); (0, _autofillUtils.removeInlineStyles)(input, { - 'cursor': 'pointer' + cursor: 'pointer' }); input.classList.remove('ddg-autofilled'); this.addAutofillStyles(input); @@ -10216,20 +10416,10 @@ class Form { if (this.form.matches(selector)) { this.addInput(this.form); } else { - /** @type {Element[] | NodeList} */ - let foundInputs = []; - // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. - if (this.form instanceof HTMLFormElement && this.form.elements != null && Symbol.iterator in Object(this.form.elements)) { - // For form elements we use .elements to catch fields outside the form itself using the form attribute. - // It also catches all elements when the markup is broken. - // We use .filter to avoid fieldset, button, textarea etc. - const formElements = [...this.form.elements].filter(el => el.matches(selector)); - // If there are no form elements, we try to look for all - // enclosed elements within the form. - foundInputs = formElements.length > 0 ? formElements : (0, _autofillUtils.findEnclosedElements)(this.form, selector); - } else { - foundInputs = this.form.querySelectorAll(selector); - } + // Attempt to get form's control elements first as it can catch elements when markup is broke, or if the fields are outside the form. + // Other wise use queryElementsWithShadow, that can scan for shadow tree. + const formControlElements = (0, _autofillUtils.getFormControlElements)(this.form, selector); + const foundInputs = formControlElements != null ? [...formControlElements, ...(0, _autofillUtils.findElementsInShadowTree)(this.form, selector)] : (0, _autofillUtils.queryElementsWithShadow)(this.form, selector, true); if (foundInputs.length < MAX_INPUTS_PER_FORM) { foundInputs.forEach(input => this.addInput(input)); } else { @@ -10290,7 +10480,7 @@ class Form { } get submitButtons() { const selector = this.matching.cssSelector('submitButtonSelector'); - const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.findEnclosedElements)(this.form, selector); + const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.queryElementsWithShadow)(this.form, selector); return allButtons.filter(btn => (0, _autofillUtils.isPotentiallyViewable)(btn) && (0, _autofillUtils.isLikelyASubmitButton)(btn, this.matching) && (0, _autofillUtils.buttonMatchesFormType)(btn, this)); } attemptSubmissionIfNeeded() { @@ -10413,12 +10603,12 @@ class Form { if ((0, _autofillUtils.wasAutofilledByChrome)(input)) return; if ((0, _autofillUtils.isEventWithinDax)(e, e.target)) { (0, _autofillUtils.addInlineStyles)(e.target, { - 'cursor': 'pointer', + cursor: 'pointer', ...onMouseMove }); } else { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -10430,7 +10620,7 @@ class Form { }); this.addListener(input, 'mouseleave', e => { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -10528,7 +10718,7 @@ class Form { this.touched.add(input); this.device.attachTooltip({ form: this, - input: input, + input, click: clickCoords, trigger: 'userInitiated', triggerMetaData: { @@ -10757,7 +10947,7 @@ class Form { }, 'credentials'); this.device.attachTooltip({ form: this, - input: input, + input, click: null, trigger: 'autoprompt', triggerMetaData: { @@ -10992,6 +11182,23 @@ class FormAnalyzer { } }); } + + /** + * Function that checks if the element is an external link or a custom web element that + * encapsulates a link. + * @param {any} el + * @returns {boolean} + */ + isElementExternalLink(el) { + // Checks if the element is present in the cusotm elements registry and ends with a '-link' suffix. + // If it does, it checks if it contains an anchor element inside. + const tagName = el.nodeName.toLowerCase(); + const isCustomWebElementLink = customElements?.get(tagName) != null && /-link$/.test(tagName) && (0, _autofillUtils.findElementsInShadowTree)(el, 'a').length > 0; + + // if an external link matches one of the regexes, we assume the match is not pertinent to the current form + const isElementLink = el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]'); + return isCustomWebElementLink || isElementLink; + } evaluateElement(el) { const string = (0, _autofillUtils.getTextShallow)(el); if (el.matches(this.matching.cssSelector('password'))) { @@ -11012,7 +11219,7 @@ class FormAnalyzer { if (likelyASubmit) { this.form.querySelectorAll('input[type=submit], button[type=submit]').forEach(submit => { // If there is another element marked as submit and this is not, flip back to false - if (el.type !== 'submit' && el !== submit) { + if (el.getAttribute('type') !== 'submit' && el !== submit) { likelyASubmit = false; } }); @@ -11031,8 +11238,7 @@ class FormAnalyzer { }); return; } - // if an external link matches one of the regexes, we assume the match is not pertinent to the current form - if (el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]')) { + if (this.isElementExternalLink(el)) { let shouldFlip = true; let strength = 1; // Don't flip forgotten password links @@ -11051,9 +11257,10 @@ class FormAnalyzer { }); } else { // any other case + const isH1Element = el.tagName === 'H1'; this.updateSignal({ string, - strength: 1, + strength: isH1Element ? 3 : 1, signalType: `generic: ${string}`, shouldCheckUnifiedForm: true }); @@ -11071,7 +11278,7 @@ class FormAnalyzer { // Check form contents (noisy elements are skipped with the safeUniversalSelector) const selector = this.matching.cssSelector('safeUniversalSelector'); - const formElements = (0, _autofillUtils.findEnclosedElements)(this.form, selector); + const formElements = (0, _autofillUtils.queryElementsWithShadow)(this.form, selector); for (let i = 0; i < formElements.length; i++) { // Safety cutoff to avoid huge DOMs freezing the browser if (i >= 200) break; @@ -11131,7 +11338,7 @@ class FormAnalyzer { } // Match form textContent against common cc fields (includes hidden labels) - const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig); + const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/gi); // De-dupe matches to avoid counting the same element more than once const deDupedMatches = new Set(textMatches?.map(match => match.toLowerCase())); @@ -11450,7 +11657,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Anguilla: 'AI', Albania: 'AL', Armenia: 'AM', - 'Curaçao': 'CW', + Curaçao: 'CW', Angola: 'AO', Antarctica: 'AQ', Argentina: 'AR', @@ -11639,7 +11846,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Paraguay: 'PY', Qatar: 'QA', 'Outlying Oceania': 'QO', - 'Réunion': 'RE', + Réunion: 'RE', Zimbabwe: 'ZW', Romania: 'RO', Russia: 'SU', @@ -11716,6 +11923,7 @@ Object.defineProperty(exports, "__esModule", { exports.prepareFormValuesForStorage = exports.inferCountryCodeFromElement = exports.getUnifiedExpiryDate = exports.getMMAndYYYYFromString = exports.getCountryName = exports.getCountryDisplayName = exports.formatPhoneNumber = exports.formatFullName = exports.formatCCYear = void 0; var _matching = require("./matching.js"); var _countryNames = require("./countryNames.js"); +var _autofillUtils = require("../autofill-utils.js"); // Matches strings like mm/yy, mm-yyyy, mm-aa, 12 / 2024 const DATE_SEPARATOR_REGEX = /\b((.)\2{1,3}|\d+)(?\s?[/\s.\-_—–]\s?)((.)\5{1,3}|\d+)\b/i; // Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) @@ -11884,36 +12092,25 @@ const getMMAndYYYYFromString = expiration => { }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ exports.getMMAndYYYYFromString = getMMAndYYYYFromString; -const shouldStoreCredentials = _ref3 => { - let { - credentials - } = _ref3; - return Boolean(credentials.password); -}; - -/** - * @param {InternalDataStorageObject} credentials - * @return {boolean} - */ -const shouldStoreIdentities = _ref4 => { +const shouldStoreIdentities = _ref3 => { let { identities - } = _ref4; + } = _ref3; return Boolean((identities.firstName || identities.fullName) && identities.addressStreet && identities.addressCity); }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ -const shouldStoreCreditCards = _ref5 => { +const shouldStoreCreditCards = _ref4 => { let { creditCards - } = _ref5; + } = _ref4; if (!creditCards.cardNumber) return false; if (creditCards.cardSecurityCode) return true; // Some forms (Amazon) don't have the cvv, so we still save if there's the expiration @@ -11936,7 +12133,8 @@ const formatPhoneNumber = phone => phone.replaceAll(/[^0-9|+]/g, ''); * @return {DataStorageObject} */ exports.formatPhoneNumber = formatPhoneNumber; -const prepareFormValuesForStorage = formValues => { +const prepareFormValuesForStorage = function (formValues) { + let canTriggerPartialSave = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; /** @type {Partial} */ let { credentials, @@ -11949,14 +12147,15 @@ const prepareFormValuesForStorage = formValues => { creditCards.cardName = identities?.fullName || formatFullName(identities); } - /** Fixes for credentials **/ - // Don't store if there isn't enough data - if (shouldStoreCredentials(formValues)) { - // If we don't have a username to match a password, let's see if the email is available - if (credentials.password && !credentials.username && identities.emailAddress) { - credentials.username = identities.emailAddress; - } - } else { + /** Fixes for credentials */ + // If we don't have a username to match a password, let's see if email or phone are available + if (credentials.password && !credentials.username && (0, _autofillUtils.hasUsernameLikeIdentity)(identities)) { + // @ts-ignore - username will be likely undefined, but needs to be specifically assigned to a string value + credentials.username = identities.emailAddress || identities.phone; + } + + // If there's no password, and we shouldn't trigger a partial save, let's discard the object + if (!credentials.password && !canTriggerPartialSave) { credentials = undefined; } @@ -12012,7 +12211,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":36,"./matching.js":44}],38:[function(require,module,exports){ +},{"../autofill-utils.js":64,"./countryNames.js":36,"./matching.js":44}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12055,7 +12254,7 @@ const getBasicStyles = (input, icon) => ({ 'background-repeat': 'no-repeat', 'background-origin': 'content-box', 'background-image': `url(${icon})`, - 'transition': 'background 0s' + transition: 'background 0s' }); /** @@ -12098,7 +12297,7 @@ const getIconStylesAutofilled = (input, form) => { return { ...iconStyle, 'background-color': '#F8F498', - 'color': '#333333' + color: '#333333' }; }; exports.getIconStylesAutofilled = getIconStylesAutofilled; @@ -12386,14 +12585,14 @@ const extractElementStrings = element => { // only take the string when it's an explicit text node if (el.nodeType === el.TEXT_NODE || !el.childNodes.length) { - let trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); + const trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); if (trimmedText) { strings.add(trimmedText); } return; } - for (let node of el.childNodes) { - let nodeType = node.nodeType; + for (const node of el.childNodes) { + const nodeType = node.nodeType; if (nodeType !== node.ELEMENT_NODE && nodeType !== node.TEXT_NODE) { continue; } @@ -12795,7 +12994,7 @@ const matchingConfiguration = exports.matchingConfiguration = { match: /sign.?up|join|register|enroll|(create|new).+account|newsletter|subscri(be|ption)|settings|preferences|profile|update|iscri(viti|zione)|registra(ti|zione)|(?:nuovo|crea(?:zione)?) account|contatt(?:ac)?i|sottoscriv|sottoscrizione|impostazioni|preferenze|aggiorna|anmeld(en|ung)|registrier(en|ung)|neukunde|neuer (kunde|benutzer|nutzer)|registreren|eigenschappen|profiel|bijwerken|s.inscrire|inscription|s.abonner|abonnement|préférences|profil|créer un compte|regis(trarse|tro)|regístrate|inscr(ibirse|ipción|íbete)|crea(r cuenta)?|nueva cuenta|nuevo (cliente|usuario)|preferencias|perfil|lista de correo|registrer(a|ing)|(nytt|öppna) konto|nyhetsbrev|prenumer(era|ation)|kontakt|skapa|starta|inställningar|min (sida|kundvagn)|uppdatera/iu }, resetPasswordLink: { - match: /(forgot(ten)?|reset|don't remember) (your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu + match: /(forgot(ten)?|reset|don't remember).?(your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu }, loginProvidersRegex: { match: / with | con | mit | met | avec /iu @@ -13060,8 +13259,8 @@ class Matching { * * `email: [{type: "email", strategies: {cssSelector: "email", ... etc}]` */ - for (let [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { - for (let fieldName of matcherNames) { + for (const [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { + for (const fieldName of matcherNames) { if (!this.#matcherLists[listName]) { this.#matcherLists[listName] = []; } @@ -13178,7 +13377,7 @@ class Matching { * @type {string[]} */ const selectors = []; - for (let matcher of matcherList) { + for (const matcher of matcherList) { if (matcher.strategies.cssSelector) { const css = this.cssSelector(matcher.strategies.cssSelector); if (css) { @@ -13315,12 +13514,12 @@ class Matching { /** * Loop through each strategy in order */ - for (let strategyName of this.#defaultStrategyOrder) { + for (const strategyName of this.#defaultStrategyOrder) { let result; /** * Now loop through each matcher in the list. */ - for (let matcher of matchers) { + for (const matcher of matchers) { /** * for each `strategyName` (such as cssSelector), check * if the current matcher implements it. @@ -13445,16 +13644,16 @@ class Matching { if (!ddgMatcher || !ddgMatcher.match) { return defaultResult; } - let matchRexExp = this.getDDGMatcherRegex(lookup); + const matchRexExp = this.getDDGMatcherRegex(lookup); if (!matchRexExp) { return defaultResult; } - let requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; + const requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; /** @type {MatchableStrings[]} */ const matchableStrings = ddgMatcher.matchableStrings || ['labelText', 'placeholderAttr', 'relatedText']; - for (let stringName of matchableStrings) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of matchableStrings) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; // Scoring to ensure all DDG tests are valid @@ -13470,7 +13669,7 @@ class Matching { // If a negated regex was provided, ensure it does not match // If it DOES match - then we need to prevent any future strategies from continuing if (ddgMatcher.forceUnknown) { - let notRegex = ddgMatcher.forceUnknown; + const notRegex = ddgMatcher.forceUnknown; if (!notRegex) { return { ...result, @@ -13489,7 +13688,7 @@ class Matching { } } if (ddgMatcher.skip) { - let skipRegex = ddgMatcher.skip; + const skipRegex = ddgMatcher.skip; if (!skipRegex) { return { ...result, @@ -13554,8 +13753,8 @@ class Matching { } /** @type {MatchableStrings[]} */ const stringsToMatch = ['placeholderAttr', 'nameAttr', 'labelText', 'id', 'relatedText']; - for (let stringName of stringsToMatch) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of stringsToMatch) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; if ((0, _autofillUtils.safeRegexTest)(regex, elementString)) { return { @@ -13629,14 +13828,14 @@ class Matching { fields: {} }, strategies: { - 'vendorRegex': { + vendorRegex: { rules: {}, ruleSets: [] }, - 'ddgMatcher': { + ddgMatcher: { matchers: {} }, - 'cssSelector': { + cssSelector: { selectors: {} } } @@ -13807,7 +14006,7 @@ const removeExcessWhitespace = function () { exports.removeExcessWhitespace = removeExcessWhitespace; const getExplicitLabelsText = el => { const labelTextCandidates = []; - for (let label of el.labels || []) { + for (const label of el.labels || []) { labelTextCandidates.push(...(0, _labelUtil.extractElementStrings)(label)); } if (el.hasAttribute('aria-label')) { @@ -13862,7 +14061,7 @@ const getRelatedText = (el, form, cssSelector) => { // If we didn't find a container, try looking for an adjacent label if (scope === el) { - let previousEl = recursiveGetPreviousElSibling(el); + const previousEl = recursiveGetPreviousElSibling(el); if (previousEl instanceof HTMLElement) { scope = previousEl; } @@ -14521,19 +14720,18 @@ class DefaultScanner { if (this.device.globalConfig.isDDGDomain) { return this; } - if ('matches' in context && context.matches?.(this.matching.cssSelector('formInputsSelectorWithoutSelect'))) { + const formInputsSelectorWithoutSelect = this.matching.cssSelector('formInputsSelectorWithoutSelect'); + if ('matches' in context && context.matches?.(formInputsSelectorWithoutSelect)) { this.addInput(context); } else { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - const inputs = context.querySelectorAll(selector); + const inputs = context.querySelectorAll(formInputsSelectorWithoutSelect); if (inputs.length > this.options.maxInputsPerPage) { this.setMode('stopped', `Too many input fields in the given context (${inputs.length}), stop scanning`, context); return this; } inputs.forEach(input => this.addInput(input)); if (context instanceof HTMLFormElement && this.forms.get(context)?.hasShadowTree) { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - (0, _autofillUtils.findEnclosedElements)(context, selector).forEach(input => { + (0, _autofillUtils.findElementsInShadowTree)(context, formInputsSelectorWithoutSelect).forEach(input => { if (input instanceof HTMLInputElement) { this.addInput(input, context); } @@ -14619,12 +14817,16 @@ class DefaultScanner { } if (element.parentElement) { element = element.parentElement; - const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); - const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); - // If we find a button or another input, we assume that's our form - if (inputs.length > 1 || buttons.length) { - // found related input, return common ancestor - return element; + // If the parent is a redundant component (only contains a single element or is a shadowRoot) do not increase the traversal count. + if (element.childElementCount > 1) { + const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); + const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); + // If we find a button or another input, we assume that's our form + if (inputs.length > 1 || buttons.length) { + // found related input, return common ancestor + return element; + } + traversalLayerCount++; } } else { // possibly a shadow boundary, so traverse through the shadow root and find the form @@ -14632,9 +14834,11 @@ class DefaultScanner { if (root instanceof ShadowRoot && root.host) { // @ts-ignore element = root.host; + } else { + // We're in a strange state (no parent or shadow root), just break out of the loop for safety + break; } } - traversalLayerCount++; } return input; } @@ -14717,7 +14921,7 @@ class DefaultScanner { this.changedElements.clear(); } else if (!this.rescanAll) { // otherwise keep adding each element to the queue - for (let element of htmlElements) { + for (const element of htmlElements) { this.changedElements.add(element); } } @@ -14741,7 +14945,7 @@ class DefaultScanner { this.findEligibleInputs(document); return; } - for (let element of this.changedElements) { + for (const element of this.changedElements) { if (element.isConnected) { this.findEligibleInputs(element); } @@ -14762,7 +14966,7 @@ class DefaultScanner { const outgoing = []; for (const mutationRecord of mutationList) { if (mutationRecord.type === 'childList') { - for (let addedNode of mutationRecord.addedNodes) { + for (const addedNode of mutationRecord.addedNodes) { if (!(addedNode instanceof HTMLElement)) continue; if (addedNode.nodeName === 'DDG-AUTOFILL') continue; outgoing.push(addedNode); @@ -14796,12 +15000,13 @@ class DefaultScanner { // find the enclosing parent form, and scan it. if (realTarget instanceof HTMLInputElement && !realTarget.hasAttribute(ATTR_INPUT_TYPE)) { const parentForm = this.getParentForm(realTarget); - if (parentForm && parentForm instanceof HTMLFormElement) { - const hasShadowTree = event.target?.shadowRoot != null; - const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); - this.forms.set(parentForm, form); - this.findEligibleInputs(parentForm); - } + + // If the parent form is an input element we bail. + if (parentForm instanceof HTMLInputElement) return; + const hasShadowTree = event.target?.shadowRoot != null; + const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); + this.forms.set(parentForm, form); + this.findEligibleInputs(parentForm); } window.performance?.mark?.('scan_shadow:init:end'); (0, _autofillUtils.logPerformance)('scan_shadow'); @@ -15176,7 +15381,8 @@ class Settings { inputType_credentials: false, inputType_creditCards: false, inlineIcon_credentials: false, - unknown_username_categorization: false + unknown_username_categorization: false, + partial_form_saves: false }, /** @type {AvailableInputTypes} */ availableInputTypes: { @@ -15500,7 +15706,7 @@ ${css} if (btn.matches('.wrapper:not(.top-autofill) button:hover, .currentFocus')) { callbacks.onSelect(btn.id); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } }); }); @@ -15704,7 +15910,9 @@ const defaultOptions = exports.defaultOptions = { }`, css: ``, setSize: undefined, - remove: () => {/** noop */}, + remove: () => { + /** noop */ + }, testMode: false, checkVisibility: true, hasCaret: false, @@ -15732,9 +15940,9 @@ class HTMLTooltip { this.tooltip = null; this.getPosition = getPosition; const forcedVisibilityStyles = { - 'display': 'block', - 'visibility': 'visible', - 'opacity': '1' + display: 'block', + visibility: 'visible', + opacity: '1' }; // @ts-ignore how to narrow this.host to HTMLElement? (0, _autofillUtils.addInlineStyles)(this.host, forcedVisibilityStyles); @@ -15992,7 +16200,7 @@ class HTMLTooltip { checkVisibility: this.options.checkVisibility }); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } } } @@ -16374,25 +16582,27 @@ class HTMLTooltipUIController extends _UIController.UIController { /** * Called when clicking on the Manage… button in the html tooltip - * * @param {SupportedMainTypes} type * @returns {*} * @private */ _onManage(type) { - this.removeTooltip(); switch (type) { case 'credentials': - return this._options.device.openManagePasswords(); + this._options.device.openManagePasswords(); + break; case 'creditCards': - return this._options.device.openManageCreditCards(); + this._options.device.openManageCreditCards(); + break; case 'identities': - return this._options.device.openManageIdentities(); + this._options.device.openManageIdentities(); + break; default: // noop } - } + this.removeTooltip(); + } _onIncontextSignupDismissed(_ref) { let { hasOtherOptions @@ -16936,10 +17146,14 @@ Object.defineProperty(exports, "__esModule", { }); exports.buttonMatchesFormType = exports.autofillEnabled = exports.addInlineStyles = exports.SIGN_IN_MSG = exports.ADDRESS_DOMAIN = void 0; exports.escapeXML = escapeXML; -exports.findEnclosedElements = findEnclosedElements; +exports.findElementsInShadowTree = findElementsInShadowTree; exports.formatDuckAddress = void 0; exports.getActiveElement = getActiveElement; -exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = exports.getTextShallow = exports.getDaxBoundingBox = void 0; +exports.getDaxBoundingBox = void 0; +exports.getFormControlElements = getFormControlElements; +exports.getTextShallow = void 0; +exports.hasUsernameLikeIdentity = hasUsernameLikeIdentity; +exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = void 0; exports.isFormLikelyToBeUsedAsPageWrapper = isFormLikelyToBeUsedAsPageWrapper; exports.isLikelyASubmitButton = exports.isIncontextSignupEnabledFromProcessedConfig = void 0; exports.isLocalNetwork = isLocalNetwork; @@ -16948,6 +17162,7 @@ exports.isValidTLD = isValidTLD; exports.logPerformance = logPerformance; exports.notifyWebApp = void 0; exports.pierceShadowTree = pierceShadowTree; +exports.queryElementsWithShadow = queryElementsWithShadow; exports.safeExecute = exports.removeInlineStyles = void 0; exports.safeRegexTest = safeRegexTest; exports.setValue = exports.sendAndWaitForAnswer = void 0; @@ -17320,8 +17535,9 @@ const isLikelyASubmitButton = (el, matching) => { // has high-signal submit classes safeRegexTest(/submit/i, dataTestId) || safeRegexTest(matching.getDDGMatcherRegex('submitButtonRegex'), text) || // has high-signal text - el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className) // it's a large element 250x40px - ) && el.offsetHeight * el.offsetWidth >= 2000 && + el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className)) && + // it's a large element 250x40px + el.offsetHeight * el.offsetWidth >= 2000 && // it's not a very small button like inline links and such !safeRegexTest(matching.getDDGMatcherRegex('submitButtonUnlikelyRegex'), text + ' ' + ariaLabel); }; @@ -17549,22 +17765,16 @@ function getActiveElement() { } /** - * Takes a root element and tries to find visible elements first, and if it fails, it tries to find shadow elements + * Takes a root element and tries to find elements in shadow DOMs that match the selector * @param {HTMLElement|HTMLFormElement} root * @param {string} selector * @returns {Element[]} */ -function findEnclosedElements(root, selector) { - // Check if there are any normal elements that match the selector - const elements = root.querySelectorAll(selector); - if (elements.length > 0) { - return Array.from(elements); - } - - // Check if there are any shadow elements that match the selector +function findElementsInShadowTree(root, selector) { const shadowElements = []; const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT); - let node = walker.nextNode(); + /** @type {Node|null} */ + let node = walker.currentNode; while (node) { if (node instanceof HTMLElement && node.shadowRoot) { shadowElements.push(...node.shadowRoot.querySelectorAll(selector)); @@ -17574,6 +17784,52 @@ function findEnclosedElements(root, selector) { return shadowElements; } +/** + * The function looks for form's control elements, and returns them if they're iterable. + * @param {HTMLElement} form + * @param {string} selector + * @returns {Element[]|null} + */ +function getFormControlElements(form, selector) { + // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. + if (form instanceof HTMLFormElement && form.elements != null && Symbol.iterator in Object(form.elements)) { + // For form elements we use .elements to catch fields outside the form itself using the form attribute. + // It also catches all elements when the markup is broken. + // We use .filter to avoid specific types of elements. + const formControls = [...form.elements].filter(el => el.matches(selector)); + return [...formControls]; + } else { + return null; + } +} + +/** + * Default operation: finds elements using querySelectorAll. + * Optionally, can be forced to scan the shadow tree. + * @param {HTMLElement} element + * @param {string} selector + * @param {boolean} forceScanShadowTree + * @returns {Element[]} + */ +function queryElementsWithShadow(element, selector) { + let forceScanShadowTree = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + /** @type {Element[]|NodeListOf} element */ + const elements = element.querySelectorAll(selector); + if (forceScanShadowTree || elements.length === 0) { + return [...elements, ...findElementsInShadowTree(element, selector)]; + } + return [...elements]; +} + +/** + * Checks if there is a single username-like identity, i.e. email or phone + * @param {InternalIdentityObject} identities + * @returns {boolean} + */ +function hasUsernameLikeIdentity(identities) { + return Object.keys(identities ?? {}).length === 1 && Boolean(identities?.emailAddress || identities.phone); +} + },{"./Form/matching.js":44,"./constants.js":67,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],65:[function(require,module,exports){ "use strict"; @@ -17613,7 +17869,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.DDG_DOMAIN_REGEX = void 0; exports.createGlobalConfig = createGlobalConfig; -const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/); +/* eslint-disable prefer-const */ +const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = /^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/; /** * This is a centralised place to contain all string/variable replacements @@ -18124,6 +18381,26 @@ const availableInputTypesSchema = exports.availableInputTypesSchema = _zod.z.obj credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = _zod.z.object({ + type: _zod.z.literal("getAutofillInitDataResponse").optional(), + success: _zod.z.object({ + credentials: _zod.z.array(credentialsSchema), + identities: _zod.z.array(_zod.z.record(_zod.z.unknown())), + creditCards: _zod.z.array(_zod.z.record(_zod.z.unknown())), + serializedInputContext: _zod.z.string() + }).optional(), + error: genericErrorSchema.optional() +}); +const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = _zod.z.object({ + type: _zod.z.literal("getAutofillCredentialsResponse").optional(), + success: _zod.z.object({ + id: _zod.z.string().optional(), + autogenerated: _zod.z.boolean().optional(), + username: _zod.z.string(), + password: _zod.z.string().optional() + }).optional(), + error: genericErrorSchema.optional() +}); const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.object({ credentials: _zod.z.object({ username: _zod.z.boolean().optional(), @@ -18156,6 +18433,11 @@ const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.o credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ + status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), + credentials: _zod.z.array(credentialsSchema), + availableInputTypes: availableInputTypes1Schema +}); const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = _zod.z.object({ inputType_credentials: _zod.z.boolean().optional(), inputType_identities: _zod.z.boolean().optional(), @@ -18166,56 +18448,8 @@ const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = _zod credentials_saving: _zod.z.boolean().optional(), inlineIcon_credentials: _zod.z.boolean().optional(), third_party_credentials_provider: _zod.z.boolean().optional(), - unknown_username_categorization: _zod.z.boolean().optional() -}); -const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = _zod.z.object({ - generatedPassword: generatedPasswordSchema.optional(), - inputType: _zod.z.string(), - mainType: _zod.z.union([_zod.z.literal("credentials"), _zod.z.literal("identities"), _zod.z.literal("creditCards")]), - subType: _zod.z.string(), - trigger: _zod.z.union([_zod.z.literal("userInitiated"), _zod.z.literal("autoprompt"), _zod.z.literal("postSignup")]).optional(), - serializedInputContext: _zod.z.string().optional(), - triggerContext: triggerContextSchema.optional() -}); -const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = _zod.z.object({ - type: _zod.z.literal("getAutofillDataResponse").optional(), - success: _zod.z.object({ - credentials: credentialsSchema.optional(), - action: _zod.z.union([_zod.z.literal("fill"), _zod.z.literal("focus"), _zod.z.literal("none"), _zod.z.literal("refreshAvailableInputTypes"), _zod.z.literal("acceptGeneratedPassword"), _zod.z.literal("rejectGeneratedPassword")]) - }).optional(), - error: genericErrorSchema.optional() -}); -const storeFormDataSchema = exports.storeFormDataSchema = _zod.z.object({ - credentials: outgoingCredentialsSchema.optional(), - trigger: _zod.z.union([_zod.z.literal("formSubmission"), _zod.z.literal("passwordGeneration"), _zod.z.literal("emailProtection")]).optional() -}); -const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = _zod.z.object({ - type: _zod.z.literal("getAvailableInputTypesResponse").optional(), - success: availableInputTypesSchema, - error: genericErrorSchema.optional() -}); -const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = _zod.z.object({ - type: _zod.z.literal("getAutofillInitDataResponse").optional(), - success: _zod.z.object({ - credentials: _zod.z.array(credentialsSchema), - identities: _zod.z.array(_zod.z.record(_zod.z.unknown())), - creditCards: _zod.z.array(_zod.z.record(_zod.z.unknown())), - serializedInputContext: _zod.z.string() - }).optional(), - error: genericErrorSchema.optional() -}); -const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = _zod.z.object({ - type: _zod.z.literal("getAutofillCredentialsResponse").optional(), - success: _zod.z.object({ - id: _zod.z.string().optional(), - autogenerated: _zod.z.boolean().optional(), - username: _zod.z.string(), - password: _zod.z.string().optional() - }).optional(), - error: genericErrorSchema.optional() -}); -const autofillSettingsSchema = exports.autofillSettingsSchema = _zod.z.object({ - featureToggles: autofillFeatureTogglesSchema + unknown_username_categorization: _zod.z.boolean().optional(), + partial_form_saves: _zod.z.boolean().optional() }); const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = _zod.z.object({ success: _zod.z.boolean().optional(), @@ -18251,19 +18485,30 @@ const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtection }).optional(), error: genericErrorSchema.optional() }); -const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = _zod.z.object({ - contentScope: contentScopeSchema, - userUnprotectedDomains: _zod.z.array(_zod.z.string()), - userPreferences: userPreferencesSchema +const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = _zod.z.object({ + generatedPassword: generatedPasswordSchema.optional(), + inputType: _zod.z.string(), + mainType: _zod.z.union([_zod.z.literal("credentials"), _zod.z.literal("identities"), _zod.z.literal("creditCards")]), + subType: _zod.z.string(), + trigger: _zod.z.union([_zod.z.literal("userInitiated"), _zod.z.literal("autoprompt"), _zod.z.literal("postSignup")]).optional(), + serializedInputContext: _zod.z.string().optional(), + triggerContext: triggerContextSchema.optional() }); -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ - status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), - credentials: _zod.z.array(credentialsSchema), - availableInputTypes: availableInputTypes1Schema +const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = _zod.z.object({ + type: _zod.z.literal("getAutofillDataResponse").optional(), + success: _zod.z.object({ + credentials: credentialsSchema.optional(), + action: _zod.z.union([_zod.z.literal("fill"), _zod.z.literal("focus"), _zod.z.literal("none"), _zod.z.literal("refreshAvailableInputTypes"), _zod.z.literal("acceptGeneratedPassword"), _zod.z.literal("rejectGeneratedPassword")]) + }).optional(), + error: genericErrorSchema.optional() }); -const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = _zod.z.object({ - type: _zod.z.literal("getRuntimeConfigurationResponse").optional(), - success: runtimeConfigurationSchema.optional(), +const storeFormDataSchema = exports.storeFormDataSchema = _zod.z.object({ + credentials: outgoingCredentialsSchema.optional(), + trigger: _zod.z.union([_zod.z.literal("partialSave"), _zod.z.literal("formSubmission"), _zod.z.literal("passwordGeneration"), _zod.z.literal("emailProtection")]).optional() +}); +const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = _zod.z.object({ + type: _zod.z.literal("getAvailableInputTypesResponse").optional(), + success: availableInputTypesSchema, error: genericErrorSchema.optional() }); const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = _zod.z.object({ @@ -18276,6 +18521,19 @@ const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProvi success: providerStatusUpdatedSchema, error: genericErrorSchema.optional() }); +const autofillSettingsSchema = exports.autofillSettingsSchema = _zod.z.object({ + featureToggles: autofillFeatureTogglesSchema +}); +const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = _zod.z.object({ + contentScope: contentScopeSchema, + userUnprotectedDomains: _zod.z.array(_zod.z.string()), + userPreferences: userPreferencesSchema +}); +const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = _zod.z.object({ + type: _zod.z.literal("getRuntimeConfigurationResponse").optional(), + success: runtimeConfigurationSchema.optional(), + error: genericErrorSchema.optional() +}); const apiSchema = exports.apiSchema = _zod.z.object({ addDebugFlag: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ paramsValidator: addDebugFlagParamsSchema.optional() @@ -18492,7 +18750,7 @@ function waitForResponse(expectedResponse, config) { return; } try { - let data = JSON.parse(e.data); + const data = JSON.parse(e.data); if (data.type === expectedResponse) { window.removeEventListener('message', handler); return resolve(data); @@ -18647,7 +18905,7 @@ async function extensionSpecificRuntimeConfiguration(deviceApi) { return { success: { // @ts-ignore - contentScope: contentScope, + contentScope, // @ts-ignore userPreferences: { // Copy locale to user preferences as 'language' to match expected payload @@ -18841,6 +19099,7 @@ function waitForWindowsResponse(responseId, options) { if (options?.signal?.aborted) { return reject(new DOMException('Aborted', 'AbortError')); } + // eslint-disable-next-line prefer-const let teardown; // The event handler @@ -21727,7 +21986,6 @@ exports.default = void 0; window.requestIdleCallback = window.requestIdleCallback || function (cb) { return setTimeout(function () { const start = Date.now(); - // eslint-disable-next-line standard/no-callback-literal cb({ didTimeout: false, timeRemaining: function () { diff --git a/node_modules/@duckduckgo/autofill/dist/autofill.js b/node_modules/@duckduckgo/autofill/dist/autofill.js index 6a97e06c86fa..c4584483dadf 100644 --- a/node_modules/@duckduckgo/autofill/dist/autofill.js +++ b/node_modules/@duckduckgo/autofill/dist/autofill.js @@ -269,8 +269,8 @@ class SchemaValidationError extends Error { } case 'invalid_union': { - for (let unionError of issue.unionErrors) { - for (let issue1 of unionError.issues) { + for (const unionError of issue.unionErrors) { + for (const issue1 of unionError.issues) { log(issue1); } } @@ -282,7 +282,7 @@ class SchemaValidationError extends Error { } } } - for (let error of errors) { + for (const error of errors) { log(error); } const message = [heading, 'please see the details above'].join('\n '); @@ -405,8 +405,8 @@ class DeviceApi { */ async request(deviceApiCall, options) { deviceApiCall.validateParams(); - let result = await this.transport.send(deviceApiCall, options); - let processed = deviceApiCall.preResultValidation(result); + const result = await this.transport.send(deviceApiCall, options); + const processed = deviceApiCall.preResultValidation(result); return deviceApiCall.validateResult(processed); } /** @@ -494,44 +494,44 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.transport = getTransport(config); } /** - * Send a 'fire-and-forget' message. - * @throws {Error} - * {@link MissingHandler} - * - * @example - * - * ``` - * const messaging = new Messaging(config) - * messaging.notify("foo", {bar: "baz"}) - * ``` - * @param {string} name - * @param {Record} [data] - */ + * Send a 'fire-and-forget' message. + * @throws {Error} + * {@link MissingHandler} + * + * @example + * + * ``` + * const messaging = new Messaging(config) + * messaging.notify("foo", {bar: "baz"}) + * ``` + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.transport.notify(name, data); } /** - * Send a request, and wait for a response - * @throws {Error} - * {@link MissingHandler} - * - * @example - * ``` - * const messaging = new Messaging(config) - * const response = await messaging.request("foo", {bar: "baz"}) - * ``` - * - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * Send a request, and wait for a response + * @throws {Error} + * {@link MissingHandler} + * + * @example + * ``` + * const messaging = new Messaging(config) + * const response = await messaging.request("foo", {bar: "baz"}) + * ``` + * + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.transport.request(name, data); @@ -544,20 +544,20 @@ class Messaging { exports.Messaging = Messaging; class MessagingTransport { /** - * @param {string} name - * @param {Record} [data] - * @returns {void} - */ + * @param {string} name + * @param {Record} [data] + * @returns {void} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; throw new Error("must implement 'notify'"); } /** - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -582,9 +582,9 @@ function getTransport(config) { */ class MissingHandler extends Error { /** - * @param {string} message - * @param {string} handlerName - */ + * @param {string} message + * @param {string} handlerName + */ constructor(message, handlerName) { super(message); this.handlerName = handlerName; @@ -690,8 +690,8 @@ class WebkitMessagingTransport { config; globals; /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.config = config; this.globals = captureGlobals(); @@ -700,11 +700,11 @@ class WebkitMessagingTransport { } } /** - * Sends message to the webkit layer (fire and forget) - * @param {String} handler - * @param {*} data - * @internal - */ + * Sends message to the webkit layer (fire and forget) + * @param {String} handler + * @param {*} data + * @internal + */ wkSend(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!(handler in this.globals.window.webkit.messageHandlers)) { @@ -728,12 +728,12 @@ class WebkitMessagingTransport { } /** - * Sends message to the webkit layer and waits for the specified response - * @param {String} handler - * @param {*} data - * @returns {Promise<*>} - * @internal - */ + * Sends message to the webkit layer and waits for the specified response + * @param {String} handler + * @param {*} data + * @returns {Promise<*>} + * @internal + */ async wkSendAndWait(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (this.config.hasModernWebkitAPI) { @@ -774,27 +774,27 @@ class WebkitMessagingTransport { } } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.wkSend(name, data); } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.wkSendAndWait(name, data); } /** - * Generate a random method name and adds it to the global scope - * The native layer will use this method to send the response - * @param {string | number} randomMethodName - * @param {Function} callback - */ + * Generate a random method name and adds it to the global scope + * The native layer will use this method to send the response + * @param {string | number} randomMethodName + * @param {Function} callback + */ generateRandomMethod(randomMethodName, callback) { var _this = this; this.globals.ObjectDefineProperty(this.globals.window, randomMethodName, { @@ -803,8 +803,8 @@ class WebkitMessagingTransport { configurable: true, writable: false, /** - * @param {any[]} args - */ + * @param {any[]} args + */ value: function () { callback(...arguments); // @ts-ignore - we want this to throw if it fails as it would indicate a fatal error. @@ -820,16 +820,16 @@ class WebkitMessagingTransport { } /** - * @type {{name: string, length: number}} - */ + * @type {{name: string, length: number}} + */ algoObj = { name: 'AES-GCM', length: 256 }; /** - * @returns {Promise} - */ + * @returns {Promise} + */ async createRandKey() { const key = await this.globals.generateKey(this.algoObj, true, ['encrypt', 'decrypt']); const exportedKey = await this.globals.exportKey('raw', key); @@ -837,44 +837,44 @@ class WebkitMessagingTransport { } /** - * @returns {Uint8Array} - */ + * @returns {Uint8Array} + */ createRandIv() { return this.globals.getRandomValues(new this.globals.Uint8Array(12)); } /** - * @param {BufferSource} ciphertext - * @param {BufferSource} key - * @param {Uint8Array} iv - * @returns {Promise} - */ + * @param {BufferSource} ciphertext + * @param {BufferSource} key + * @param {Uint8Array} iv + * @returns {Promise} + */ async decrypt(ciphertext, key, iv) { const cryptoKey = await this.globals.importKey('raw', key, 'AES-GCM', false, ['decrypt']); const algo = { name: 'AES-GCM', iv }; - let decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); - let dec = new this.globals.TextDecoder(); + const decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); + const dec = new this.globals.TextDecoder(); return dec.decode(decrypted); } /** - * When required (such as on macos 10.x), capture the `postMessage` method on - * each webkit messageHandler - * - * @param {string[]} handlerNames - */ + * When required (such as on macos 10.x), capture the `postMessage` method on + * each webkit messageHandler + * + * @param {string[]} handlerNames + */ captureWebkitHandlers(handlerNames) { const handlers = window.webkit.messageHandlers; if (!handlers) throw new _messaging.MissingHandler('window.webkit.messageHandlers was absent', 'all'); - for (let webkitMessageHandlerName of handlerNames) { + for (const webkitMessageHandlerName of handlerNames) { if (typeof handlers[webkitMessageHandlerName]?.postMessage === 'function') { /** - * `bind` is used here to ensure future calls to the captured - * `postMessage` have the correct `this` context - */ + * `bind` is used here to ensure future calls to the captured + * `postMessage` have the correct `this` context + */ const original = handlers[webkitMessageHandlerName]; const bound = handlers[webkitMessageHandlerName].postMessage?.bind(original); this.globals.capturedWebkitHandlers[webkitMessageHandlerName] = bound; @@ -903,11 +903,11 @@ class WebkitMessagingTransport { exports.WebkitMessagingTransport = WebkitMessagingTransport; class WebkitMessagingConfig { /** - * @param {object} params - * @param {boolean} params.hasModernWebkitAPI - * @param {string[]} params.webkitMessageHandlerNames - * @param {string} params.secret - */ + * @param {object} params + * @param {boolean} params.hasModernWebkitAPI + * @param {string[]} params.webkitMessageHandlerNames + * @param {string} params.secret + */ constructor(params) { /** * Whether or not the current WebKit Platform supports secure messaging @@ -915,13 +915,13 @@ class WebkitMessagingConfig { */ this.hasModernWebkitAPI = params.hasModernWebkitAPI; /** - * A list of WebKit message handler names that a user script can send - */ + * A list of WebKit message handler names that a user script can send + */ this.webkitMessageHandlerNames = params.webkitMessageHandlerNames; /** - * A string provided by native platforms to be sent with future outgoing - * messages - */ + * A string provided by native platforms to be sent with future outgoing + * messages + */ this.secret = params.secret; } } @@ -933,28 +933,28 @@ class WebkitMessagingConfig { exports.WebkitMessagingConfig = WebkitMessagingConfig; class SecureMessagingParams { /** - * @param {object} params - * @param {string} params.methodName - * @param {string} params.secret - * @param {number[]} params.key - * @param {number[]} params.iv - */ + * @param {object} params + * @param {string} params.methodName + * @param {string} params.secret + * @param {number[]} params.key + * @param {number[]} params.iv + */ constructor(params) { /** * The method that's been appended to `window` to be called later */ this.methodName = params.methodName; /** - * The secret used to ensure message sender validity - */ + * The secret used to ensure message sender validity + */ this.secret = params.secret; /** - * The CipherKey as number[] - */ + * The CipherKey as number[] + */ this.key = params.key; /** - * The Initial Vector as number[] - */ + * The Initial Vector as number[] + */ this.iv = params.iv; } } @@ -1165,7 +1165,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && * }} PasswordParameters */ const defaults = Object.freeze({ - SCAN_SET_ORDER: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\\"'<>,.?/ ]", + SCAN_SET_ORDER: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\"\'<>,.?/ ]', defaultUnambiguousCharacters: 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789', defaultPasswordLength: _constants.constants.DEFAULT_MIN_LENGTH, defaultPasswordRules: _constants.constants.DEFAULT_PASSWORD_RULES, @@ -1292,7 +1292,7 @@ class Password { _requirementsFromRules(passwordRules) { /** @type {Requirements} */ const requirements = {}; - for (let rule of passwordRules) { + for (const rule of passwordRules) { if (rule.name === parser.RuleName.ALLOWED) { console.assert(!('PasswordAllowedCharacters' in requirements)); const chars = this._charactersFromCharactersClasses(rule.value); @@ -1623,7 +1623,7 @@ class Password { */ _charactersFromCharactersClasses(characterClasses) { const output = []; - for (let characterClass of characterClasses) { + for (const characterClass of characterClasses) { output.push(...this._scanSetFromCharacterClass(characterClass)); } return output; @@ -1637,9 +1637,9 @@ class Password { if (!characters.length) { return ''; } - let shadowCharacters = Array.prototype.slice.call(characters); + const shadowCharacters = Array.prototype.slice.call(characters); shadowCharacters.sort((a, b) => this.options.SCAN_SET_ORDER.indexOf(a) - this.options.SCAN_SET_ORDER.indexOf(b)); - let uniqueCharacters = [shadowCharacters[0]]; + const uniqueCharacters = [shadowCharacters[0]]; for (let i = 1, length = shadowCharacters.length; i < length; ++i) { if (shadowCharacters[i] === shadowCharacters[i - 1]) { continue; @@ -1679,6 +1679,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.SHOULD_NOT_BE_REACHED = exports.RuleName = exports.Rule = exports.ParserError = exports.NamedCharacterClass = exports.Identifier = exports.CustomCharacterClass = void 0; exports.parsePasswordRules = parsePasswordRules; +/* eslint-disable no-var */ // Copyright (c) 2019 - 2020 Apple Inc. Licensed under MIT License. /* @@ -1731,7 +1732,6 @@ class Rule { } } exports.Rule = Rule; -; class NamedCharacterClass { constructor(name) { console.assert(_isValidRequiredOrAllowedPropertyValueIdentifier(name)); @@ -1748,10 +1748,8 @@ class NamedCharacterClass { } } exports.NamedCharacterClass = NamedCharacterClass; -; class ParserError extends Error {} exports.ParserError = ParserError; -; class CustomCharacterClass { constructor(characters) { console.assert(characters instanceof Array); @@ -1767,14 +1765,11 @@ class CustomCharacterClass { return `[${this._characters.join('').replace('"', '"')}]`; } } -exports.CustomCharacterClass = CustomCharacterClass; -; // MARK: Lexer functions - +exports.CustomCharacterClass = CustomCharacterClass; function _isIdentifierCharacter(c) { console.assert(c.length === 1); - // eslint-disable-next-line no-mixed-operators return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-'; } function _isASCIIDigit(c) { @@ -1820,14 +1815,14 @@ function _markBitsForNamedCharacterClass(bitSet, namedCharacterClass) { } } function _markBitsForCustomCharacterClass(bitSet, customCharacterClass) { - for (let character of customCharacterClass.characters) { + for (const character of customCharacterClass.characters) { bitSet[_bitSetIndexForCharacter(character)] = true; } } function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFormatCompliant) { // @ts-ignore - let asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); - for (let propertyValue of propertyValues) { + const asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); + for (const propertyValue of propertyValues) { if (propertyValue instanceof NamedCharacterClass) { if (propertyValue.name === Identifier.UNICODE) { return [new NamedCharacterClass(Identifier.UNICODE)]; @@ -1842,32 +1837,32 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo } let charactersSeen = []; function checkRange(start, end) { - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(start); i <= _bitSetIndexForCharacter(end); ++i) { if (asciiPrintableBitSet[i]) { temp.push(_characterAtBitSetIndex(i)); } } - let result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; + const result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; if (!result) { charactersSeen = charactersSeen.concat(temp); } return result; } - let hasAllUpper = checkRange('A', 'Z'); - let hasAllLower = checkRange('a', 'z'); - let hasAllDigits = checkRange('0', '9'); + const hasAllUpper = checkRange('A', 'Z'); + const hasAllLower = checkRange('a', 'z'); + const hasAllDigits = checkRange('0', '9'); // Check for special characters, accounting for characters that are given special treatment (i.e. '-' and ']') let hasAllSpecial = false; let hasDash = false; let hasRightSquareBracket = false; - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(' '); i <= _bitSetIndexForCharacter('/'); ++i) { if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === '-') { hasDash = true; } else { @@ -1883,7 +1878,7 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === ']') { hasRightSquareBracket = true; } else { @@ -1901,12 +1896,12 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (hasRightSquareBracket) { temp.push(']'); } - let numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); + const numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); hasAllSpecial = temp.length === numberOfSpecialCharacters; if (!hasAllSpecial) { charactersSeen = charactersSeen.concat(temp); } - let result = []; + const result = []; if (hasAllUpper && hasAllLower && hasAllDigits && hasAllSpecial) { return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]; } @@ -1934,7 +1929,7 @@ function _indexOfNonWhitespaceCharacter(input) { let position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; console.assert(position >= 0); console.assert(position <= input.length); - let length = input.length; + const length = input.length; while (position < length && _isASCIIWhitespace(input[position])) { ++position; } @@ -1944,10 +1939,10 @@ function _parseIdentifier(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - let seenIdentifiers = []; + const length = input.length; + const seenIdentifiers = []; do { - let c = input[position]; + const c = input[position]; if (!_isIdentifierCharacter(c)) { break; } @@ -1963,16 +1958,16 @@ function _parseCustomCharacterClass(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(input[position] === CHARACTER_CLASS_START_SENTINEL); - let length = input.length; + const length = input.length; ++position; if (position >= length) { // console.error('Found end-of-line instead of character class character') return [null, position]; } - let initialPosition = position; - let result = []; + const initialPosition = position; + const result = []; do { - let c = input[position]; + const c = input[position]; if (!_isASCIIPrintableCharacter(c)) { ++position; continue; @@ -2008,11 +2003,11 @@ function _parseCustomCharacterClass(input, position) { function _parsePasswordRequiredOrAllowedPropertyValue(input, position) { console.assert(position >= 0); console.assert(position < input.length); - let length = input.length; - let propertyValues = []; + const length = input.length; + const propertyValues = []; while (true) { if (_isIdentifierCharacter(input[position])) { - let identifierStartPosition = position; + const identifierStartPosition = position; // eslint-disable-next-line no-redeclare var [propertyValue, position] = _parseIdentifier(input, position); if (!_isValidRequiredOrAllowedPropertyValueIdentifier(propertyValue)) { @@ -2059,8 +2054,8 @@ function _parsePasswordRule(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - var mayBeIdentifierStartPosition = position; + const length = input.length; + const mayBeIdentifierStartPosition = position; // eslint-disable-next-line no-redeclare var [identifier, position] = _parseIdentifier(input, position); if (!Object.values(RuleName).includes(identifier)) { @@ -2075,7 +2070,7 @@ function _parsePasswordRule(input, position) { // console.error('Failed to find start of property value: ' + input.substr(position)) return [null, position, undefined]; } - let property = { + const property = { name: identifier, value: null }; @@ -2131,7 +2126,7 @@ function _parseInteger(input, position) { // console.error('Failed to parse value of type integer; not a number: ' + input.substr(position)) return [null, position]; } - let length = input.length; + const length = input.length; // let initialPosition = position let result = 0; do { @@ -2152,8 +2147,8 @@ function _parseInteger(input, position) { * @private */ function _parsePasswordRulesInternal(input) { - let parsedProperties = []; - let length = input.length; + const parsedProperties = []; + const length = input.length; var position = _indexOfNonWhitespaceCharacter(input); while (position < length) { if (!_isIdentifierCharacter(input[position])) { @@ -2190,7 +2185,7 @@ function _parsePasswordRulesInternal(input) { * @returns {Rule[]} */ function parsePasswordRules(input, formatRulesForMinifiedVersion) { - let [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); + const [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); if (!passwordRules) { throw new ParserError(maybeMessage); } @@ -2200,13 +2195,13 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { // When formatting rules for minified version, we should keep the formatted rules // as similar to the input as possible. Avoid copying required rules to allowed rules. - let suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; - let requiredRules = []; + const suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; + const requiredRules = []; let newAllowedValues = []; let minimumMaximumConsecutiveCharacters = null; let maximumMinLength = 0; let minimumMaxLength = null; - for (let rule of passwordRules) { + for (const rule of passwordRules) { switch (rule.name) { case RuleName.MAX_CONSECUTIVE: minimumMaximumConsecutiveCharacters = minimumMaximumConsecutiveCharacters ? Math.min(rule.value, minimumMaximumConsecutiveCharacters) : rule.value; @@ -2239,10 +2234,10 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { if (minimumMaximumConsecutiveCharacters !== null) { newPasswordRules.push(new Rule(RuleName.MAX_CONSECUTIVE, minimumMaximumConsecutiveCharacters)); } - let sortedRequiredRules = requiredRules.sort(function (a, b) { + const sortedRequiredRules = requiredRules.sort(function (a, b) { const namedCharacterClassOrder = [Identifier.LOWER, Identifier.UPPER, Identifier.DIGIT, Identifier.SPECIAL, Identifier.ASCII_PRINTABLE, Identifier.UNICODE]; - let aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; - let bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; + const aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; + const bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; if (aIsJustOneNamedCharacterClass && !bIsJustOneNamedCharacterClass) { return -1; } @@ -2250,8 +2245,8 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return 1; } if (aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { - let aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); - let bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); + const aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); + const bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); return aIndex - bIndex; } return 0; @@ -2896,6 +2891,9 @@ module.exports={ "keldoc.com": { "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*];" }, + "kennedy-center.org": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&*?@];" + }, "key.harvard.edu": { "password-rules": "minlength: 10; maxlength: 100; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^[']];" }, @@ -3408,8 +3406,8 @@ class CredentialsImport { activeInput?.focus(); } async started() { - this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); this.device.deviceApi.notify(new _deviceApiCalls.StartCredentialsImportFlowCall({})); + this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); } async dismissed() { this.device.deviceApi.notify(new _deviceApiCalls.CredentialsImportFlowPermanentlyDismissedCall(null)); @@ -3453,7 +3451,7 @@ function createDevice() { }; // Create the DeviceAPI + Setting - let deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); + const deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); const settings = new _Settings.Settings(globalConfig, deviceApi); if (globalConfig.isWindows) { if (globalConfig.isTopFrame) { @@ -3587,9 +3585,9 @@ class AndroidInterface extends _InterfacePrototype.default { } /** - * Used by the email web app - * Provides functionality to log the user out - */ + * Used by the email web app + * Provides functionality to log the user out + */ removeUserData() { try { return window.EmailInterface.removeCredentials(); @@ -4858,14 +4856,16 @@ class InterfacePrototype { }); break; default: - // Also fire pixel when filling an identity with the personal duck address from an email field - const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; - if (checks.every(Boolean)) { - this.firePixel({ - pixelName: 'autofill_personal_address' - }); + { + // Also fire pixel when filling an identity with the personal duck address from an email field + const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; + if (checks.every(Boolean)) { + this.firePixel({ + pixelName: 'autofill_personal_address' + }); + } + break; } - break; } } // some platforms do not include a `success` object, why? @@ -5113,13 +5113,15 @@ class InterfacePrototype { postSubmit(values, form) { if (!form.form) return; if (!form.hasValues(values)) return; - const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated]; + const shouldTriggerPartialSave = Object.keys(values?.credentials || {}).length === 1 && Boolean(values?.credentials?.username) && this.settings.featureToggles.partial_form_saves; + const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated, shouldTriggerPartialSave]; if (checks.some(Boolean)) { const formData = (0, _Credentials.appendGeneratedKey)(values, { password: this.passwordGenerator.password, username: this.emailProtection.lastGenerated }); - this.storeFormData(formData, 'formSubmission'); + const trigger = shouldTriggerPartialSave ? 'partialSave' : 'formSubmission'; + this.storeFormData(formData, trigger); } } @@ -5540,6 +5542,7 @@ function initFormSubmissionsApi(forms, matching) { // @ts-ignore if (btns.find(btn => btn.contains(realTarget))) return true; + return false; }); matchingForm?.submitHandler('global pointerdown event + matching form'); if (!matchingForm) { @@ -5635,7 +5638,7 @@ function overlayApi(device) { * @returns {Promise} */ async selectedDetail(data, type) { - let detailsEntries = Object.entries(data).map(_ref => { + const detailsEntries = Object.entries(data).map(_ref => { let [key, value] = _ref; return [key, String(value)]; }); @@ -5898,7 +5901,7 @@ class Form { */ getValuesReadyForStorage() { const formValues = this.getRawValues(); - return (0, _formatters.prepareFormValuesForStorage)(formValues); + return (0, _formatters.prepareFormValuesForStorage)(formValues, this.device.settings.featureToggles.partial_form_saves); } /** @@ -5929,7 +5932,7 @@ class Form { if (!input.classList.contains('ddg-autofilled')) return; (0, _autofillUtils.removeInlineStyles)(input, (0, _inputStyles.getIconStylesAutofilled)(input, this)); (0, _autofillUtils.removeInlineStyles)(input, { - 'cursor': 'pointer' + cursor: 'pointer' }); input.classList.remove('ddg-autofilled'); this.addAutofillStyles(input); @@ -6050,20 +6053,10 @@ class Form { if (this.form.matches(selector)) { this.addInput(this.form); } else { - /** @type {Element[] | NodeList} */ - let foundInputs = []; - // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. - if (this.form instanceof HTMLFormElement && this.form.elements != null && Symbol.iterator in Object(this.form.elements)) { - // For form elements we use .elements to catch fields outside the form itself using the form attribute. - // It also catches all elements when the markup is broken. - // We use .filter to avoid fieldset, button, textarea etc. - const formElements = [...this.form.elements].filter(el => el.matches(selector)); - // If there are no form elements, we try to look for all - // enclosed elements within the form. - foundInputs = formElements.length > 0 ? formElements : (0, _autofillUtils.findEnclosedElements)(this.form, selector); - } else { - foundInputs = this.form.querySelectorAll(selector); - } + // Attempt to get form's control elements first as it can catch elements when markup is broke, or if the fields are outside the form. + // Other wise use queryElementsWithShadow, that can scan for shadow tree. + const formControlElements = (0, _autofillUtils.getFormControlElements)(this.form, selector); + const foundInputs = formControlElements != null ? [...formControlElements, ...(0, _autofillUtils.findElementsInShadowTree)(this.form, selector)] : (0, _autofillUtils.queryElementsWithShadow)(this.form, selector, true); if (foundInputs.length < MAX_INPUTS_PER_FORM) { foundInputs.forEach(input => this.addInput(input)); } else { @@ -6124,7 +6117,7 @@ class Form { } get submitButtons() { const selector = this.matching.cssSelector('submitButtonSelector'); - const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.findEnclosedElements)(this.form, selector); + const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.queryElementsWithShadow)(this.form, selector); return allButtons.filter(btn => (0, _autofillUtils.isPotentiallyViewable)(btn) && (0, _autofillUtils.isLikelyASubmitButton)(btn, this.matching) && (0, _autofillUtils.buttonMatchesFormType)(btn, this)); } attemptSubmissionIfNeeded() { @@ -6247,12 +6240,12 @@ class Form { if ((0, _autofillUtils.wasAutofilledByChrome)(input)) return; if ((0, _autofillUtils.isEventWithinDax)(e, e.target)) { (0, _autofillUtils.addInlineStyles)(e.target, { - 'cursor': 'pointer', + cursor: 'pointer', ...onMouseMove }); } else { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -6264,7 +6257,7 @@ class Form { }); this.addListener(input, 'mouseleave', e => { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -6362,7 +6355,7 @@ class Form { this.touched.add(input); this.device.attachTooltip({ form: this, - input: input, + input, click: clickCoords, trigger: 'userInitiated', triggerMetaData: { @@ -6591,7 +6584,7 @@ class Form { }, 'credentials'); this.device.attachTooltip({ form: this, - input: input, + input, click: null, trigger: 'autoprompt', triggerMetaData: { @@ -6826,6 +6819,23 @@ class FormAnalyzer { } }); } + + /** + * Function that checks if the element is an external link or a custom web element that + * encapsulates a link. + * @param {any} el + * @returns {boolean} + */ + isElementExternalLink(el) { + // Checks if the element is present in the cusotm elements registry and ends with a '-link' suffix. + // If it does, it checks if it contains an anchor element inside. + const tagName = el.nodeName.toLowerCase(); + const isCustomWebElementLink = customElements?.get(tagName) != null && /-link$/.test(tagName) && (0, _autofillUtils.findElementsInShadowTree)(el, 'a').length > 0; + + // if an external link matches one of the regexes, we assume the match is not pertinent to the current form + const isElementLink = el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]'); + return isCustomWebElementLink || isElementLink; + } evaluateElement(el) { const string = (0, _autofillUtils.getTextShallow)(el); if (el.matches(this.matching.cssSelector('password'))) { @@ -6846,7 +6856,7 @@ class FormAnalyzer { if (likelyASubmit) { this.form.querySelectorAll('input[type=submit], button[type=submit]').forEach(submit => { // If there is another element marked as submit and this is not, flip back to false - if (el.type !== 'submit' && el !== submit) { + if (el.getAttribute('type') !== 'submit' && el !== submit) { likelyASubmit = false; } }); @@ -6865,8 +6875,7 @@ class FormAnalyzer { }); return; } - // if an external link matches one of the regexes, we assume the match is not pertinent to the current form - if (el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]')) { + if (this.isElementExternalLink(el)) { let shouldFlip = true; let strength = 1; // Don't flip forgotten password links @@ -6885,9 +6894,10 @@ class FormAnalyzer { }); } else { // any other case + const isH1Element = el.tagName === 'H1'; this.updateSignal({ string, - strength: 1, + strength: isH1Element ? 3 : 1, signalType: `generic: ${string}`, shouldCheckUnifiedForm: true }); @@ -6905,7 +6915,7 @@ class FormAnalyzer { // Check form contents (noisy elements are skipped with the safeUniversalSelector) const selector = this.matching.cssSelector('safeUniversalSelector'); - const formElements = (0, _autofillUtils.findEnclosedElements)(this.form, selector); + const formElements = (0, _autofillUtils.queryElementsWithShadow)(this.form, selector); for (let i = 0; i < formElements.length; i++) { // Safety cutoff to avoid huge DOMs freezing the browser if (i >= 200) break; @@ -6965,7 +6975,7 @@ class FormAnalyzer { } // Match form textContent against common cc fields (includes hidden labels) - const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig); + const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/gi); // De-dupe matches to avoid counting the same element more than once const deDupedMatches = new Set(textMatches?.map(match => match.toLowerCase())); @@ -7284,7 +7294,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Anguilla: 'AI', Albania: 'AL', Armenia: 'AM', - 'Curaçao': 'CW', + Curaçao: 'CW', Angola: 'AO', Antarctica: 'AQ', Argentina: 'AR', @@ -7473,7 +7483,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Paraguay: 'PY', Qatar: 'QA', 'Outlying Oceania': 'QO', - 'Réunion': 'RE', + Réunion: 'RE', Zimbabwe: 'ZW', Romania: 'RO', Russia: 'SU', @@ -7550,6 +7560,7 @@ Object.defineProperty(exports, "__esModule", { exports.prepareFormValuesForStorage = exports.inferCountryCodeFromElement = exports.getUnifiedExpiryDate = exports.getMMAndYYYYFromString = exports.getCountryName = exports.getCountryDisplayName = exports.formatPhoneNumber = exports.formatFullName = exports.formatCCYear = void 0; var _matching = require("./matching.js"); var _countryNames = require("./countryNames.js"); +var _autofillUtils = require("../autofill-utils.js"); // Matches strings like mm/yy, mm-yyyy, mm-aa, 12 / 2024 const DATE_SEPARATOR_REGEX = /\b((.)\2{1,3}|\d+)(?\s?[/\s.\-_—–]\s?)((.)\5{1,3}|\d+)\b/i; // Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) @@ -7718,36 +7729,25 @@ const getMMAndYYYYFromString = expiration => { }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ exports.getMMAndYYYYFromString = getMMAndYYYYFromString; -const shouldStoreCredentials = _ref3 => { - let { - credentials - } = _ref3; - return Boolean(credentials.password); -}; - -/** - * @param {InternalDataStorageObject} credentials - * @return {boolean} - */ -const shouldStoreIdentities = _ref4 => { +const shouldStoreIdentities = _ref3 => { let { identities - } = _ref4; + } = _ref3; return Boolean((identities.firstName || identities.fullName) && identities.addressStreet && identities.addressCity); }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ -const shouldStoreCreditCards = _ref5 => { +const shouldStoreCreditCards = _ref4 => { let { creditCards - } = _ref5; + } = _ref4; if (!creditCards.cardNumber) return false; if (creditCards.cardSecurityCode) return true; // Some forms (Amazon) don't have the cvv, so we still save if there's the expiration @@ -7770,7 +7770,8 @@ const formatPhoneNumber = phone => phone.replaceAll(/[^0-9|+]/g, ''); * @return {DataStorageObject} */ exports.formatPhoneNumber = formatPhoneNumber; -const prepareFormValuesForStorage = formValues => { +const prepareFormValuesForStorage = function (formValues) { + let canTriggerPartialSave = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; /** @type {Partial} */ let { credentials, @@ -7783,14 +7784,15 @@ const prepareFormValuesForStorage = formValues => { creditCards.cardName = identities?.fullName || formatFullName(identities); } - /** Fixes for credentials **/ - // Don't store if there isn't enough data - if (shouldStoreCredentials(formValues)) { - // If we don't have a username to match a password, let's see if the email is available - if (credentials.password && !credentials.username && identities.emailAddress) { - credentials.username = identities.emailAddress; - } - } else { + /** Fixes for credentials */ + // If we don't have a username to match a password, let's see if email or phone are available + if (credentials.password && !credentials.username && (0, _autofillUtils.hasUsernameLikeIdentity)(identities)) { + // @ts-ignore - username will be likely undefined, but needs to be specifically assigned to a string value + credentials.username = identities.emailAddress || identities.phone; + } + + // If there's no password, and we shouldn't trigger a partial save, let's discard the object + if (!credentials.password && !canTriggerPartialSave) { credentials = undefined; } @@ -7846,7 +7848,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":26,"./matching.js":34}],28:[function(require,module,exports){ +},{"../autofill-utils.js":54,"./countryNames.js":26,"./matching.js":34}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7889,7 +7891,7 @@ const getBasicStyles = (input, icon) => ({ 'background-repeat': 'no-repeat', 'background-origin': 'content-box', 'background-image': `url(${icon})`, - 'transition': 'background 0s' + transition: 'background 0s' }); /** @@ -7932,7 +7934,7 @@ const getIconStylesAutofilled = (input, form) => { return { ...iconStyle, 'background-color': '#F8F498', - 'color': '#333333' + color: '#333333' }; }; exports.getIconStylesAutofilled = getIconStylesAutofilled; @@ -8220,14 +8222,14 @@ const extractElementStrings = element => { // only take the string when it's an explicit text node if (el.nodeType === el.TEXT_NODE || !el.childNodes.length) { - let trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); + const trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); if (trimmedText) { strings.add(trimmedText); } return; } - for (let node of el.childNodes) { - let nodeType = node.nodeType; + for (const node of el.childNodes) { + const nodeType = node.nodeType; if (nodeType !== node.ELEMENT_NODE && nodeType !== node.TEXT_NODE) { continue; } @@ -8629,7 +8631,7 @@ const matchingConfiguration = exports.matchingConfiguration = { match: /sign.?up|join|register|enroll|(create|new).+account|newsletter|subscri(be|ption)|settings|preferences|profile|update|iscri(viti|zione)|registra(ti|zione)|(?:nuovo|crea(?:zione)?) account|contatt(?:ac)?i|sottoscriv|sottoscrizione|impostazioni|preferenze|aggiorna|anmeld(en|ung)|registrier(en|ung)|neukunde|neuer (kunde|benutzer|nutzer)|registreren|eigenschappen|profiel|bijwerken|s.inscrire|inscription|s.abonner|abonnement|préférences|profil|créer un compte|regis(trarse|tro)|regístrate|inscr(ibirse|ipción|íbete)|crea(r cuenta)?|nueva cuenta|nuevo (cliente|usuario)|preferencias|perfil|lista de correo|registrer(a|ing)|(nytt|öppna) konto|nyhetsbrev|prenumer(era|ation)|kontakt|skapa|starta|inställningar|min (sida|kundvagn)|uppdatera/iu }, resetPasswordLink: { - match: /(forgot(ten)?|reset|don't remember) (your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu + match: /(forgot(ten)?|reset|don't remember).?(your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu }, loginProvidersRegex: { match: / with | con | mit | met | avec /iu @@ -8894,8 +8896,8 @@ class Matching { * * `email: [{type: "email", strategies: {cssSelector: "email", ... etc}]` */ - for (let [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { - for (let fieldName of matcherNames) { + for (const [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { + for (const fieldName of matcherNames) { if (!this.#matcherLists[listName]) { this.#matcherLists[listName] = []; } @@ -9012,7 +9014,7 @@ class Matching { * @type {string[]} */ const selectors = []; - for (let matcher of matcherList) { + for (const matcher of matcherList) { if (matcher.strategies.cssSelector) { const css = this.cssSelector(matcher.strategies.cssSelector); if (css) { @@ -9149,12 +9151,12 @@ class Matching { /** * Loop through each strategy in order */ - for (let strategyName of this.#defaultStrategyOrder) { + for (const strategyName of this.#defaultStrategyOrder) { let result; /** * Now loop through each matcher in the list. */ - for (let matcher of matchers) { + for (const matcher of matchers) { /** * for each `strategyName` (such as cssSelector), check * if the current matcher implements it. @@ -9279,16 +9281,16 @@ class Matching { if (!ddgMatcher || !ddgMatcher.match) { return defaultResult; } - let matchRexExp = this.getDDGMatcherRegex(lookup); + const matchRexExp = this.getDDGMatcherRegex(lookup); if (!matchRexExp) { return defaultResult; } - let requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; + const requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; /** @type {MatchableStrings[]} */ const matchableStrings = ddgMatcher.matchableStrings || ['labelText', 'placeholderAttr', 'relatedText']; - for (let stringName of matchableStrings) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of matchableStrings) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; // Scoring to ensure all DDG tests are valid @@ -9304,7 +9306,7 @@ class Matching { // If a negated regex was provided, ensure it does not match // If it DOES match - then we need to prevent any future strategies from continuing if (ddgMatcher.forceUnknown) { - let notRegex = ddgMatcher.forceUnknown; + const notRegex = ddgMatcher.forceUnknown; if (!notRegex) { return { ...result, @@ -9323,7 +9325,7 @@ class Matching { } } if (ddgMatcher.skip) { - let skipRegex = ddgMatcher.skip; + const skipRegex = ddgMatcher.skip; if (!skipRegex) { return { ...result, @@ -9388,8 +9390,8 @@ class Matching { } /** @type {MatchableStrings[]} */ const stringsToMatch = ['placeholderAttr', 'nameAttr', 'labelText', 'id', 'relatedText']; - for (let stringName of stringsToMatch) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of stringsToMatch) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; if ((0, _autofillUtils.safeRegexTest)(regex, elementString)) { return { @@ -9463,14 +9465,14 @@ class Matching { fields: {} }, strategies: { - 'vendorRegex': { + vendorRegex: { rules: {}, ruleSets: [] }, - 'ddgMatcher': { + ddgMatcher: { matchers: {} }, - 'cssSelector': { + cssSelector: { selectors: {} } } @@ -9641,7 +9643,7 @@ const removeExcessWhitespace = function () { exports.removeExcessWhitespace = removeExcessWhitespace; const getExplicitLabelsText = el => { const labelTextCandidates = []; - for (let label of el.labels || []) { + for (const label of el.labels || []) { labelTextCandidates.push(...(0, _labelUtil.extractElementStrings)(label)); } if (el.hasAttribute('aria-label')) { @@ -9696,7 +9698,7 @@ const getRelatedText = (el, form, cssSelector) => { // If we didn't find a container, try looking for an adjacent label if (scope === el) { - let previousEl = recursiveGetPreviousElSibling(el); + const previousEl = recursiveGetPreviousElSibling(el); if (previousEl instanceof HTMLElement) { scope = previousEl; } @@ -10355,19 +10357,18 @@ class DefaultScanner { if (this.device.globalConfig.isDDGDomain) { return this; } - if ('matches' in context && context.matches?.(this.matching.cssSelector('formInputsSelectorWithoutSelect'))) { + const formInputsSelectorWithoutSelect = this.matching.cssSelector('formInputsSelectorWithoutSelect'); + if ('matches' in context && context.matches?.(formInputsSelectorWithoutSelect)) { this.addInput(context); } else { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - const inputs = context.querySelectorAll(selector); + const inputs = context.querySelectorAll(formInputsSelectorWithoutSelect); if (inputs.length > this.options.maxInputsPerPage) { this.setMode('stopped', `Too many input fields in the given context (${inputs.length}), stop scanning`, context); return this; } inputs.forEach(input => this.addInput(input)); if (context instanceof HTMLFormElement && this.forms.get(context)?.hasShadowTree) { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - (0, _autofillUtils.findEnclosedElements)(context, selector).forEach(input => { + (0, _autofillUtils.findElementsInShadowTree)(context, formInputsSelectorWithoutSelect).forEach(input => { if (input instanceof HTMLInputElement) { this.addInput(input, context); } @@ -10453,12 +10454,16 @@ class DefaultScanner { } if (element.parentElement) { element = element.parentElement; - const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); - const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); - // If we find a button or another input, we assume that's our form - if (inputs.length > 1 || buttons.length) { - // found related input, return common ancestor - return element; + // If the parent is a redundant component (only contains a single element or is a shadowRoot) do not increase the traversal count. + if (element.childElementCount > 1) { + const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); + const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); + // If we find a button or another input, we assume that's our form + if (inputs.length > 1 || buttons.length) { + // found related input, return common ancestor + return element; + } + traversalLayerCount++; } } else { // possibly a shadow boundary, so traverse through the shadow root and find the form @@ -10466,9 +10471,11 @@ class DefaultScanner { if (root instanceof ShadowRoot && root.host) { // @ts-ignore element = root.host; + } else { + // We're in a strange state (no parent or shadow root), just break out of the loop for safety + break; } } - traversalLayerCount++; } return input; } @@ -10551,7 +10558,7 @@ class DefaultScanner { this.changedElements.clear(); } else if (!this.rescanAll) { // otherwise keep adding each element to the queue - for (let element of htmlElements) { + for (const element of htmlElements) { this.changedElements.add(element); } } @@ -10575,7 +10582,7 @@ class DefaultScanner { this.findEligibleInputs(document); return; } - for (let element of this.changedElements) { + for (const element of this.changedElements) { if (element.isConnected) { this.findEligibleInputs(element); } @@ -10596,7 +10603,7 @@ class DefaultScanner { const outgoing = []; for (const mutationRecord of mutationList) { if (mutationRecord.type === 'childList') { - for (let addedNode of mutationRecord.addedNodes) { + for (const addedNode of mutationRecord.addedNodes) { if (!(addedNode instanceof HTMLElement)) continue; if (addedNode.nodeName === 'DDG-AUTOFILL') continue; outgoing.push(addedNode); @@ -10630,12 +10637,13 @@ class DefaultScanner { // find the enclosing parent form, and scan it. if (realTarget instanceof HTMLInputElement && !realTarget.hasAttribute(ATTR_INPUT_TYPE)) { const parentForm = this.getParentForm(realTarget); - if (parentForm && parentForm instanceof HTMLFormElement) { - const hasShadowTree = event.target?.shadowRoot != null; - const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); - this.forms.set(parentForm, form); - this.findEligibleInputs(parentForm); - } + + // If the parent form is an input element we bail. + if (parentForm instanceof HTMLInputElement) return; + const hasShadowTree = event.target?.shadowRoot != null; + const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); + this.forms.set(parentForm, form); + this.findEligibleInputs(parentForm); } window.performance?.mark?.('scan_shadow:init:end'); (0, _autofillUtils.logPerformance)('scan_shadow'); @@ -11010,7 +11018,8 @@ class Settings { inputType_credentials: false, inputType_creditCards: false, inlineIcon_credentials: false, - unknown_username_categorization: false + unknown_username_categorization: false, + partial_form_saves: false }, /** @type {AvailableInputTypes} */ availableInputTypes: { @@ -11334,7 +11343,7 @@ ${css} if (btn.matches('.wrapper:not(.top-autofill) button:hover, .currentFocus')) { callbacks.onSelect(btn.id); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } }); }); @@ -11538,7 +11547,9 @@ const defaultOptions = exports.defaultOptions = { }`, css: ``, setSize: undefined, - remove: () => {/** noop */}, + remove: () => { + /** noop */ + }, testMode: false, checkVisibility: true, hasCaret: false, @@ -11566,9 +11577,9 @@ class HTMLTooltip { this.tooltip = null; this.getPosition = getPosition; const forcedVisibilityStyles = { - 'display': 'block', - 'visibility': 'visible', - 'opacity': '1' + display: 'block', + visibility: 'visible', + opacity: '1' }; // @ts-ignore how to narrow this.host to HTMLElement? (0, _autofillUtils.addInlineStyles)(this.host, forcedVisibilityStyles); @@ -11826,7 +11837,7 @@ class HTMLTooltip { checkVisibility: this.options.checkVisibility }); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } } } @@ -12208,25 +12219,27 @@ class HTMLTooltipUIController extends _UIController.UIController { /** * Called when clicking on the Manage… button in the html tooltip - * * @param {SupportedMainTypes} type * @returns {*} * @private */ _onManage(type) { - this.removeTooltip(); switch (type) { case 'credentials': - return this._options.device.openManagePasswords(); + this._options.device.openManagePasswords(); + break; case 'creditCards': - return this._options.device.openManageCreditCards(); + this._options.device.openManageCreditCards(); + break; case 'identities': - return this._options.device.openManageIdentities(); + this._options.device.openManageIdentities(); + break; default: // noop } - } + this.removeTooltip(); + } _onIncontextSignupDismissed(_ref) { let { hasOtherOptions @@ -12770,10 +12783,14 @@ Object.defineProperty(exports, "__esModule", { }); exports.buttonMatchesFormType = exports.autofillEnabled = exports.addInlineStyles = exports.SIGN_IN_MSG = exports.ADDRESS_DOMAIN = void 0; exports.escapeXML = escapeXML; -exports.findEnclosedElements = findEnclosedElements; +exports.findElementsInShadowTree = findElementsInShadowTree; exports.formatDuckAddress = void 0; exports.getActiveElement = getActiveElement; -exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = exports.getTextShallow = exports.getDaxBoundingBox = void 0; +exports.getDaxBoundingBox = void 0; +exports.getFormControlElements = getFormControlElements; +exports.getTextShallow = void 0; +exports.hasUsernameLikeIdentity = hasUsernameLikeIdentity; +exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = void 0; exports.isFormLikelyToBeUsedAsPageWrapper = isFormLikelyToBeUsedAsPageWrapper; exports.isLikelyASubmitButton = exports.isIncontextSignupEnabledFromProcessedConfig = void 0; exports.isLocalNetwork = isLocalNetwork; @@ -12782,6 +12799,7 @@ exports.isValidTLD = isValidTLD; exports.logPerformance = logPerformance; exports.notifyWebApp = void 0; exports.pierceShadowTree = pierceShadowTree; +exports.queryElementsWithShadow = queryElementsWithShadow; exports.safeExecute = exports.removeInlineStyles = void 0; exports.safeRegexTest = safeRegexTest; exports.setValue = exports.sendAndWaitForAnswer = void 0; @@ -13154,8 +13172,9 @@ const isLikelyASubmitButton = (el, matching) => { // has high-signal submit classes safeRegexTest(/submit/i, dataTestId) || safeRegexTest(matching.getDDGMatcherRegex('submitButtonRegex'), text) || // has high-signal text - el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className) // it's a large element 250x40px - ) && el.offsetHeight * el.offsetWidth >= 2000 && + el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className)) && + // it's a large element 250x40px + el.offsetHeight * el.offsetWidth >= 2000 && // it's not a very small button like inline links and such !safeRegexTest(matching.getDDGMatcherRegex('submitButtonUnlikelyRegex'), text + ' ' + ariaLabel); }; @@ -13383,22 +13402,16 @@ function getActiveElement() { } /** - * Takes a root element and tries to find visible elements first, and if it fails, it tries to find shadow elements + * Takes a root element and tries to find elements in shadow DOMs that match the selector * @param {HTMLElement|HTMLFormElement} root * @param {string} selector * @returns {Element[]} */ -function findEnclosedElements(root, selector) { - // Check if there are any normal elements that match the selector - const elements = root.querySelectorAll(selector); - if (elements.length > 0) { - return Array.from(elements); - } - - // Check if there are any shadow elements that match the selector +function findElementsInShadowTree(root, selector) { const shadowElements = []; const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT); - let node = walker.nextNode(); + /** @type {Node|null} */ + let node = walker.currentNode; while (node) { if (node instanceof HTMLElement && node.shadowRoot) { shadowElements.push(...node.shadowRoot.querySelectorAll(selector)); @@ -13408,6 +13421,52 @@ function findEnclosedElements(root, selector) { return shadowElements; } +/** + * The function looks for form's control elements, and returns them if they're iterable. + * @param {HTMLElement} form + * @param {string} selector + * @returns {Element[]|null} + */ +function getFormControlElements(form, selector) { + // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. + if (form instanceof HTMLFormElement && form.elements != null && Symbol.iterator in Object(form.elements)) { + // For form elements we use .elements to catch fields outside the form itself using the form attribute. + // It also catches all elements when the markup is broken. + // We use .filter to avoid specific types of elements. + const formControls = [...form.elements].filter(el => el.matches(selector)); + return [...formControls]; + } else { + return null; + } +} + +/** + * Default operation: finds elements using querySelectorAll. + * Optionally, can be forced to scan the shadow tree. + * @param {HTMLElement} element + * @param {string} selector + * @param {boolean} forceScanShadowTree + * @returns {Element[]} + */ +function queryElementsWithShadow(element, selector) { + let forceScanShadowTree = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + /** @type {Element[]|NodeListOf} element */ + const elements = element.querySelectorAll(selector); + if (forceScanShadowTree || elements.length === 0) { + return [...elements, ...findElementsInShadowTree(element, selector)]; + } + return [...elements]; +} + +/** + * Checks if there is a single username-like identity, i.e. email or phone + * @param {InternalIdentityObject} identities + * @returns {boolean} + */ +function hasUsernameLikeIdentity(identities) { + return Object.keys(identities ?? {}).length === 1 && Boolean(identities?.emailAddress || identities.phone); +} + },{"./Form/matching.js":34,"./constants.js":57,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],55:[function(require,module,exports){ "use strict"; @@ -13447,7 +13506,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.DDG_DOMAIN_REGEX = void 0; exports.createGlobalConfig = createGlobalConfig; -const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/); +/* eslint-disable prefer-const */ +const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = /^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/; /** * This is a centralised place to contain all string/variable replacements @@ -13828,25 +13888,25 @@ const contentScopeSchema = exports.contentScopeSchema = null; const userPreferencesSchema = exports.userPreferencesSchema = null; const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = null; const availableInputTypesSchema = exports.availableInputTypesSchema = null; -const availableInputTypes1Schema = exports.availableInputTypes1Schema = null; -const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = null; -const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = null; -const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = null; -const storeFormDataSchema = exports.storeFormDataSchema = null; -const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = null; const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = null; const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = null; -const autofillSettingsSchema = exports.autofillSettingsSchema = null; +const availableInputTypes1Schema = exports.availableInputTypes1Schema = null; +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; +const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = null; const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = null; const emailProtectionGetUserDataResultSchema = exports.emailProtectionGetUserDataResultSchema = null; const emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = null; const emailProtectionGetAddressesResultSchema = exports.emailProtectionGetAddressesResultSchema = null; const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = null; -const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = null; -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; -const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = null; +const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = null; +const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = null; +const storeFormDataSchema = exports.storeFormDataSchema = null; +const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = null; const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = null; const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = null; +const autofillSettingsSchema = exports.autofillSettingsSchema = null; +const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = null; +const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = null; const apiSchema = exports.apiSchema = null; },{}],60:[function(require,module,exports){ @@ -13964,7 +14024,7 @@ function waitForResponse(expectedResponse, config) { return; } try { - let data = JSON.parse(e.data); + const data = JSON.parse(e.data); if (data.type === expectedResponse) { window.removeEventListener('message', handler); return resolve(data); @@ -14119,7 +14179,7 @@ async function extensionSpecificRuntimeConfiguration(deviceApi) { return { success: { // @ts-ignore - contentScope: contentScope, + contentScope, // @ts-ignore userPreferences: { // Copy locale to user preferences as 'language' to match expected payload @@ -14313,6 +14373,7 @@ function waitForWindowsResponse(responseId, options) { if (options?.signal?.aborted) { return reject(new DOMException('Aborted', 'AbortError')); } + // eslint-disable-next-line prefer-const let teardown; // The event handler @@ -17199,7 +17260,6 @@ exports.default = void 0; window.requestIdleCallback = window.requestIdleCallback || function (cb) { return setTimeout(function () { const start = Date.now(); - // eslint-disable-next-line standard/no-callback-literal cb({ didTimeout: false, timeRemaining: function () { diff --git a/package-lock.json b/package-lock.json index f331e7509a7f..18c007a54436 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "dependencies": { "@duckduckgo/autoconsent": "^12.3.0", - "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#15.1.0", + "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1724449523" @@ -58,7 +58,7 @@ } }, "node_modules/@duckduckgo/autofill": { - "resolved": "git+ssh://git@github.com/duckduckgo/duckduckgo-autofill.git#c992041d16ec10d790e6204dce9abf9966d1363c", + "resolved": "git+ssh://git@github.com/duckduckgo/duckduckgo-autofill.git#47c26dc32b94cdbcef3e6157497147917678c25c", "hasInstallScript": true, "license": "Apache-2.0" }, diff --git a/package.json b/package.json index 52aeff559b23..1cc8abc7c538 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@duckduckgo/autoconsent": "^12.3.0", - "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#15.1.0", + "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1724449523" From 06131d6c32142c4836cb6d39c8a00c0bd956fca7 Mon Sep 17 00:00:00 2001 From: Dax Mobile <44842493+daxmobile@users.noreply.github.com> Date: Thu, 19 Dec 2024 22:54:10 +1100 Subject: [PATCH 14/32] Update reference tests to version 1734514764 (#5411) Task/Issue URL: https://app.asana.com/0/488551667048375/1209012157675004/f ----- - Automated reference tests dependency update This PR updates the reference tests dependency to the latest available version and copies the necessary files. If tests have failed, see https://app.asana.com/0/0/1203766026095653/f for further information on what to do next. - [ ] All tests must pass Co-authored-by: daxmobile --- .../domain_matching_tests.json | 7 + .../tracker_radar_reference.json | 23 + .../privacy-dashboard/build/app/.npmignore | 1 + .../build/app/font/.npmignore | 1 + .../build/app/html/.npmignore | 1 + .../build/app/html/android.html | 32 - .../build/app/html/browser.html | 32 - .../privacy-dashboard/build/app/html/ios.html | 32 - .../build/app/html/macos.html | 32 - .../build/app/html/popup.html | 32 - .../build/app/html/windows.html | 32 - .../build/app/img/.npmignore | 1 + .../build/app/img/arrow--large.svg | 1 - .../build/app/img/arrow@2x.png | Bin 227 -> 0 bytes .../build/app/img/arrow@3x.png | Bin 301 -> 0 bytes .../build/app/img/blocking--off.svg | 1 - .../build/app/img/blocking--on.svg | 1 - .../build/app/img/broken-bicycle.svg | 87 - .../privacy-dashboard/build/app/img/check.svg | 1 - .../privacy-dashboard/build/app/img/close.svg | 12 - .../build/app/img/ddg-icon@2x.png | Bin 1419 -> 0 bytes .../build/app/img/ddg-logo-simple@2x.png | Bin 1972 -> 0 bytes .../privacy-dashboard/build/app/img/error.svg | 1 - .../build/app/img/fire-button-header.svg | 26 - .../app/img/hero-on-major-networks-big.svg | 1 - .../build/app/img/hero-on-major-networks.svg | 15 - .../build/app/img/hero-ribbon__bad.svg | 11 - .../build/app/img/hero-ribbon__good.svg | 11 - .../build/app/img/hero-ribbon__mixed.svg | 10 - .../app/img/hero-warning-major-networks.svg | 1 - .../build/app/img/https--off.svg | 1 - .../build/app/img/https--on.svg | 1 - .../build/app/img/icon_128.png | Bin 7905 -> 0 bytes .../build/app/img/icon_16.png | Bin 823 -> 0 bytes .../build/app/img/icon_19.png | Bin 892 -> 0 bytes .../build/app/img/icon_38.png | Bin 4706 -> 0 bytes .../build/app/img/icon_48.png | Bin 2813 -> 0 bytes .../build/app/img/logo-horizontal.png | Bin 4314 -> 0 bytes .../build/app/img/logo-horizontal@2x.png | Bin 9187 -> 0 bytes .../build/app/img/logo-horizontal@3x.png | Bin 14223 -> 0 bytes .../build/app/img/logo-small-new.svg | 16 - .../build/app/img/logo-small.svg | 16 - .../privacy-dashboard/build/app/img/loupe.svg | 4 - .../build/app/img/privacy--bad.svg | 1 - .../build/app/img/privacy--good.svg | 1 - .../build/app/img/privacy--mixed.svg | 1 - .../img/refresh-assets/Block-Allowed-96.svg | 13 - .../img/refresh-assets/Block-Disabled-128.svg | 1 - .../app/img/refresh-assets/Block-Info-128.svg | 22 - .../app/img/refresh-assets/Breakage-128.svg | 25 - .../app/img/refresh-assets/Breakage-96.svg | 1 - .../app/img/refresh-assets/Check-Color-16.svg | 1 - .../img/refresh-assets/Cookies-Hidden-128.svg | 29 - .../refresh-assets/Cookies-Managed-128.svg | 21 - .../app/img/refresh-assets/Counter-128.svg | 1 - .../app/img/refresh-assets/Error-Color-16.svg | 1 - .../app/img/refresh-assets/Locked-128.svg | 15 - .../app/img/refresh-assets/Locked-96.svg | 1 - .../app/img/refresh-assets/Network-128.svg | 1 - .../app/img/refresh-assets/Phishing-128.svg | 20 - .../app/img/refresh-assets/Shield-128.svg | 1 - .../app/img/refresh-assets/Stop-Grey-16.svg | 1 - .../app/img/refresh-assets/Unlocked-128.svg | 1 - .../app/img/refresh-assets/Unlocked-96.svg | 1 - .../img/refresh-assets/back-arrow--light.svg | 1 - .../back-arrow-android--light.svg | 3 - .../img/refresh-assets/back-arrow-android.svg | 3 - .../app/img/refresh-assets/back-arrow.svg | 1 - .../back-chevron-ios--light.svg | 3 - .../img/refresh-assets/back-chevron-ios.svg | 3 - .../app/img/refresh-assets/breakage-sent.svg | 6 - .../img/refresh-assets/chat-private-128.svg | 18 - .../app/img/refresh-assets/chevron--light.svg | 3 - .../build/app/img/refresh-assets/chevron.svg | 3 - .../permissions-camera-light.svg | 1 - .../img/refresh-assets/permissions-camera.svg | 1 - .../permissions-externalScheme-light.svg | 4 - .../permissions-externalScheme.svg | 4 - .../permissions-location-light.svg | 1 - .../refresh-assets/permissions-location.svg | 1 - .../permissions-microphone-light.svg | 1 - .../refresh-assets/permissions-microphone.svg | 1 - .../permissions-notification-light.svg | 1 - .../permissions-notification.svg | 1 - .../permissions-popups-light.svg | 4 - .../img/refresh-assets/permissions-popups.svg | 4 - .../img/refresh-assets/switch-shield-128.svg | 15 - .../tracker-icons/letters/A.svg | 1 - .../tracker-icons/letters/B.svg | 1 - .../tracker-icons/letters/C.svg | 1 - .../tracker-icons/letters/D.svg | 1 - .../tracker-icons/letters/E.svg | 1 - .../tracker-icons/letters/F.svg | 1 - .../tracker-icons/letters/G.svg | 1 - .../tracker-icons/letters/H.svg | 1 - .../tracker-icons/letters/I.svg | 1 - .../tracker-icons/letters/J.svg | 1 - .../tracker-icons/letters/K.svg | 1 - .../tracker-icons/letters/L.svg | 1 - .../tracker-icons/letters/M.svg | 1 - .../tracker-icons/letters/N.svg | 1 - .../tracker-icons/letters/O.svg | 1 - .../tracker-icons/letters/P.svg | 1 - .../tracker-icons/letters/Q.svg | 1 - .../tracker-icons/letters/R.svg | 1 - .../tracker-icons/letters/S.svg | 1 - .../tracker-icons/letters/T.svg | 1 - .../tracker-icons/letters/U.svg | 1 - .../tracker-icons/letters/V.svg | 1 - .../tracker-icons/letters/W.svg | 1 - .../tracker-icons/letters/X.svg | 1 - .../tracker-icons/letters/Y.svg | 1 - .../tracker-icons/letters/Z.svg | 1 - .../tracker-icons/logos/adjust.svg | 5 - .../tracker-icons/logos/adobe.svg | 7 - .../tracker-icons/logos/amazon.svg | 7 - .../tracker-icons/logos/amplitude.svg | 5 - .../tracker-icons/logos/appnexus.svg | 5 - .../tracker-icons/logos/appsflyer.svg | 8 - .../tracker-icons/logos/beeswax.svg | 10 - .../tracker-icons/logos/branchmetrics.svg | 5 - .../tracker-icons/logos/braze.svg | 5 - .../tracker-icons/logos/bugsnag.svg | 5 - .../tracker-icons/logos/chartbeat.svg | 8 - .../tracker-icons/logos/comscore.svg | 6 - .../tracker-icons/logos/criteo.svg | 5 - .../tracker-icons/logos/facebook.svg | 5 - .../tracker-icons/logos/google.svg | 8 - .../tracker-icons/logos/googleadsgoogle.svg | 14 - .../logos/googleanalyticsgoogle.svg | 14 - .../tracker-icons/logos/indexexchange.svg | 5 - .../tracker-icons/logos/instagramfacebook.svg | 24 - .../tracker-icons/logos/iponweb.svg | 5 - .../tracker-icons/logos/kochava.svg | 5 - .../tracker-icons/logos/linkedin.svg | 5 - .../tracker-icons/logos/liveramp.svg | 8 - .../tracker-icons/logos/magnite.svg | 7 - .../tracker-icons/logos/mediamath.svg | 5 - .../tracker-icons/logos/microsoft.svg | 8 - .../tracker-icons/logos/mixpanel.svg | 5 - .../tracker-icons/logos/neustar.svg | 5 - .../tracker-icons/logos/newrelic.svg | 6 - .../tracker-icons/logos/openx.svg | 8 - .../tracker-icons/logos/oracle.svg | 5 - .../tracker-icons/logos/outbrain.svg | 5 - .../tracker-icons/logos/pinterest.svg | 5 - .../tracker-icons/logos/pubmatic.svg | 5 - .../tracker-icons/logos/quantcast.svg | 5 - .../tracker-icons/logos/rythmone.svg | 10 - .../tracker-icons/logos/salesforce.svg | 5 - .../tracker-icons/logos/sharetrough.svg | 7 - .../tracker-icons/logos/smaato.svg | 5 - .../tracker-icons/logos/spotx.svg | 8 - .../tracker-icons/logos/taboola.svg | 6 - .../tracker-icons/logos/tapad.svg | 12 - .../tracker-icons/logos/thenielsencompany.svg | 13 - .../tracker-icons/logos/thetradedesk.svg | 7 - .../tracker-icons/logos/twitter.svg | 5 - .../tracker-icons/logos/urbanairship.svg | 6 - .../tracker-icons/logos/verizonmedia.svg | 5 - .../tracker-icons/logos/warnermedia.svg | 5 - .../tracker-icons/logos/xaxis.svg | 376 - .../tracker-icons/logos/yahoojapan.svg | 5 - .../tracker-icons/logos/yandex.svg | 5 - .../tracker-icons/logos/youtubegoogle.svg | 12 - .../tracker-icons/logos/zeotap.svg | 14 - .../build/app/img/settings-gear@2x.png | Bin 1268 -> 0 bytes .../build/app/img/shield.svg | 1 - .../build/app/img/social/blocked_comment.svg | 10 - .../app/img/social/blocked_facebook_logo.svg | 12 - .../build/app/img/social/blocked_group.svg | 20 - .../build/app/img/social/blocked_page.svg | 16 - .../build/app/img/social/blocked_post.svg | 16 - .../build/app/img/social/blocked_video.svg | 9 - .../build/app/img/social/dax.png | Bin 18151 -> 0 bytes .../build/app/img/social/loading_dark.svg | 22 - .../build/app/img/social/loading_light.svg | 22 - .../build/app/img/spinner.svg | 1 - .../build/app/img/status--bad.svg | 5 - .../build/app/img/status--good.svg | 4 - .../build/app/img/status--info.svg | 3 - .../build/app/img/status--mixed.svg | 4 - .../privacy-dashboard/build/app/img/wand.svg | 1 - .../privacy-dashboard/build/app/index.html | 18 - .../build/app/public/.npmignore | 1 + .../build/app/public/css/android.css | 148 - .../build/app/public/css/base.css | 765 - .../build/app/public/css/popup.css | 4095 ---- .../app/public/js/android-breakage-dialog.js | 5042 ----- .../build/app/public/js/base.js | 18209 ---------------- .../build/app/public/js/polyfill-loader.js | 21 - .../build/app/public/js/polyfills.js | 6801 ------ package-lock.json | 78 +- package.json | 2 +- 194 files changed, 75 insertions(+), 36711 deletions(-) create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/.npmignore create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/font/.npmignore create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/.npmignore delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/.npmignore delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-logo-simple@2x.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/error.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg delete mode 100755 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_38.png delete mode 100755 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small-new.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/shield.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/index.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/.npmignore delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/base.js delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js delete mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js diff --git a/app/src/androidTest/resources/reference_tests/domain_matching_tests.json b/app/src/androidTest/resources/reference_tests/domain_matching_tests.json index 6186e1181f02..22b32afcfc65 100644 --- a/app/src/androidTest/resources/reference_tests/domain_matching_tests.json +++ b/app/src/androidTest/resources/reference_tests/domain_matching_tests.json @@ -34,6 +34,13 @@ "requestType": "script", "expectAction": "ignore" }, + { + "name": "same party ignore with deeper subdomain", + "siteURL": "https://bad.etld-plus-two.site/", + "requestURL": "https://bad.etld-plus-two.site/script.js", + "requestType": "script", + "expectAction": "ignore" + }, { "name": "tracker loads ignore", "siteURL": "https://bad.third-party.site/", diff --git a/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json b/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json index 9a831c9e5063..aff7c7750124 100644 --- a/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json +++ b/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json @@ -255,6 +255,21 @@ "rules": [], "default": "ignore" }, + "bad.etld-plus-two.site": { + "domain": "bad.etld-plus-two.site", + "owner": { + "name": "Test Site for Tracker Blocking With eTLD+2", + "displayName": "Bad Third Party Site eTLD+2", + "privacyPolicy": "", + "url": "http://bad.etld-plus-two.site" + }, + "prevalence": 0.1, + "fingerprinting": 3, + "cookies": 0.1, + "categories": [], + "default": "block", + "rules": [] + }, "tracker.test": { "domain": "tracker.test", "owner": { @@ -819,6 +834,13 @@ "prevalence": 0.1, "displayName": "Test Site for Tracker Blocking" }, + "Test Site for Tracker Blocking With eTLD+2": { + "domains": [ + "bad.etld-plus-two.site" + ], + "prevalence": 0.1, + "displayName": "Bad Third Party Site eTLD+2" + }, "Tests for formatting": { "domains": [ "format.test" @@ -876,6 +898,7 @@ "bad.third-party.site": "Test Site for Tracker Blocking", "sometimes-bad.third-party.site": "Test Site for Tracker Blocking", "broken.third-party.site": "Test Site for Tracker Blocking", + "bad.etld-plus-two.site": "Test Site for Tracker Blocking With eTLD+2", "format.test": "Tests for formatting", "third-party.site": "Test Site for Tracker Blocking", "tracker.test": "Test Site for Tracker Blocking", diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/font/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/font/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/font/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html deleted file mode 100644 index 7c9b0a2f8b0a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html deleted file mode 100644 index 1da908bbb756..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html deleted file mode 100644 index c20561b583fd..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html deleted file mode 100644 index 4f83c6830c37..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html deleted file mode 100644 index cba0171ac1df..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html deleted file mode 100644 index 1c4578fe6407..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg deleted file mode 100644 index b0fac34d7f5f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png deleted file mode 100644 index 028fe33a282a0dd62f4dbe1dd1ad6b86d0946467..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJRh}-6Ar*{ouQ9SYIf}GC^yp_7 z5{wFQSiSOs6%&Vqi&KX5MY&rJ56XBr4n8zL|M-!7!{@{TbwR@nP6>Vm#-&r1R;}o_ zTD{No!GcH2cfX2e`leOG!XB|gy>~@_W5mUdUmrN+4=C3#^nYN~NqWW{ab%ll!rHic z25G(r{qa|)F#dRKe)Z%03G(ZCE#tDS`R*|Pv*57!^;jq2dH?2yox4_Sw_2&UK4}q) b$^&l2&NI7q@YFQ{UCrR>>gTe~DWM4fmb6!5 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png deleted file mode 100644 index 83d8e275fe8940371e9e51a3b255debe12e72691..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 301 zcmV+|0n+}7P)f*Y1+;-sKoL@aGPiSqK%v9wa)1yeE_Uw z0K)hO>hS@*@%Jz9|6G5GMdQ8D<2~(oLfY|!wBreB#}f)Yp7l|GA&i#+riAfQz=SYf z3TUE(YCP)_caT3Pv_s?ky`BI;35Zz&5|Drw_)fpujP(3N00000NkvXXu0mjf9LjR{ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg deleted file mode 100644 index 0ab2130baa2d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg +++ /dev/null @@ -1 +0,0 @@ -Icon OFF- Networks Blocked \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg deleted file mode 100644 index de51d5669252..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg +++ /dev/null @@ -1 +0,0 @@ -Icon ON- Networks Blocked \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg deleted file mode 100644 index c6c6e9024e8a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg +++ /dev/null @@ -1,87 +0,0 @@ - - - - Group 73 - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg deleted file mode 100644 index 415122ee30d6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg deleted file mode 100644 index 163acb0e33c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg +++ /dev/null @@ -1,12 +0,0 @@ - -Union -Created using Figma - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png deleted file mode 100644 index 41ca76607be49e48e303daebd0d99122dc39bedb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1419 zcmV;61$6p}P) z>{%4Y?~EavAQ=@6W)X=7jfP@p3V*uw^lVGDn-B#OGn$nk`!p!`q4rin)>6FLf-NW> zHFiQnMM1LhchBeUoXLH^xr4VS`Q`WT{?7M%&iUSR?=NKDXz_SFT3lS*`}FkmT__Z4 zl}9l-qS@Eia%7&LpFbBB6{YX)?$*=k^z~c(hF%-c)6)~XzrRlk==Tobt0rWA6~d{l zt*wmtKLm(45{XR8JAtA5d?d<~Gi zl&r6>&zzs1b3}ziPh(@_x&(2ZM}V5kfWH85Z*Mo_l6B{VoVXrIXp`xa4#xnZ7jrtSG(jWbx;aj73a#g<}v5gXW4(1@w}2cX!)EK`5!~ml@#@ibh^@=*!AWrVEzNnnJxn z4FdG#C?EOi_Zk6!CMPFtrrhPZkOeY*jRrDYks8{nkASZ0$}KtO?F-DVfJd0 ziVr-XRg$7$H={g-bP&`H-)i>^g5w(uj7=-p;VhH)oJl3oj*gDz&4@x-pgA#?89*bN zo13!@$Ti-REuzFv&I?xC(95NOWE-fwPgv#QiroK39 zX~6+$QrJh&~?IHFSyoygNQlzPQT$yM(~AB7z+ki>La%$V~XA43OpDK)E8q2RufH#B#IAQ zd=QC=nt%wXToUM(1RkUY5P_6ix6+HalwP;p8$160nVH?0-JO};s$cSF&Y80_=bQg} z&RGMD6Fkos;AJIB70NsmmnaejP%fi*Q9LNE27|#18NvV=0*SftvIE5}-HZB%Av!t& z5nqqux2Ez6;H-J_TOO1HNc3y?uL&j+3tayV{B0g~4RzjBea`4`f@S8DV6AaOPK{f- z?M3+@9iqAfMN<;7Ez}=rJr08>zSSh9MK-tg1;|@ikL@yv=prrC8+6FI@X~_fB2D@B zHYb^JJRqV44I3d3$%5dk8<6CWkO@H~S0$1w=s&z41`h34jB`1HZ$(FkVZ0!1+8Z`W z+9Z=VLplUS&0QjLq%|_D9L!X!-v;}FC9F^84td+5|L~U?Yna|uwtb&Oax0SjOp~D8 ztf|NmC_0O`?gWFq1dK)_a2yvK8$$o=M{Q@K*#wg0lO8RCM9$rJa2K0Q?S+wW7$DmU zP*x5T>efQ(j5&-ffi!x5*Si^MlRlbAVp{TIcRrFN-vlm!-0MV+w5CRmz$PB>0dKKF z&eT~@SoXL=i!|A!-N!_&I3XR-N0G0CknF#b?i*y}XrKirclCa>S^MiPIbd1a1diJ0 zV_H)KnY#DGO=+hk`Y6lHYHBi5%QZ-4%cbk+NG|{VeNeV|g)TV)Mf+n-pT?qI526+c zJJ|EGu|^`6Dk$X0TJa_nO{-+>5q}W$aOzw;oVhU!T?TG{G zusguM_$Aidxz~e}--IjI)wMk`8iHr5U9fcFbjYf07>^d+l8uNUD`8sTr_6%v>}>eU zHw^09Lf z!X57e$@$ZQzpa%nE>2twR0Y$Cvg{m1_XnJK(|d>Dd|QX=Bj?+^u;<_f<_=~|Kj|XW z+0L${!76scoB8VGRBJojM|0EUYM5GH#3a{hPCF+OBEDXBB_Ax1-_S!e8jU68B?~Ly zG?J^TRG*k!Vc#dKVtrPH#5Bg40c>b>QwjP%#%JJO{5eU3F@kBK-v^OM1WYEu`5Wry zGD$)N>u?A^_)$VV#(wS$bpF}sEt8R$BRz@ zQpa{wmP-9nWazk_T7wdt8v*7V11PG8h(B(2(v~Ddj?CYGAvHPTA;yGvJ z%hwc8G1uHr1pKV(M4e8>Dp~=P6Z{Wq;qN`inF%QoOP~nW^TpiSda2ngpW$;_4&~Ra z0bS^65yAU~k0c_bElDW7Xr>jcG~#}_g*NnZg0$TuE$Xk^L_gGm!J7IVw@Nt}GpU~! z6s_APHCZD@P>kkgB3HDo2{b214f_3l&EI4vEUmf<4Y0e;3|}lagJ)J&%4ck7J@Nd8 z4w!`ete6-#&FG6OaL4ZsVzE|TT%sRFZe4*0`XQ|kkKFwZEMlhTuQWO)vf~g0t=(cL45>=p29y@mqKn6u53B7_ zFdvc@Z8jU6?)nM3f}I$a0B3qmfa$6k0x$;LL^4nogt0stqdXWm!L$$a3`yk5w(q4C zG>_dk_`jq?(H-3$oc_=Wb7#j&ID}NShIUJ7HaJdf}O9XOa zTG=K)RY*xtBuVyPgyJQVc0u(@^mamMXn>WyC-SEyJ`bUw5UM^FESI- zk;n`zA9IVUq1WF7Ry-l8`2H7gjB;?JH~@dzq7W=BV1X#6w0==@2U79?9f*4t`m*)Z zr+u@ux#t%w2ivQSV9qze%AfHB)o6va6>q^S6|X7YaqpcM*@~TxgKf)JGh(8@c_6{( z#tqs;qjc~h#;&#T4^AKAySuwt|6JD@emFG5r-J`t3;X?}5jGx0d5E$F{tt*mkMNlx zD#}@uM$sy1A>&hi8Bv \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg deleted file mode 100644 index 1151a5e558d1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg deleted file mode 100644 index 4f5e241b570f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg deleted file mode 100644 index 8c6a43371303..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg deleted file mode 100644 index 2f5a1aceef19..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg deleted file mode 100644 index 4527a8f0e3c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg deleted file mode 100644 index 1801055f44d3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg deleted file mode 100644 index 8ee83ae4dbdd..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg deleted file mode 100644 index 03e4ef15071b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg +++ /dev/null @@ -1 +0,0 @@ -Icon OFF- Connection \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg deleted file mode 100644 index 534f54444e7d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg +++ /dev/null @@ -1 +0,0 @@ -Icon ON- Connection \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png deleted file mode 100755 index e661553ef4523f8e786ee4775c19512ed7efd984..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7905 zcmV<79v*F*d`D-Ku&T;oP*%-G$hC4j>HZrusKtyT#ui5TFv&%&g{;t zMtoIMyPDmVR{j6||KI=UZbqL%w64A=9E*=O=pmXDi&4GKs8ZYxbK>E|J6Kr#Ngg3i z-HfsBxOn75ZMsga(Ky=|im~qcpYLv=PZ=0ZaY$j)NF#C9pb@{EG!_;@tRg?agmQ3d ziE-K|{zkK|#aimOwnS(OW6CK&>#Bw-Dh@ToIA5hPezo;%&J#Fq5f-B*O6=+RTlX~6 z6vLEJfY#N^8^vhf${DTlZHDKHgoW51i_=TxrT_x10IfG)&_MCn)ts^Qffc$n zB4TixiDH|A>?Q)K0GRE9ux%7i8z~2bX4Fw(cmZjpW{mw75|CxDe0 zIhcXN}boq>UQ}x;CFGNiKs2EB6SO>~;L+zdQ~4Pw?W#t%Y=NmdCt z8%RYE3IR(5&f!)m+$e%bDm_yF+@5a?t0?Oe8E)+rJ5MnFx!3}&@fYzIq-71PIkJu%0-1vCR^qyCqqk-Mc zImhQ-0XYU(ERa(t?h1;~e*ao~vWQ|7=bPrf@b)9*BYahW)*F{TY-jReS|NB0UM66M zpWOC%-eza*RR4zs@c+f5l~ z3PORR|($2ME9GnTKp6284^JhGVz;5hZx80Mg&{&@YMc2CMhL z&u5zT5P0XKo7^T?0tcsx(EZ}$(!$xm7hd400%Rh47>t=4ekfVA6{d=*cMJT_GdFCu zwRjG=f#*u#nF3@IK1@D@Z^iII?jZP6JD;OZGhq3q35#Gg4iNsa&G*_7Tu+t269vd5 ze2}8kh1s{lr^Vbm1uS9p+KskEvFn-5c9X#~CCFI;G6^5rUL}~m6*ByzpK4%SFg{ku zzzaN4f}9i}$@br&EQIgC)X6Zh_6Lt8)3fDiW)m4d{2pZd22r9Fi6InYrV?NcYVUi@ zk{j460p~3}!|@flL#}mz3edWG=|)k_TdR7_PWXuFk3DdgW5Mu~pHTGOw`lNa8;yKs z0hLu&AzyC$87M{B1&M?Vx`0O74hC8g@ZEY}+a?vdc>dzF*KL(RSl{)FXIE``@91wR z3uL7Ltv4@Q$2ogI^_rdVVaiSjpYIkje7yNCnzmq3M&X-*?x3ln2!s3Hl1{lqK@Kx0 z!A0vA*F}US*henmS^*NIPuq&`WPS|;J?*Bul%Ip};m_Oxzq979f2D%iVaf$i1SDhN zR)!C~M?rjYNkE*$N-l1PaAN z1vEN3N&^D}@){Z%lGn({hs$ftc<2jo90*oG^?|kHYUsvW$-1ZYVR)AzD&+Dq!&iK&|rSN-1 ze4mZacZK?Mi7#y=!X*GDz~uyeyIvLvs3rz;%Qn<9~xRJ7`N&Rej?(0-_hMk?7(hf-JcMhbsh~xWAb)MNlC_!qLBm9Lh-ys zvP~>{yq$suR0+{%U=9)Svz05;L>1PlE6~UZinVp5NcN!itz!H}k|$r__2&_v6{b*m zB~?~dQgLyy99Q=vP#J*;N!Y9DC^Abe~U&x`IVIIec2NX4`saAfpRN zrg~e=_wD@t;k&=;dtM(xr-jR@r+l3lK>Lbnu>IzK`OLilu_|4fxpDDg}Stom6_&tu$ll#exIQl;$2p z&?_JzgRG)W+?{vCdb*^L5e1||E^{j^Qn~_0T0^ERp{)ftw0h}n8nGwM_c8lnF3rG< zX}^CB`GRTH#ILgw_)d;n_`ss$4d3NXePYcs5>ilM}kJ4;w90A@cah#y+Ft>S&p z{eE$2V%A@?mOe9ofg@(`2cQJgZTcDV3E5h%s1Cv^s0b_<5y3&Zw}Kj)^$Y6RKkd3T z$}i=4O&`L)qlqe4TrFq4mp(oloR(ay5(HqZRpx&Bt$(jv_HJhdl%tx|n6UZ2)$I2p z4J1m=AGRGAfAcN+`nqT7I8_A33aAtj zJVli&V4ST>dvEFwhi+H~4GEjyq%tY+KYq-9lyy~jX4_ucw)0);9~hRiaaMJ?6w0f+ z-luC;E~ZPC*OON`CY0*CYZ__Ex#@&&-~OZW?=BN#5(Fz?Z~?Qxkr!y+Z?f8qsz3%) z6GId2tVXNMe?a!vDF|eb$6+5|c!A9J!Tg)C<{w@ZgWg3;7S_@&*DhBI#!FnXJZ$;e z_}{LVgC2x>0V0Chb0;R}@ZG=%%ryc*25%*~eO&?*T!6;tYV$8IUbxhJOU``H^Zn;u zK!t^cX}*8kD}NAXzK=Hl<5jfzzOVW&d^aey&adPZax)A?c2G$MIjwpJn{^~HrT{Wd zRIK4gQN)b?J-f(r2nA4O`d;1jfe`#vffBp{kS|rpH5pJ@WR>NH8z?UhjYR|6_s4TMK2FzeQKIZDj6hPyAN!l+^n13XF zye5CVsygu<6zSgbvLXsHg5m}e8(F3&1gciAK|e?jYWxC4 zMZp%f3T4YLr=XzU!U`x5PA2>kQ9vxNH>heYSgvG-FU=m)tSvwg@QYX8rEMZ7aO`+5 z%@ytlVJ8wo0Nf<5AgpXwHLsLdtU!*D)+ipHk|WL-Z#2I_wG|pd3SYvWl2XbBNDM(J zc=QWK;t78TShBE=-rN(B`2YjO3xlzNr79XQ_Bu=hCu#Ae1z?P&`+tSzsCm@|7GepK7K#jolO0JiU$;_EI^!v@u0~Hks|(AeJBVGlK-o8|mm-Gsf>1%?U;*2&me}u`V(VA|C)Es73XVasx+IeCwMF zZ~>KoVW#1ykuFZ1nO@+UFE3KwzvbF-Gn?g}N7XqFaA3oQw0EZ!iUS_)L8!Psco zPeh~9tjfT!3I@tcy$vO=UHMu0J71NR$39tvGS?%F4W@&z&M>hVcJBnG#CKCgD)DH% zK16X*{WCR(tFlMF&VDTG5}}|I9)R%c)iV^;!obX&RXsW87<(AGMe!L#r>`J7 z<69yZcCUE+rVvyO<&0rPi=Jvy>x@-~7)vLBs>VlOEx=H}e1HpZg72si7I!_dmMDkNJl|DkE5?(2?@13tuPEaMKEO-${8wI6(|&dO9fyo%>t;*1(r|yhVFy{IB@|%1^h0AjadwV z7mDn5$(e~qH|XPr$l2HIIUyDM$B2MnwA*{}> zaUpsDFNELyCV2vt1<)-TR|25`k^_JU7MIcB;Gkt=XigXqB=+OY2?YokycE7$1VaIU z6G92<${a@muF&-|QKX52hGi#$OpIp&oC^=-QkBQ2#60Qgg$U+a%a35P=E-TA^}y%=eGi|_HiPZ zZA~BzeS7U0zE1#?hrmZfhI<(F=Fj4JC*=*Qq>n|%QpE8nYh~_JovzT{Hue-&0GmGL z4ETPR!0g0K9XTe1XlgVH*?1-h9Pc--$%HDA7gL0W#CW&T0;sgbcNc&t0MURb3VD_f z7&k$szwpcsYl~N3(PO5GD*s=60gx7kq@u{PFuump*we5g8?FDxk8onQDt)D#3LGM z(gjQaPTMvkAAN7Eb^qA&;b9LPX@&D{-H?Zo=VU|K(4%w#6w!E$Ma(b2T&UWM^AZXs zOT*X}K4(-lI(}=V(3Q|>H02@Xq#%K+ZG7UI)}rZJtVQ*UR6fJWdAK>FJt7}Gvj7gQ z04jO4H%@&eP|bd;J)A}15{lld1-(CDB%W>5%h!ygf|MO=*)7#4WK)x z`pe#Q=1d0E>p9Y0I!-6A|9MMGA`cMf5%b!>1P_?Fun^0Q{XXN5iAaFc_3}BaK+c;( z7S<6hc#PXaLq!CA=K&yre&hq71ZO`= zG(GptogiRb=3+)tbJ1RrKvU%ejzS#f~1EL3%fd>xy zUm;X&5^c4YW0cs~DI#ME5E_cM@Djb-yiyp;jm-*x4T-zAxjzfg6~F_80vJ5N@7+TX z-Wt1~KxnCjArL&Ud?GMN0j(#1^mhfSRlwp$lAeb zFGrQ-7WO|<|LmR#RzA(KifCYq`Cfudq|cCw%hLCt^AyQ^fM<098wBMf5VxqhR()`% zYBx7VEbV6ccJZuCVns{;{+ZCejoD z6(UO6P1*oVimIu=*CSL?cz`GU0X9%=iWPKN&Hg?Gp%t~BX4NU8%GfGKEKO73BUKv` z`^p9K$OCdMbPW_T+IfBf{rlC$)K%{IQ1+~WWSpDXA63W{P%1$3K!IlSeZ(lYk7dQt(wLx{D#$` zg}xBN6dvHG1pu6E{oZ_Dh#p*3BxkuDU>*Db##q(#*?#|8<@@bsKVZ8w3|8Qy)yta6 zbdDe_00^Nu17)}Z&)de(Cn)Ly-~iwPI9f)9rw=?zZ*=~aJ{dkHe?F^XKGhV@qQ$45 zPm88C$e-;HSv;HGK2N8QPuIoFPTZT{5u?RzaVi-h`mZk*W)!>uScVhAQk>q$$t!?s zsgpkHYkPcr#m1df37JJ$}sJG`eNNm`3Url_R>pjFVK#|FH(QBkLbdQ zzZ<5!`MiV>Pq<|F2Zgd+crZp@K$`yR)TZCc_iHS64`o0`JGJG#j_$h`)ruMdYfQb* zM@OWPRc8v7F8RD{MDQ%VIwW!c7yhLfg+gR1l?z9o{NqokWB7>es$vMZwf7Lcc62Ab z*1nUXBT;&4|4-?6U9Zt-+)YEY102~iZ7BW-$b|X6;R;k=c;<#5l4k%9XpbbGTBLwnzh{01J;hN6#<12|Ful!{}d-L87= z#50?fn@A#2QN6Z_Jj4FoV^38{q4vHbX;0tv=+NAsph>IsmfQ6&Ub%VXV>D;2Cu)_6>hRbmC z8C}kX$xq zgoCM=Ra)m-IA}8isdNg1WB9EEcEZOPDCGdtm9Y^`!EJf>|@Rr@j_tN&=;*0-Os;sYQi zc1i$JlP%bRaUy8W3f7jnw*W@SIO4F^Ae!9Ec%ZM}6&G*{kY+pKTaiA5d~;veG*1!I9RQJwM$*a;spn7egP6J?3q_F@~1 z-A+ZC^3+k|3#-gN!kXIq9+gbi^?{2B2bVU=r?3J>QV1@fyr4n~qo_FZ#=Uso;J~2# z3~~skdU_*_47tDU&CS0~qkseTDaT{ecemw^2c%bv+(4bx80B2!GzRbLht_o)iRfHk}yiqOQSC zSvx2TmDAkHv#Fuxb9CvSb-M1&Q*`CQ5LFH{p#Y5L^k{U^5nbMcV&Lb(I3qn8r;`OS zip65mO5E~}PF2I!3V{C~!nZnXB9rhz`s!b7>7X3oNvaCRk8#3kQx;ae4zq9P`=KbE zk8W~i4T{T%-}j_^ikTJ;hsR!e;r*Yv=rHRJ}zOB3#3#(;WwVe(Pcv+JY++qW*NC54{_=`+K#-la@Rkjd1cZgBF&#~oD? z`F9?a`w9cKwY6h=2*8xD{Ke;~T)2f$!MJyW;D-i>P29CvqyAY>w#lPWXUlMQap|)-Rg*l9fA%^>oPs5h{qPf1VW-i6YX)vd<0w zJl=1K>e)nRCQ7?-1Er;jvxf`yB5LW}O-D}sSulKE`uQPY>J7q(S^saB{+Q-hokMPb z!q?!wwv-U98)frW_<-l#i;DW@7{IEY`#xyvn0AvUIjxx@~oBW(vK4t`2` z7&E(Au>OK%nYLC$13*Xr5t=7vI?O$UZ`{uYuuiZ7ZpbQTeARVp#H`P)Y zA%_CC{axlvD+G`JNGGlG_@hJ={u$Zud@9;Z8|U`<8W&mOYq z-c5z~WX}qDQ2+xU-ni@$;m_7(dY@ZG$S1(iLo;e!ofr#8jYPA4Jhf-+mC_$j7Gu)jag@JG(_XPDx~ox@fg($ z*D;5q7{z&&_>Zfs`Gm3RiHTf1MdCPEQK!~el-hKypk=BHTZR7z*nnV;bY>*300000 LNkvXXu0mjfi^T7> diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png deleted file mode 100644 index d2f71339abe3a404868b1841a571df06cd6727b5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 823 zcmV-71IYY|P)QDY_`!b$o6>{(VwV{XiP7wwCknwVzhR!VORu9%C69Pd= z^8=wMq^9nqR@g1mC{J8W?I6aAs%mM)9X~XbSHrs_!a2X8`I)9v*rx=I$V6i#8%wXY z8+db0O*8>O4F+(r#HKs4NF&{N&=$o3Ws9$*)mH)W7qkhb6x*x@V#-WHjtYw?xKu?) zPLt=_5O9h(Iy@$ERR_=uiQ1pY>mI?7TX=dk&w{?-&2&12AnCN)q5h@jofcwRQ4aSU zB)shU$VfafWyuLymUX9c4B?&A-UF@#04l7g+vy-GN9>Z|M*0cJrhwqC4?#Jgxj|zE zRs;@jGE$)GgV6+~i%c0dl#S0!{)xp#3kF8|7%{SM1Cbxocy5`-wzLIr(FRCo8aTq? z_V*)ASWJzZBLkzQ?;Qfq5FeN2f0NdhZd&g47sQUD2#X@NOYpkcy=b6X)) zTk3GO^FI7k%GmMW8(r{5k{*+q#t)gBTl{{X83LZ;_p-?9Jz002ovPDHLkV1nAL BYzhDX diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png deleted file mode 100644 index 149582f90ba915d8da96f095440ff59c54ebcb77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 892 zcmV-?1B3jDP)71GS&6zVZ2S^}ElJsQFWbgf! zrG?)cYZ5ckG+95HDbaUa0#LK)a&*|<4C$TYuMyZ>Q;cg$N+Fb=g|4F3Ox>#-$1Ns= z5$K_9Y^Y^-xL5A;sXB;mhivguXXPQc?a8h>JHL{EGYS}i+N~qK9e+WoXD%SU{uA+4|J>q2_8)D5lo_cCaL9`>X$oi;X`wOS(i~XM3Prb5!Sb!I%57I`b;#kE1a{33f(}#{ z0{-9>496%UA7FVAj?U$fVM~ZpV9Nqg6v6X+$T4>V0UI%AqjUTlwB?l$kcrpoz-G^A zj+QE5+`=q89#7Pflm}iD`q=rI5dl3F_Q^4UPk;weqWmpExNF-f(Eo-{vq^NZI zPQ#T}#RSjSDLHSy+!nY3P9zzNuq|+y&*5>eP6JO87mg|)X*HJ?D5$6M3t-XF`tT0MJmt9)Fe@n8PM@8zsBQxTE3Rl`jR%ywsQb-K&lhwR`RoXwH0*00% Sh<>I300007Xf`GRjG~Na}wCfzI7~}1Uv#iB%F@tf? z`4D4lJkDXjyaO0(heCk!ejV5e&REaV z!>{(jJfNtA4Q_640noN#gB}EwA}B6~ura*=@m;Nl`-h-NC<3x2t!sdi>z095UV+<<;<$>~$VKr#a^bAljt-rLC~oWFknQht4m~rU1tn}Q zq5?OphO%4MLHU|>f~b5zq(z6`gwToSVdjlK%WIMncW)sjt{{X7BVM9)3Dq+}l2mcq zCxsLh10;Dfr~6>+*(XyHsRA4MRH0NgZ^F+1#p+JY1K%{;C?cx*(_av3X9ayKB&38? zEqdWi+@BQtW@u$WL9`#$mQ!H4r}cV$Q%x+nX_r(?Tr&e0{wi7@K@ICx&f%@%o#j5QIp z;EpYZYe|yAXnR91J)bv8b|CVCw{3)qj!$NsyL#-9kT_E(fjw$`eJ(2Mny|sYY;Whf z=l?(=afaqX^U-+rYZ zT)-7!f-H`brP!-Vl&G4mI}O*_sl$B1j<|7@w6SNONFU%Z9@Dk;Zb)-Xm=#%dJGvpL zJQNW`L={W*+=8C1deeOd$tM*ZJ-8=*kxSAX5oRWf>{Y`*eM9tC5=0V-y{dlnrpwlJ z7@Sc$PtIrT%J95MAU#9v)`vs~AwjA+{K$RjXLUi^oP?PTycJm_<|OVJ2$Vr!)otLv z`;MSef`d_0jsTtXfz73 zSPXPs2ahN7XZV8WbX0}_Tf=yq2 zCUrim8ahFB9q_;E0)KroG&eU}UP1&{K)3X_L}5DEG;3$#92yvfYsb?Fhv^Cl)k!ww(il`p<1Yx)xSq0IWbCD1 zB1dCffg~&$@=S)K@bHdxt_gAq8i^_-M68M94g~WHVM&ezVN6j+@^>UiL|q|JZb;UV z%_$aH1RB08G(w8&r1r+>6$y?sG5Vv_I+Q4>o3P7)W8Tn`vR%ah8UN3I@fp~;`>3#E zBn4`!sSr?u{_-^)=@Xo_{|dR%VpK(wgm{3K!~>8KEOe@w8hqbZjzHI*y56p#lhGm%s6QUbB|9)ZCGuQW z7&x7FO9%9dQW5Z#g%v0YwP0$V@5N^Iv_qhSTL?dtcVbhUXgz0#IG znRY01%CTcQ+Kw>Q_!D{c3oD@BWry&{L!S^5T8}C7#k6!MIw>>+>0$pmG;PCYugD}wMQj2e?`Pl|R6V4irSMME2O}_pS=I9La#yzrQbsUia2Y>w z=h97{x4&+VuST*i_c*s<*-&`GE)79!>5cC0iC_nFc88FdLSqsKgGO;UM~^^3P%9dfYvx_lX#8C5D;!Z0MA#4{GZn(n=j+#?9V6Gm&hTe|q-(s__OyD>VK$=S_2gTnm&kDh+T1kNxk2PR&1A1iOd_6N%#* zWBPJYq@$^S^OrzCNl?iqLKu-av9bWQ8`(yTBZNR(Jm z4veIX;xn0|%_%3A^!TGu7sG5)%7(26Hb~m&;}%4o8^S0>FY8FmQ*{vTJj7}DNq)&ljhpQ?F8PM@POlgHJxv{l`^ zW1!)up3<=$lklU#ZRtu7hySCa?s{ud(}}(WQS@=!%a$v7e09VOn;`}`gde6etq1Lx zC=-w=S~?~+?7!jkpry>efjVnUUJ-a2;$Bm}Z!gj}V} z=>W&M#hUo!icIM;Ot1NlTDx!fl{l~zlV&MXi|ZU?cqnDZa=~1+6ThxuaNv#-__qxu z@Lzx8hiQLqvl)%j^{T;s#TnbDUTYvMSQQ|Dw6ZHRBil_NJx__z2r+o4kHGTSGP=RcY)L z6;;5OwuzonozO5a+6PD9Jp!+d{sP9MABbbsCB_kg5+w=NZI5zW>xEL+QDt48L{v>U}u!Cj2sU zr7?*s)wDYX)#QKqKcKd@HdSOdIU9n`@2-Q=@-oAvi%J*6%Ice8%SS#BFJJ0~!-G%5 zR4koxDvffO@^H{R*7l0d|MRz;t3SL)bNt6Hl%SFvt5C}wl7}tzkNOU%qeGB&j9?eZ5K=8GMyAN9sv-3_qbz!bSvr=+_16Z7N*@65#3PFj)4GSraBqG>>B@Ih?r$LCrxYEH+6y444N zuNhMtd^7F_$fcmJm!|2_d_w|t1SOcEr73i_bAhTB0l#Jm1Ofr@`Fz6gUkJaQIZKyF z!4BfqhV^jn${8dj0yCKLsMczr_53*8^O^?t4*1|2Y*zVX3_FGhT;|g-8=Zv(V^R3j zY2){4WeZ^O-yJXn){?B$vob!$G<`$sq5d;42V6{&zoi|Gv0;)tttL>Z#F-R-jU9Q? za>^dR;TC|;Jq*>=)#7t(um|>@d=vu70%DS&nHeO;QwxvXdH|MGe^j_1p=byi$`fIk zVTzuDu#dwP^iUR}#+S{qRMQg6Lv$HJEUIC>^0=aPL>5EIdZypeBzecK@&1z+FQKFz zmy$-urUza&Ox7d^kf!WeO-E*vn27I46l+tSzaiKJJ?9QXjL)KUM1@q{b^T`8wf1YU zxV%YR=f}i+g+CpD6BS{LLS>)MpfbY5e}Z>W6VyNSuVOY!ddV3sX2Xpg{`d5aF3BRe ziX~E{as77uH6dyA#wi^{Dk>k2<~nA~nje1h&WmspI;(&G z`;S8BlDh>-cA)R2-r6qG(8?D;)t%c!-0N#98!ix)PF)X)W4gglm#(Oy)S z-=m0tjB2GtDu`y2kV`V%a6JG`+EToJx1eQV3^PD5Bnfg54511=y(K$ri4yiokF(E{Lk@YM zFbl3FragD#<~H*=xeiY0iq%D_cqWqcN$gF3{JiK8EPBzrrAkGCm-G|F(G=))R_Eoi zRbtV!oJZEV_@mU*6pl;Skd(X-dNC>bNFmokEXtyhH1o^L_?Iw(>9o5>&N@+7o+Fr3 z;WXq&i*wNb#KMuoiJ?II$?`=ZN}?!)Nu*VkcbIKlfx*#6jdQLY&>;5IZ{4z_Rv@X< zIPYZnFMO*8i@hkt13F{h`JGt!)(+&7(4;W0#@jIO){3r4o0wpsK?@Esn-<9BVhs&O kWmz1Pni>pzm`f}F26|_bQXmwY1^@s607*qoM6N<$f+5BXsQ>@~ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png deleted file mode 100755 index 3346cbf3f62b179695ff8d31b1d89fdb79616073..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2813 zcmV^5!G2Gb-^r%CDnjWAM4^P>%l5+I?E{3yj%R3&Ol z1@sTZsz{M2Pz5Cwkw_D%wTUQgFkr$ivk0mlmFr=aVQfWBO&h)g*&V=Vu^viwM(}d33oo&NX2V@O3sCi z33EZP5%CNGV8YY=0eO!dF%YD-*Bm_EK^Y<=2Kv@ERI94}J%VjB@*jPQ34bw4l;ZP{ z=hz1n9JtIxofeW#21i6YxlPTK!%XY%WB%y7okm93U&6~X(MDPZ`q~iBr+ zhHX)aLxQ7+-xlLcfZr)zJ*`17;(lX;CIFSj6qR16{p+dsX{HPalOd@c=S3}TLX zc?I`PcswAOimiL18X4KQo$ehy5Fyaqq->M{@g?iGkc(|ya%77iANkXp!p7mewxS2b zXmm)cz`KHA7AH(AxBd|!S^p&nNNV0(S3x_^yStOUn^Xf=pKENDWqJ?ir5oBQf7w$) ztwY;?#&-U>Hp!VsxlgPSTFK7N7Ps(hlC=V2Qu#qTz)#AyY!}+_vV#xrZr2Ev=*Kk& zPW?H4eu4(zu#zkv1&OfF!YA9JwmEgHe|lnQiVDB^IOWWLh{HMSioalUm5}qRi-oyO zOVAp^<0CZD(@lBo=b%#?vmbya70CSmI1Ka z07swE4-e7!nd9UMsU(+_MYVyCXYrhgo-VQqn3T>$PW`vUb>QlGCujQRofq7DQZfL$ zXJxg5xboNkDDJu6crjM;hL0#iH;KlEiAIMhJ1?JPBr+bM4Zu-7UueToSMeJ4KVd*1SmbrsUC^X@Kvo-|E7$9l5$;e7V4Bfv$ksv*i6=VM?+-F-*30j7U--9v?I%zM`63 zTRW-Z`|HvY4~S6t>pfz$0t5sQ50lJ)^l6CPRp^vA>(2!PkUpP0k8@;L0Ct}e#iitW z`8QNNcL7-e!YvY^RlpK7+I}KNNtHI8K}|*x2ErsaW7MS&j?KcLZADv@_~SkOboj$_ zbbHv`zRzB~Mf(o-Q1>wVNYe_k0=@Wy_C(e;XhAR_tF#GY!Lp}gI8F+de$nzDh*J=r zpX;EN-u1ocb7Q-#fD}oGcl!YfB1;% zAJn4IDlQqUBG`XfjL0u^j1W>AWKKHuxS1XK!L(}4$&I%$&;aqfjUmy+jn+ziSf6vZbjKwyf z(f}H`$8}U?3McfON+2Fm^|v+vR$~Jv&=RMj+j@f{u@NYM>StDLr#3X z#!X>+4KK~EuWjr?b*HaUvry5y7XykKQO@9oloex=Ss}9iElIsLP2=fB0K%IHJi@O(OOdamJ!0uoo%TYnMfH#R;anBe7a$Gn3* z?fRS;{mnagx*hvgV#6Wg&}CbGpE^6UANa>cNKq8>2Jgi@x-)s3KKkN_(29;pheW}+ zLhx=uazDT~(c}ft5!WgOwckj50t0{~DbK=`&`=uZL+jn|PR<1T0lE7{I0Y0X9P?O~ zZ3*|{0j81>ukRN?kXq|q9g|2|9zQpM0XT=Es;}bwE_04OES(8QvUM!iMeu|2yei6( za}yp1`~eDc!ovaS&m9br&*K&6xR>pZWf0%ciATuPyMsztdLh}CQ&JD&=4tQ7x+=72 zn?-k-PtYkwqcy&5j_aw1zD+Kdi$1-5obHDHEACJ6qGze=VR~)JujniG2k5cN7JBkO z9$I;Ph@QA2(bsM&R5&_C3%&?Z?WiV4G=gC^@I7cB8z}(nzV^_m-N|S*4aC>hHnCHy zq8F$)S%LVLySjBRRn*i{&)pN$aq{P^i9C8~@oUsl(;D-8APQQIhjF(Py`QMrM2L^K z`-~X?#BPm^_UfB_#=R`DSH>!yT==l))|Hf$&?kfcpe3`uPWf4h^$$vb8?QVQZL`O3 z)8hArcXw!lVVhS}+pDz)PrhSDU*_AaB>$7ASK}I6PQ|OIw^>otVVRkimzVap5X-|8 zUMk=|EKEhbFQQ(jA#vbybyjnwd;ItpBTl zwh_`!k#;IZ@~;Ni5T7{NJ-uTSAzb!{cGN^RF8*%}7#TrdRdlu`sexvOE_TxH znGmjH#taytGb7>OZMa*;MqI7?i}n>2osThYWA<{=9#FZK$3kkRL>uux1ab#XH~;8W P00000NkvXXu0mjfbm&y0 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png deleted file mode 100644 index 259aaa6d9c8f79ab677747917f221b7b669f2e64..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4314 zcmV<05GC)4P)Gqo)BLmgWr zp&yF+fncY?P|;9r(RNxE$5Eyb2vuN|#%zithJe|S_ha|=|2uo`a(DOcayN*bZuU2G zbMKye?m6e4^Sl4oIrm1P>p)9IiNl{}bCE(Wg{V+bv=UMj2WjLG85HtSK=Ue!;`3{C ziqk!|VZW!Sp~*)njB6+~2DGdycWI<;<*Q3VBx9(V*sZ~ z+cSHAV*{lyE|C!N{=KTSQYB?8A3E{desck3E?7(xi_0kE&N5ObWt(0X=T&hmWJdm+S|B?QW#gTM7)+&B~FcOyZO+C-&yx9qwK{GQw9^x2oNmL-z)b$ zA?X)MND#04FMFx?-8c0luR{JMMf;k(l)|{cHHp` z4V-OcNp^x&Yny2qAYhvFb|&n@LONbm#ckB}+RGsVY5{H2toO8j6D|^2iOX@QHf7Ck^V zCgmX8d{zOXg0Of5VE;i4<9a6Z!i~k#yLX;$KT0Vi9m0qg^j_75NYb_ca($R2n^54S z{>z>8#e0XSr?Z2G^9pF<#EE3f$`N+k1ioI7DFMLF)5!-C_kHj;()xQB{;2qtcYb@O z?Q=>YsSrlI>bqu~<_M{8S8&e*;A&{wGdR>yM#kx1t93<-)|Sk zxeu)t*NZq}3P}Y)JV-m0i>>QHkfn>G&6TyCo4)EltNO#?hn{X zR29=$i$y|TydZET0)^9mLuN>f@aN%7Esaw4*x+G??R}wEj54e+e zmE4&wu zKC4EXIIkOvdU^AJblhf)hv-)jlM;ZP3z&z4w8G%v4tqbgd@)GZ+#&k4$C!jhDDmu z80e?b(b3S)MQp$I_777>XKW&6Wv0;|cCHZ{pf5Jikuj4fr;Jto>=;#^2~NLZNfys+ z%%d@YJIlxFq@Fuy2~-Ow?FJd?I@^fF!eop>|4} z!j&@J)ACup&*9^o;Hl0-=9ffBM<-ne&~ZGFRosz>SprsaQZ3X7|E@9XShI5&3|2ev zu-A@^j5s(Cl09sfRmHN)IL}%x$IXZJJV=(7d~tbht_Rma;&`Nubr_2$n3#3Oy!tub zYM2NIBiql{IOT6I@7%F$GFi?W;vE^kf4S5Wkj!p8yp#Z>y^XfJ40WTQHlZxRAS_`A zuzENy2E!#D5JkFn4ukkSf@I{6mV|lbQAyNun&W+^$rM=oC)yYxDaQ(Ke-jU=Pd72R zb0+Hp6N$)kl5~eD_yE*F{qXr*3@!$Y)8`SwUcs)p{q#4Buxy zpQo=3vP01kPD&6wFm7DO9l0dJhBO@*opij_@!%yKhm>BUBT>U$N}C#!dh1bEJkps+ zes5&?lGGKEZRNU_$hM+R*sseCSsM5{I3>FwneE~gM5~5jS0@d0T_(!UH$NXix>%$d z<>1EX6|w|46@XB=8hu%>MdE(DDRDpocp}3jW@<=!ixs@z#`)beHaKMY-bBd91hPmXC-$)Cm>6OCnTV~N?t*h*e7IypAQTl~lK@0pEbA@->G{6BX7$N3 zOH?MhxG^!XWPyBbt<=}oXMQekS?CZ>#N#%1mQ9EqbyZ)WL0SkfuQhOb|gXb|w>vDaP$1E)zDf zm#1kpvD_#uY!L^_*?-2i^JZ=)nsRko%)!K)xsGTC-_G=vtf9Xh+;EKa!XF2ZV*#Xt zQvo$A-o;SHB&7r}2+}q|=ho@cfIFf|?xO)s*5 z7-H~cdwsfOF~aD8$lnceZ^^Ed;TsUV-bg-3HnaiuBKKX)vbdf?{aAmXnXJ{3`D7p9 z-kR(IQav`(whp%x%A(Bqv#lYss}E;TR#VTjq~C&8(X>4ySNiiK~>36 zfYVqmLMBY2lOPi3MHIhP&QzdmEi%|EZL=i^bx87s*-%hRT({fMPLu_2+a*c2JR*Oc zZ0Bxx$vn7T76Kqj7%4y)&f}4J3z1j!UmyU|R+t5XK|UE80{KFoEFK;i#@QjgTzKfM zvOV);-B7jL~r=V_k6m#%-4J5El1uHn<;aFi_}+M zh&{V7*hi!1PEp{NTg>e|AiIo42d7i}_C~U2^^iUHs>%%v1)U3!4#)9;m&Spfci+No zdgttG^pG`F!p?|*hqrpO(14+H5o8YKm+CU4W+aj3Gl}qWdp)EX0F}zun}$lv$fuv< z@?me581w68!7+$*TG$4|YzD}Qa785#CXxj~Wtb-fghV(E&IP9CDrK@ylF(EgnvqX$ zzx3!qa+iMJvb}g{EBOK5V<@MFJ!>EO&d^TLr`%Q%?-Zlcyt1^GFRsRW7MPUpdhMmq zvLrKT4^>ir#ahbFjy>;+l_l-ZuBWjAQ+P9;dsQ5t-}ngmJKO4uuJOtv)M-XWMwDGM zI5_CD5&*??l{CzKm_g9XJ9_k}*Q72dKgmu#ukjpaG$QNN%hJ=$W<9L7)2wc@I`w)v zFARPk6ToXcueTxc{$i!;W$E+KOva|jdpFCEV@N$?d4hQ7R+YP0-5v(%Kt4#j^G`k! zca=)krtKV6$&Xd1u*ohwy(TKXKTQ#pP8`-K9&X;?7Hjc(kGv^f_U7O~QR)*H$pfJ) zp>BESft1qMz{OoV*B-~Sm4L)Du0#Rh4$YrH+a60N&sEnm-IppEY0kgkJu5C;jO^f22=)&WW_X(Ox<>FPF(? zr+?jQqvtEq#qj_W&@(sovUzy2(eHiuQ(qNGGK5*+%`3~;)}v~?-iX%|G3Xbbe%w^$ zYWIJa@*dkjxw*Nt`Mq`Y$-vprxx5Maf_Q`4fcPEo2S|h!>{lh7d;cKa)EljCbvqMv z!?xoFUemTq;r|a|ZmBwiFoWj(;+5?}<%&1Ne(|E|;!Vuk#!|N({q58P^N;$46iXAsiAS-!r?S$QQWKOalW0bX(3GeA`Z>VL!p2MoXqXNLl_Ix?8=2 z?myZ~n>kQ??}=WT(cDWDJNl^LvR~v!nFyPJbdYo)Jfv+vvu#Q_6v>O2pDB}{o!t#$ zO#R7kLhn7`eOuiD(H1>K*{hzUiH;1a__Ir>)Z(0bXv>0UY1*V2p|U{W!86ex@_`+R zFGXSXv+-+GJVQ}6d*88oN+D?xGp@1oqxPmJiwjO^16LOI{QY%@{y`nsVA(=C^^$h+ zGa8zEFHOmt%IbD1Ex&CwRn7e&Wu=9$3;?_J7k6MUW`Ao1P1*P>nzZNv@u>@tvg3uH z(nx!Y&rj-74(~Kj3Q3J?e~LEv1u346QJj!|`5U%|eft;=2EG&(bNWo8^LOshXUO#T zJH)4GIZlTlF=2{|!zL;9IzC|etMARL%H3@2uLS`?Jbces5Ar4oNI1N|%k#q&7`Woo z{OYz@`;XUB3gZTri3iB9zq{GGTdYgKjN($txU-zn*#QZ?{~7@}C|Lc1rB_h7A}FkA zJc+E|}L#>eCTyYuCMR~q`hJUcaWFt*!QdDZ7e*c~n;l?k< zM7&5~k%3*+<^=-UWF}*w@f=52y0L)MrrMgQf5e+2TMEE`0e=8rR-}B(@&Et;07*qo IM6N<$g0=TMB>(^b diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png deleted file mode 100644 index 10487147fb3ede0c62d67a387ab160dc50e43f9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9187 zcmV<9BOKg`P)n!exnKmVTncTdku&!hJN z|4%XObWcyeru*B!$N&HP8#IAvzhPdBx=GK@;H_^*mVon%>^ z1{u+q#qSMkuN5=eLY5h=`}K=$q|sg4h1p#cM2!no|iKL~d&1HB`Z2Jcu2vxIzQr>)QFW5I=}v3bgQP zG-n9~7d*u1EV9;93fHxC{$i^7^et4%mfTp?Q!D?@5$ncZ zxWb6}!7WY))^YOjpQaQ(gRJJdt$Q|*Mx#07D2U*-uc{AQ6xzXW!|u)33fUX?Y0Usb?Rh)4zK(Z%Zy);0Bjo+CWv;ds~~Gk3UE!w>_9NU%R*( z&6z{af_G?D!@~v{P3k;|%IrISD6+09<0*7rAfD(Ye5tHG!$7;eUF%4r(M)P`5 z3wxSlcBz2%Hge!)Dy}|<%FdsUWI)m~5XFk65t_kSURZ&HhYyUI)d#U1K7K@Wce8=Z zi@kLA%{3xxKTsRpw69|?X*8NiLq@@iH!3!_^4n5-o?GmYg?;A-w+mM`9T2nHyIQDX z!BS7Lb5k6?LU!f4oqFpH>KfqpeFHQ&I7p^x zdb+p(f-{A`pGi;)#n6!`4IJFZF}-UY`!I66W3&{Nfd_!OvgyLvTORn^JN=~5XeK;q z%`A7^4x%;pKYrn8dIC4Ld*@S>GgUQ2b(fNLddt*J_9B=EOAQ9FaKN8Ah_c&upiFn`h{QrXEQUi&M5*FGiwP7(0!8bX!r@HWb62qLp(Dn2*nhB1lOM7rt zLz79y!}c^>&GR-tnfN?qhkL)2mXmeG$Eobf>#1_iTq-LoqkK5=$ldu{nrT4)U|6?m z$*cxxBbK0%6ghnroE+a0~<&g{mKP=G~Oa?1ufC-QNs zI%hUbnKFg)rF`M#fo5{yzT$Y*BnFZw-OoLpm^R2*)^ySA2Xq2MqnWrQ2_CFFwd)wN zvg(ZvS2kB`%DUoXG~<@_G&_8LL4-~PSyZ^T$gTzfdV)aoOE3C>n1%%ut)#uhxb#*lb1I?`w~6Ou#=-}W2o>n+2mx2L_VyIeqn;;Qp6 zb~GmL?irvz?vB#YV_j5HQ9@TN4%4|c*$>nB4uAhAKl>9p^V8JwVlfTAebZ{9=kjO_ zod(;=tCC&o;+2#aCo;AcQRKj?C6SA^j#0M|jYi{}gbIy>LTgoXPi=FDn>?qwcBK_$ zE?7p>rj3f(!NVu$j=P?s3+K(Gg_p8RSXNAb+!dv(mS0R$D@rI^{`J;I$M+znV$+HU z6&hH1u>ss;4J)>i|Fn`uqnS`71dqk8F)h$bbf~eMuD{H8@xHvI+#gZ_MC8)049Z)P!)XqEBk%)7`B39cc zniPvro^I{p#fw*3mX)!Yi(wd@cnuE^w=rj2xvKj5`bv%gi}*4hV?E6 zWzT|h8s>8v#(O@-C?8{#3e1uvOCo&zF2v@@Ic7D6K;6r~MeD9zV;k!hf@fIH%%VD$ zY+iA&+Hk=e7^ecUyF+iB5bqbxk6Vysmo@|@cmM;4+iooi8@SxsM#`Ui`KAl|S&%Ov z3WY)t$tX{@j*N_K2;w3h4;N7zY8npw3R1Y_?+%MQ_d-$ zhh{!LgkErdF=Rmt6#)5AS;OmJo94FXQ&PI7W*|)Q>lNoV@VK`r;&;~Q&bdWmFq&hZ z*~)V=F7umbU#9E6*g`A6)FQ;nZdQ^lXoGiDes|&gxgryMD0*BZUxJL|xzCMbJYJ6D z$=GN?;HM$nfM}YRm)j*Sq@_!jj+gjOXfmA7sK-~rxS9FJd`Uk@oX7`(qYu8kCR-_< z!22YhyA^ohJ-;@&&N0sIz3c|(UxFzOMI%NitTsnct&|`~5ras<8UwRuO{1^ebUEF} z(;M!%in67rH&L68Mf9)YFPgc4A~7yTFvoy%1JSe386FmD9B(9KLTGY|H+isW&z?Qa z=@x*n@kO*U7K^P`T;VWJL-ba>_~MI&+Lto|xN@0dNHPx9#BW#I^Z4A><3Ylrx9Cia z?_~?bPFi&;oA|nGPIG>?^SOl(uHfY!vaeTuAE5v-4byTw{in)?^WcejRG;J=JSDnZN7tgzdf@DCc8dIWLcwmg(S_m57z|Aa- zb$kJ-qpDT%h4cjCE2PN^2;%PDyPG)1RL8=nJ}|;8dcNa?d&GPYkd0JfiXo*+P?H$D`Z%hx3_7ai61j z*{HbiT81^Qu``Gs-;nry?LN{g@kAc$rT|_nTed80zklI{7os#tU`uZ;TOE#3SUR0?n9<)sYqSeEe?6b?@k_z zuOk-o{1{f*FE)Rce!ufIVc}h1hG^;&-Q+FvIXeNs#d?}XW!-WO}sDS_qESyA)6=h zdhoDJv|YrYRlHxnm6M5LBS=8-aW>N!z(R{ZO}sCw`IzzGsZ{nC*AlM77B9=Y2-!s2 z_f)GIgS;&~7QMk4>AkwE8iS3ofuiYby|VRI#Jf_)LRb2}WRbHOKEJWJoizdz!- zS)U7;d2P0*VZqsAhb*;X<&sCzqTnDz!>r(Q^AI^3GOO6q(ik$eLbG4s>%&ae%F-krbBapd!#%W~7^{>W)y=E#!+>KT*eHlot-cGsa)= z0N)rbise%YaTqJt!+p~L*<2xto(ytUMEMvuX_&HTTtz@Rg*fl!b%2Z<#eHOYS4^q(dze#lLne4@Gk`bj* zHz07!Q@T8fUJ1A8Q_bjEmSwqONJ|L!jH0NrKhNtSx9VI}$c;g!K0s7gpKyS3C`8URf{-Au0<|_@nOw#%0 zdAKfG`0Y*>#6Q@g$LoL_d}Ue{QZtS@Arlv=GPP+r@l>E<2aB%j750=5#sx1|)FP>q zh`4?7y%U)I)k`(UG2aggBosLiUzroYTC=eV;42#C(=JSJ$ z>)4Y~3K;d~WLgU8@_2|{N=qjw#=2{nY&0IRrwg4V2vY3wfv;O!v{_$EXxk?fOL#^2 zWw20QS0r!BxZw4;Gmd#CG5ULil{ZjYn%(!1a2QN)S)SsMUgz`vn~wxV(JW_E8i(K+ z6G!mWAU0cHQ3@V4Xztsk$^@SDQtZNV)|iVOKxrj4lNxlT50uAJw^zu<&S);A#s&R| zoy(04QwEUPUbbvmU8>Iq2M1U1Iv;Y+m&d$NKCCVN`&;sf760;+c5;dTE@Z*ujG27$ z4c0U1&4Y)<#mosc99(`P(?4PGkgvh9Z~U@O;*Z^>T6PdRDO{&PB)&Y<+R+^ zuw?}QcvVsG?GpIFGx_0u(%Y4F3jx}ixe6n+jJ4>wyHxSbUJ#c(UE^(~%_1mh z(n)sQkIKogtOOHI_Z|7rj4JC0a(L3H@;>Kd$HUU(kf7tH91xx1;}nMr&x+z1cUWwDQpPYtCngrd~$lPP*zcd?UO>8^&QXG!kKm24{q&wcclCn-Nb6H=0(0l zG;>9~Uo5(hnQ2CPw7ZyL+39SURbC!{zry62dU+7}9R-7l5ZQSJNd$O@I9>|UMs`$0ttowCao0?5@yJhMPoij%ci#T3i zUtd;V6K?GVKa7iC3LtzlSiEMl?$6~@G4E?cb$9aLud*245`SSDFTBSxShkvP>#ED+ zuNgTur*c=9>3>z}4Z_)Pac;)}T%>&S@8FB0$)1M`8HEJAmbbek$@i->J=xt>ju$RB z4;}39B_Cu{v(HQPf-1od(Q=C&vx&2%sodGbIaNw@r9`^Pk#x)OdNwKV*ZL9CY|dx4 zqKD80FYB(mxFeef4}^&=V$>S^j@ReV4Rnp9QDLp~Qx%!7KUjlUXBgA6xWSfq+SD5T zabTsWna1)0j5cVz`j_~+v$gU-WrXOG`&pr`&FX6?4giZTQ>+gSkkQK`7p68k_er&m z4THu^>~K+|+!AgY2pz^1Am!#!dO3Iod|ek*Wx9*p%gXUWx_OQpG~E~*I0oMTdwJbi zl}~qzo-Dzhx9H(~LQqin0OwRzM+w`X!<9vm%T(WY32`LdK0zQ*-kdT3i%JnA>_ggd zAmqqoS&hSyt?0=f5u21*5Lj5-4`&i&y9fgMyOLAv_bU4X@jB@i`&7pS0hJJwGj8R)#n@0&Kw9P|< z`NFYB>~-_G%2+oKW&C-)i#*obMDm=f4Xsu&%tU3vc9=OxUqm2#gp z%GVlli5+j}B(5nhu>*X}7QaybeT!?|P5gR7xkj;WPq70+@GjcQ3a7;Jx_3Hn-a@#w zImhulfFK{++DgY+u-<-zwUonrZ*PfLJAsI~Uzq>qgDi4CCOXQ`*VDW6@1c>-o#me| zIv(*mb(APR*L4tqZ2FdBc|7ec?-9FfTBSAT2w0~A+lN44y_9BPa=Gsq_+=5_)Gd?) zL5QB*FNnn_F;+-6JshOqFCwSQm$ZKS!9+eA6hn;UxFze-{Z`pN^t`qsMbEyL?E#@Y zMGxm6V$5&1WVnXB_VIjqO{Llwyx`h4`M5?ws~lUyA)tvK{p^Bm;RS?AitbUkfo;of zTH`g;`S^o*RX|1@&${Ac!pbWvE2Dhy8fzobH#Uz#0DghhTd|}uF%1D$i!5+>pp^;$ z{~kB{T&|O!zMX|Al`dVI7G>0UxF2vk(f)0(>b9c5CdY`x&CG%4Hb3i?ZY6G*dA$BA zxH(uanq8!cF}Ct{R@ldyZaZ=;k5+q{twnWtF~AJ@pit*j9@APr?u|HZSyl?v8@ zWxHMV1Mw$&|1upXkOHw$y18Mc$3&F3)s}9QI$jpmU<=;6n!LF8Kg#>H0$tnec|$`( zo#~b*StLNYhVb36vKW>@IAc4u?N#+86{v>7wD2*vV7+|Yjq*Ce^@LUt(cOZn zVZS-BinCCZC|fPW4zWC&lPq|h+w!PhQm8l{bL_qi)cxF3G+s@KbKQGPD|vCN+u9t-`HUTn<=KYOjkKAG_g! zWvtkp%_}pj(P)ChA$VqAti_$YD5RBVx5q<$ynM)}%iEtX3egX)E2W?RQ!(WWVs~k+ zJ0vR}J$uI})o3O<4#BJ2E?Q0}GD=8NoZL1V$Aj2aecI=UI9_zbds^k2srA$4?ZCMv zZN9pMe!)WbcC|r&Vd2BPe5kzsmh{%$7>wMc(P(lfNde6M*haUNr)EXr*5=$UPsZ_J z;pH30OSKQZ#RmQ6gHz~7A1k4QbDW3w^1Kk`yuJC0MYh^TTX!1GKX2)s*-9dHj~}a*WY`E+WPhj5qoc%L1nxv?@cv?(7pOTZ(%!KZcyZv?1znn zD?9s+yB)v(`Y6*DTfjpA!9>` ztcX30hR0>>*4fol(EFl_h2UhiZS!P(ye`wE>gwvmYzST`FDaw=XqRVMf7QK5MXUPW|v#Uo%r*>sEn#n~*{|@e2 z%(5I62N1(jMGtM_AbP&t+xGp!wN;y^TvRnbqu_-?AsQY^pJjyw7#m5w9wax?0XKHe zcOGzLWO1zSxScg(YFAdHnPm8Cn6`OeN89ZS=E8o8*z-i&JR{yj#RgU$>?cR5^HiM2 z$&Z@3iRLNAp%VJ}{{QyO(k5W78j!s-iuikC77H9=e?uG(?Cb3lf_5_2FN9IV1o@vC z8rAg=9vG(Cr@TcE35uDko#SYDiXF%8E_iI$_erDCOe%c0#NE8_NbA=Y)Yciwi1J>d zhjxI=;QBffT?{}|1K||({J@~GJ;h`bw>F%cbnx*vCsW&(| z(Jx*Qz);s9&3`LKH@y_1&%Zo{7I%bb_GzNt*bsGEgVZ(H$AUN{MDbI9HK=^Zxo%jf z=iL51n)c7vJLY?d9qa3+3m@D44bo^dla9;*Ef)t@Ep9QL<-*~xn6>$(AJEfpJ?^mbV8QkG_fb`-n!fdq|4xg}SxVhQU3B2&-{{xzzxIig0{g}ci;k7YcsYaSA9s53B3}39=A;TNo?=I|<-)DIn@FS4OiHru zYsK#Eb}vhB`1ldgPR}Tg_ntru3^Bcw)?R-vQA32R(sEHF53Vh&yl2|CQ!%@^5IR_I zy`0$i(Cp=OcjE&zZ+d)~11vX3iXGk?Q%Y#$)Cn3mxX*K+XABrr+ig-!@2I}Rs+)P^ z*J#!kzv+nAq3Ox-hrUmzpLx`=4lQ;X&EzMi&ZQ8&+b^rFV$XA#JrBb>_WbF8seMN-CELUG?SjJV|Z>3{Y%4IBV?>+Wl%>75(0!0 z@m|%5;WqZ}YNf8f?4Z7n-z>_%&zUo)AY)yqLnQ*l=*l6s%dc@*p6YiHuS<$G8dhh_ z3az_vYi+wEi!lT>cZ~Nrm|I6b^Wa=%d!s-4-5Ad$qQs_^QGgv zalwPg!M#qoT~4Z?o}IJAlZ_Qcqhj68PNO-qD2U+M99p%c*&xevSiDTaH&#IC;J%{A zh*wq@%}zoCBhBb#LK=?RCX*8NMkb(=I z&B0X-O(xO$RKkZCU+JX{qAOR<6_nF}IHAZKvwo$r<^&w8LpQMtezi*vzN68c;RGgl zHkpLa2BL=qLrM5zDwBtzeas*!9nN-qkm7|(*r_hnVZc1;f>mT)o9KR z0v9|RA$%6CA;YNm`yDY@4`)`i8_)yroMBowH<9Mp_M%wo~uO7A+XP4GnvDjM9gf?cf`U(cDxtOsfW*FObj83CDdl_@VQ-S!gt=4G8XeEnMJy}L2 z6#^DGURRq%#?Ba9bXw#z8Vwj%!E*xv92t&<4b!SO4P&7t8Z%pA-pk4)F%+Uk;$;{{ tTg;+UmSMGp%urk1FJEjUjYgw!@&Dp&$iQlJH2nYo002ovPDHLkV1inGDXRbg diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png deleted file mode 100644 index 8d88fd63053eb7ff973dc8101e04012365c0b9ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14223 zcmXY&bzB?G)4(akU5ZP97PkTgiaQjFySux)ySo*);u_qocyTAVyAveHOP}BSM=r^I zZgy{WW@qMZzZ)ShD}jnchy(=%g(~?&R1pg5!^->bU!iG#|F_T=*(YLyPuNG7!o{%?PcSc7!T#@|0R@vXxJ9IsAMaHUk=jH3!E*n$b{xN zvk16_5lPxE(w5GHb(9q>W+aCnOLb!53|f$^h5DFURY7?syYY6~d~FHNTw7lIwWe|P z`nR^?*YfhON7t^m`>qX0XRZ)idKWvM_;y4D*dC{GaA(dGqcIf4l4B(L%l%i1C%Ft3 zD|&*uV9AeE)35gFPuoe)mZ63=Z`X>-ec?iUL9wRKk zgrU=8Znc?IB3`22utFFxBsla9J{6$MoyPom1J=|`xGJiojIxeD(n+2oW(S%YM;swb5Xema^=92*ShdYqvi|h_Ggh~ zeA0$>YH>J=YyIv!PF?B^9zjwJHk4y5dNmA~t$vZs;3o9|)Ok*Yv*jp8p{kw5j0Lum zKaJ{x_uYd9UjDIzx`lO}dGyB#d%J^J)%zkLc3s^7c+OZ8P)tF%X0-AZ#Z@9DRK zr8?G~wDKBs9Z6iLR6mcK`gUf`rQ-){oZfe3(pzDK%^?fU*25C|^_7O1l$NR^9RY1-qsrzT?U zA(%_a_yoWwjk@o?)KTBN@Q}Oe)fI-^NIV~SzTG}!SA+4~fd910-xY4Zh>B7R>vQ&F z;&hPGH@iu!nG%wpcJuu7QUcN2}$=avL8_f0OO;XR@ zt}F;)Xq|_?v*Qjd$P4}l28>YYcPWYnAFGwmR3W*A#6EQ~V@$tOE2`bjC_?klE>4?7 zE99-_>Ax~HgHO>cHC=yMO^^5gCT64Q64oAhcaD^>3t^Dk-L{oX!T7TF07jVyr?ow$ zygf3&_lcbQ+73NMM?1UcZjM=FBK48Inh@3AsoQC2vA#V?hVZMfbA3zVyC>5j>xC>3 zHi?Lnce6rDINuA7Q|;z>9T3L$c#3i6stEUf#G z@AKBnlZ9@W(HRy;r5e8UZYmhO$zYDO;Wk9~z&j-Rg#r9of)D423=pa&$LwJO8cIWY zgg^{)UQA6+iuO&Sd+xTM1_K2Ej?4;Ys-&^D@nt*u|E^H)z+9=o6WC9d#q5=(UUdyC z9Bw06VNF3&=q&zG`e;mOuCPy6~s*$^v?!gX?~bjtqzF0H#1ckHg$=ITfcE; z!%`4E7Fqla%?!p6BF|JKJ8>b?Da7m+bo`7QNS2)25u!?2v?P;(2n~#|W`Pb9eHp6i zoSz+8Un}B4ffiexUD~R9fW?YnKnRrA?MtTS%Fqfzu8W(hu*by4&I}JDprWB^)`X!0itFlF2mt`<*>AMOXrKA=D|Y%=t9ML{ z571bt2Wd-tWTKs{HC<^5*z1dJMEXBE?V$0!6`dE3yUcH`Fn04^qWp{5CZCz3IJCMe zl?F=;R|oXLPXcxPJg$d)1tRbzcG?)^Nq8_)3S-{%bglXMy)Lz%{2#jShPv?{@`aXH zhnHD@P-5La&iXFZXa93|;HIW|{WxvZ77c!C!AB!wWK{3bsMtN@>gPbp7L4UqrvuG` z6F7uNEkAEmSQ3~Y1{824u?nlJdR`Ca9WvU(@AtFU+j#O|b-=V@ZBB(G2-tqEc@YcM z!p=i?zI@{orp)&fAYgtbf&>%MTqP)3xVxuYT3S|8;%)7>sv6~kZ{rda_$u^IKz3AU ze;CHvU!S8`o3>WN{GR;S7@dMF%|b)~oe;Gb0kZdqoWI)wG_P-smTQ9`+T@`nDtN~; zl6MWIkKaU0=nCgM3CK2@IlNivkg&6}?@2r6e>~sKCy|>WyZ3=(;a;XK6XO`;l^u+n zZBFTHd=J-TMLSaF8`||Pao?DXN+dz#vfZs$j@Q{Mo~%3tsVy8?kd4y1x&+hl43+qn zV}#=+t)c=^zbac+59u1tytv}nY+zMM%)enwOjI(@1`70=c+ac}j4lCs{Tf)AxUda}w6ea0`IUiWxHykCcmf{ebrYn&WhX{w*qr&HuWz{%9E ze9{!WcK}j$!yml~^OJGne>35J{2QnFQuF)EukYKWC+swvx}VePNun`rwOuv#;ZZDe zbcou1{ipI4O+&4z$4+CL4WpV)ZXFX>$*J2g`V_jAw+S}m;X^RH^^hE=0|yxpUpI(< zCeOcPy5-(gv-&9#%)4CPX>orHHvJbVqyh^KX{|Uu!U!G}M6)Ch#rbNqL{@Y;fA-nE zWnp5RYP)wX?o>&b*wD>9Q6`z7YHE=7)BO0~An$fh zs|ByLI*$d#f)qW3tl?tw*5fw+*7$bTg{|j5 z)rdKWu_TfEO38OU$6SmE5WSckn<#2j^R&`AUmi=Xu$U><5)dnCn)p2!y88#w?$j?A zJg{Cb>ONbQ+eDEN#ESW$as}3GgU5y>aEYu7ERLDx@<~X6wLb2BNc^O+HDQE~xNWj2 zVtkG=O{`SYq74C2pirLNd^a>SAZ)uolje;0nHh5tcC1}PQ}@j}hR67$w>N_;S(`e4 z=d<*Q-D<9)Y+gKSIPKv4iV~Y47IgN#fvZeuk{(CWdk>q)v%wsq;-MgXA8&iUl`G1b zmNVj$dE4=>@ol7p5JWh)D%oen1yinC?RxYLy!6}X%Wn-!R9^mKQNV^=BN}6U{4|8B z_lD%832N<$l1#gnpD4!~0k<7?xXujCtApSlM)VKiV&HWc^nroySI(zbci#1}Kc&LosT$xK zL7d#JB0dg8%;qvV@`BjPyU@^ZCbiY@qm ziuL5iUG?MbG<&%(kE4TPr977c`?d!boP4l1CT~ymO(_!8kM3TQf#|ru8N4`4HzblL z4^|=~5a&e3ZHxI(!}{l@r>Dmt=bIaS`+0A;3@RrOVXyWwNkxSk2ll6J4!H4~set(tm1*|5L3|2>*UPip zdC3(>AhxO~MV1%*gg+0SJq`k4MMR#J#9RYY01ccTt*OE2*b0fj8k!Xls7||w;*ps7 zUMYa0!T=W87Vw64ey}4!qfev4RzN_MoH-q97eR1*oV1ZyGWB{ef&apX3`kYB6crFW z9st}VZYzyV74J#4}Z_4%jA$!Z42<8g3(I= z)&xRnF~x$3i<{G*TnV`LgGI9P{NVNSrOV4$C$6 z?e$fOXUZv+)zg$FfUnAam4(B?`pZeJVzBI7#X);E?!91JhM%bnLV{|_cQ@iT?VLBB zw@I+V<{}8eGd5GLLUE~Nxfi>;#uGmJ<9#MsXn~2cF~oA+^W6KMpfFkcOhuc8%%-0*qPNTy&8exV9M4ze^$K;+ z>jou4=PCz-q|IIiGyo`M9~YbYOVW*@Q1=kEN^V< zouKU1+#MEx&QRg!g(#xMD~qZjEw+bKk5;|*7YbJZ1Qw`lGN!CjDMqw?zD}2dZ1Su_ zmoXCbc!iqX6eD)KGl+~6GARLtn@pN5={&IQJmDKEp2Xe#>468cLWiKAeyv!Xu z>+q>a_OZ}tbEef@Y1MXi_;l|@3#6TSvgi9u7&Ei9gwJp@hi^<@HWS6%l|E^Jfnw5N zS~=GeV=(??IUP&MsL6z{*8Vn)O3$EHw-$qPe-3z_j4Dm^Z<#RYZvhwWCT_nRgvWk5 zs%jpU!S;wAOx7_MF%~TqmaMVIbQrFffgDh1Bf2SuOe!WLA(U5D+3dqv!1&e1qtxQj zfDLdH8-U%yN?=B9aIIx~X<%6c@Bk?I@tz9eiA%4Zok`QPscV!@t7#!3B7(7iKak(A>ss>)L{S9|t9ySQT(~bmrFjzN4?&@K4 z;<5uR+SJodeGdQ(at)fPbzdwQ(_ zDPhcevc$qzlfd}~n4Ja?a(~Q_q3#{H%=s}W6?1~GnoxuC<)z3r1Xs|SyfTHN8e^_4 ziIq`}nhHIMy2sH48`Vb9q%C$eI7P}J2#i&usqc&-pDpZk zATws;tHE{SBZV6UGFqo#&e!}a@nlDQtiDUhTsd|(@FlMTW?7j2@=|vceQ$KW^>IFe zbdFw1L3P#eCzl@*_f!J6M8lsQRT}oBq;kAqJ+jEV_LiG6FA#BlQ}ERDAll|dNHfpp~@9B zTt>|h%5e|gYr^(wJ(CpTZESmo?5o~g*1LQ8>x(O2%TmIk&>DqlL1XGT`Lc*9lmI`0 zwNb*XKtO@Yr%m4#YaGoFdB77xK2bmngc=2B z>6c86k&z6OsRoI!qg?-z>kZlZ*4m9LD%@SW*c>b}@yp^-!s6lnsbcQDol&KWm%`Q{ zT1&R}E)rap2z2k_8tsZ3^X-fRN?cBl7g6}Mo^oE9A%WLFX@V{JulDEU)4#Qid{jOS zwAv(4(NUX~UtH{4yvGJcFyunWU$Z#slaHTbuYfrHgZ4D*_X=GbHcdu(#NZqL%&TAe zib&ck0Ok`nCAH&K4#3h(vF}uBj6WmWLDd}8 znB-FVP|LnJQUluBrjrmOf=Pxv)D}a^;=4HYu3ApX8`j>P(&gfF#%5KA2v17sc19#^ zvn?=!S9?$*mUx=OR&jCYo>!bpzJJuy<89zs3xcS318b34#j=`=l1PYJ~ zIdd=cq3podUY<+`x^WGxeVcP~z{Z(2s|xPs@yT{1kWhAZ;5O}AOydZJ7|H;%%2-xc z!V7`p{5P%)k1up&qinIH2+703+F`yUD{mjcjL$kVDp@oRwT&13je$S&=(M6!cEi}D zex)G7_0^PMB^4H|#W;th&;W&C?gKZ9Mri3A} zSB={JDk}DzHM7Jw;=DVx=0>05&1aQ&SuVekmA~;Q%VO~Hf~~rWgGL%6f4icG5o#ak z#ZIFH`aM)-%m+9URiJQJe5-D%GQs**66uPkd6p6%Ak`YpmRMu|kzf8G7AaScn>}+> z1w8b4IDnwZnl)zQm-!5#agSzx3RrfDyINfP=7YjQ2v(>%Q8$}THCD}dRcECsZ|Vj4 zm)_^*c}v#bd)hN2@AUrtgNaW~RL%!>n?EfQ%K%Cl)NQjpw4;bPvm#gpg0McbZ4~Sw z6)ZF93)K(KJ-%n9Kz1+Al$<$hiG$HG}xJi?}u; zSj65vqfNB|pU<9G33!QO_j{*wYPS-FOq<<)2;p%a2ZeRI#4OO9*8nvO*( zLt;+_za38i9pqb}A~@kzAkrCc=#*YrzQCvx{?K7Y97jw~4mWjICJ8x#K zR<{0CySJWQuV2+h>SB}xdKJ(G_9DEPpz`PaFp_7=ahgg;CoW0R!0R{^6bg*5D8FiJ z4qSL>++kR-76R!d)TwahAGTRJP7z<`p9<&|nI)}^VX>IJz6>taKo@BzQE?E&ur*QL z@TB`SB*tCZ*{n47+mIH>o1XN0peenr4T*2m6t8=+{w)cGr1qZ^AsqT;OU^aq0Q$o> ze+p$^=LOekRVLpcB*=JVNMC+SlicRv>wCREFM7L>aM1DVv_woWnL5k9@kFO$AA?an zDf&we;#^MWccZo7+3!aYBZhS0c~gVvkK-A4T3P&gRsqLP4%c4*&H4;4=-;=p0f|&CtdhIZ7E)`85NzfW?X5C!l&c?GGyj86tf>m4N6!ahe%AFvr z4k1@NbwfIKlU-vD#x$+3v3{1i4tv|QW6qj`9CqxqC)+Cg0lIC&?Thn+ww+b z8!Z#&Og%^e^&9v5tYEV4fkdnY{EeWI*h+o6@(fD zWy%I?)FBJQ(ZjPE4dMFpDyum`J$(E1XQ{#a}Yy zEcv)KqJJ__H`X&Ig_nb(0=Cy_zYZ-*dGX(eAOoN5N%3^u$#EhH4_4GFm*^^*;^OKQ z>bcmhWHa$lk+j)j`wyZ$$r7#n=3D0BtoC?#FnXNyw6v^B6VNb0ZU#TR|6*yf)vK7q z)X!-&%BD0Qyw{p|a@6>Ow^te))ERO7pgw5YEmc{K0!D@+CpBX1+1q!m`6xRcw96nq zE~E%B!WQ+y1nbg9DoFAPn*s8wr`*2g8((||%qbD6-HdtNy;mV?{O;~c@2eM=wR$}` zGjNWQnkII5TD&c)V*-GaW9;0A;633Iijc42hM8EHDqQ`Z54;;Z(hp@fr0S1>PB9-Q z_7&`jY+`_FInhnfWBfbK5~Igs65;aTprD`!YtYQ^pJnnLSX%S(ONIiW&>F+~<2qXA zc_hB*55(2KH1cEd>ds8Lv(l;qu=gmL>jt=Lhl?FmH!R+4b(;z7D!&nsv(>E?UFv{? zP%ci3xzeQ3zmywAxo%=!=XO5lHD@PXmzA)3y7x;qJ7ltr%6>j?Bk+qFjbRsCSK8%5 z{aHY8GH6tD?3NRqW|Ebk32016l~8C6qe#wjy3+(%6CCOP7!kR!k5;DOX^eJ>rTF0G_6IRd^wN3x@}C>t zUuY&1j7}VJW+JoG%j9OH>{B1zR27_(TekY@sZSpGi?5`BH{^~9X}Mywlhb6pvst9T zWoF}KDQ&v!^E$z4OkL-V89G-y--~#dU(ZMa8^=K=gH(fO5zkW>VV@oxgVJ?=5h#24ey4BWTc0Y7hsOapdlrW|`_PJ3v zi@$p&bEDG^<*Fp`w&oLX*K#3Ja0>*NuI!QV5a1; znhEq+5Xd98m|Ip^=(=8=xw$e*I$+mmSW$U})3H(CBxAqG)8?Y|NfC^pu~xJu`+YU; z6N_#)lgmbZvJXcZ%Y?=6S&Yv$qon6I4ZfCtshn7%&d+ZhN19KS*q)XKR1IFbE;D5C z=iOYd4-9^r-C#NIXg;P-o`iNPtlV8cR_^ZzX&0gm33IvJ)Dd?Q9{=)N*urPgZFBdK z_qj;^UPS2UjdteE#CZd1%(!`mx|u6JKVo5<7X1#s?V`NhGvH>2sQ(?@OPfh3A*Ike z+7Mvx?O9q%_Y>y12kx>?jTb;_Mi#LUm|(zD$gktON?xh!np1b3PVDlyR;nr))jBrE zY#Pls=)^dGaTtJW$?&vefdXEw;?nU%I80J=RHdhvo7d=b8JnKJq~vYw#=&hd{ICo? z7?dr)$Y|QUX3C!Y;pRO4%rrGxB^Cv7m>A>=i$PT&U~AuKRk;*0faq@;ax!lm>dP-i z+el2%6^w<(=()s3%lA&yD=?G7Ey)IHXkj3q^_exYEgDzhW_sgc5m7uC98G zrXpXxRt7C?K-7w=3+cjFmav*ALxt8rrNxXK6Qp}Cm(Jy$7KP(JdJsDj(#* zVJ*_O26eRR#!BwwP4>Ol;In7fIBxM^pjI=%B9b;o183Wn`L4pbxpI}O6X|GT=hC_j z3;UIqyR^WBz533X|7Gfzi#jRogyRxM*h6NYli09B5?kzxw~go5fFdhAwkJVimRyG7 zDW`9qd&BJ{*l~HH_?^nqe_`eTm<Kg8@&Fv(sd&7ZC%+m&4q`O@#=#dDczSd)n#8- z``@?zY4u}8bf21-HXTp4;mxX|7Me{Iu6#2U`v$9l{mCAk)zx|tHk|i1`NGG_B5H~u zmd0H0z+4HmYbNv<7i>uovBCl>At4Ls-dzJsQ*`#shYnYDnlgnVAF!Co9Y&xGCg@4| zI}}ji-7a-$ZFCB1BgO0FEvxhFO0Ng6yV&*}uz2sINmFBy9!Io) zOIy5YN$k@~{W;KO!t4caCGl>ycnd$Jf*hfs+-QPw(YTUm% zJp98A3rd*#)c~H+E*tGwB5ZwBVv?kU2N$|Wxa8eP8IqqsH@~glu=1to(_KazgW$4Y z$RF!HBz<~HdY~%~#+=lUDOtpoqk3xv!0j_{xg1uCHp9#F@Nb+P)vf9|lRn9}&+HNh zD726tD_r^Lq%W>K-*6ZxG)q!CMZhc)rozhy+-Q`O0xyJ^9-Z222jTg@7<9*@gP-u-I6j?l25%C+(`-5YRY#?Q%f3TK^-r1=7g|aH#07%Mw`hCs2MVN9uyy(@`$SSWn za9>>3EJN&MmtPzpIIVTO06nNEW|9)yDZw8$~eKtR&207SF71 zN_84u2CkERG4I^z8GStvqH7k>pD`~c|4y3yEUJ6wk1PDRPjm)Og2RW)f8>_2;|lij9!(k4)0b;V+hp zvM)Y~NQ=AjPgei5qgIv>u#uvZ5En14mKCUyeY@0hmbjpLI(w+GaCZzREGIk)ZiD^S z4Hj*)fAuT*F>B#0HG6beGUrQL@H~1-zTzXB?(3zU&Nx$~(smdG!}vD;g+#zu^QAh@ zwJ@z|Po3)xbj@{{)E2u)hyO8dQEKA57I9mbifq2u zH>qADIn93LRr3b$yl#$Dhd%pLa4$nYOsn^L>}90PdA^pHn{@6gOaukn+|^~baQd$< zE7+%e$3rl#hg1#>vThN3S<3vG5dCCM2sA%1Wf0HqqspMnbOopZBN^P?Zf%}M0!j|$ z+}1_)UgMZ&*dTtQeyvU)U&z3MstK^&e6ftHTbNB~H`wEga)0%*veVna996@zU652G zsO0F(e;f*WbujL70g8wK*Z0-rwz|f{io1?(4hinTMf6VLN9gI7vFv6o!xK0wL(^Bz zRI}TgLk7EGToDiFdmNLgw*$R--$5jQ&(fj#R@!$Lfw^x%4Zx^{1V$$$3%ZC^>!!M3;|cR9qlb}&2*J6yQb_I7G$55BW5 zdz5x;^v<7bf3$pN>y6JHabsIcOI`Ba0hC&H!5e}AnVwMw{72tZsY_ad8h@duEA!`0 z=H)IR5P0~>k#FX3MKA>BW`$noMfXVznEa#vY_D-OTjEirDxHsO&fac_8VsY91ERX_ zIt$i@2gio6)RrI?a@Oj93_+q-BhL&n>ZKUt-j$j`9Z?jn(D#|w~1`Ml0Q=kf0>nRcb_QfOZCx6q?w8U`ycCK zq>1T19&A!HgXLQx?(XxgPj_ z-Tj=xwLo#Mi_!PNhw$Z5uI#GsO-Ova(gGBHtnrT=WAL&+-6N$7-+vUP&b93n(^s@P zt2;UbcXfw>Nqkc*O~)O5zN?q)tZpDrS5{Zot@d$an4nmB7`y+$(p2v~q|V9u5!q=F zOf2BFUbEx;1UeTbD8s=NHSKmIqXlwK{Rv11*HaM?$t^F`{|DL%$}3~7xBGeILEhQH z=-P$`P_qfPmVd{vLDPb`-z&wQj1t@Q^3SSfjP~MUBUQb(%MVW)Z+`MN+3l_G1b4rP z$bv(yw6wJP3C1Cem4~5s;9|_|(qTG#{)fsXwsp#<(Q3h^0#3h}jU9*;G;+8nAL;l=yt39w7ut;uh-Buv?9#cP`kfcNX8F#$bBtzQxe!+x$qYKX z^z2Nf4eSr%%%-nCPc#z=$x*L9+0a*{g0)pPlahuh@_)R8=4$^ya|{|@%$2VBv+@1P zsd{aYULGjtr*&1?J!#jZ14Aj=%@|Qj{R8pIONYlzu|{JW?-OE1Wrlu*s=yUgu#2^I za%?QgZ`jom2wr!6h^*CPX(Q_L?{!kiNJi+2se|@BgM3PRyO%5W-O&5vq&|o)-#Yc- zZa?|cZcTO;JY0L^;&)j$cpx0V2A=UbN37K4JAEaLab^74#8}h8=X!HQ{p{a2SfXLg zCTvVz^qG&R^t_PdlPwqj&dp(SmB1TCc}}zcpkJq4<_t>^HmLZ?A_3HrpKo9}3vYDc zq<1#i_|kx())I;Nwb6Qd;FfdjqVCVPfz`I1G8fm(M#11r%fxLw+Z?MqS~=3w674xT z{04g((Gn7*X^)H0vb$RTeFl>Oj+gTk&3kTq$h_=NM!YM)qMa)lbr7@H^}U5t#B z$PSOD3O7dfr2HoEqx8uCQ`y>ktnG3z4R>RJ(5-$Jto_nNI|v4=2l9ZW&>31RKr;}F zgTKE-oDL?kSDGMeX@|uJ3tDVvg8HBXMiXRkg>&!oZ)KFjpQQHbqP@S0dYZKFaOhXK ziGGxY=TQ&6s#6Iy+%?$no&1N9^L7<;dK!%02i-5#*N~PCN{?$#nIoq;8CUw zUdQycp^fYnQ#Sxa%(Y^nwjk`l+caj6!Y%TPEc^#K_=~mV`A9L%fnb8J_uFT-q5Q`e z8(s<+FwZs@^BF20YP_~JSwq;Fx|6FwCys4NNSV#Xw|n2?@qJ8Gzgg^~**_Z{&12PkTR>YV$S{#;NneFB|7zoh>fyDTMU( zKn?dVhwrRlJ}d37sp4Ag5z*!YpzW4yXh`NKZPCNjXJtNW^Z=Q*$elsYzaOOE!e}ZIO;63U=H8v^b?;ZF$Z4q1kGI9N zaN)I>5iR$LDMszC_u}ZN*9?Dgc{s9B)dTYU?fM?FklSTr_8&&d7AQzFPo#I+vWzet z)4DoB`?bdAWo9o`Yx$T6HTW=tp*m>cYtdE?$+w0b$@>V#B^m3C{C1P2*nitxK7XY$ z=sMs1grO5|^Rm77t>O-)JR(bhVvD`%Egs_DQj#g|dY*T+Wc6qgqXOaizVAPhj%5A~7#SxYk8Z}8zj~>eIUH-R zythZhOO925d7pw?A|m=cT;wgQdIaMo=$u61hT^^k2oA?M`iVjIIy-Z|*cY8Pow8kN z(xe}RWSHPfe@NpleZW+I?-?Br2ea>gTXXsw7QR_DYO2uY57E}Q@W>8QAv(Up%nz3e z3PvWe8m)txuWaS2@Mna@f94UUcfMiy30A88Yl0ak6PALq?Va>l{Wk8prwjMHtGK8Z zsI~Mp=FEXL7d?)$DXQiDSq&lYdX|y)saj)&RPGOGc|}LI*n^)yyxk_vux6e^B6rye zUz|C_9G$WpU - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg deleted file mode 100644 index 4f4179f7a888..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg deleted file mode 100644 index 595f4092e713..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg deleted file mode 100644 index 3f1ac0baf712..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg deleted file mode 100644 index b749e73b61a1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg deleted file mode 100644 index aa7a3cc20844..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg deleted file mode 100644 index 3bdc8437306b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg deleted file mode 100644 index 7feac82df076..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg deleted file mode 100644 index ab30f2c6854f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg deleted file mode 100644 index 9743f903c955..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg deleted file mode 100644 index 26b2b27cc47e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg deleted file mode 100644 index fbc0e1800214..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg deleted file mode 100644 index 3c7720d7c1fb..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg deleted file mode 100644 index 0b97dd242cb6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg deleted file mode 100644 index acc7e592179a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg deleted file mode 100644 index 9d536db9607f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg deleted file mode 100644 index aa650f927a0c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg deleted file mode 100644 index 8120be1fde02..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg deleted file mode 100644 index 9393f7e9c04f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg deleted file mode 100644 index bac34c4036c7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg deleted file mode 100644 index da13b75c79c6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg deleted file mode 100644 index 5d644c8cc65a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg deleted file mode 100644 index 9eb63ce5bb61..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg deleted file mode 100644 index a97be77f652e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg deleted file mode 100644 index 1553bd9eceba..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg deleted file mode 100644 index bb9ce40066db..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg deleted file mode 100644 index 284e3274ecb9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg deleted file mode 100644 index 72e560547da0..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg deleted file mode 100644 index b901366815ec..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg deleted file mode 100644 index 4fd2d0704d74..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg deleted file mode 100644 index 8ae55c2b93e8..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg deleted file mode 100644 index 8efa014dec0c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg deleted file mode 100644 index 5bb6f1dbe0b6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg deleted file mode 100644 index 7ab5fb3393a8..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg deleted file mode 100644 index c8277654d710..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg deleted file mode 100644 index 8850b78a635a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg deleted file mode 100644 index 8233dd2c9344..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg deleted file mode 100644 index 0eb789d68a08..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg deleted file mode 100644 index 6724f6ae8f4a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg deleted file mode 100644 index 12a8ece441cc..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg deleted file mode 100644 index 9a39aad5e9fc..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg deleted file mode 100644 index 1c99013109e3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg deleted file mode 100644 index 3fa19cfa016f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg deleted file mode 100644 index a25af02d7840..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg deleted file mode 100644 index beb4a7c968e2..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg deleted file mode 100644 index 51fd6569d4f5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg deleted file mode 100644 index 503c722ce911..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg deleted file mode 100644 index 41de0c0e7517..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg deleted file mode 100644 index 2f60d2dce0c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg deleted file mode 100644 index 90eaf7b9afde..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg deleted file mode 100644 index db24c455872c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg deleted file mode 100644 index ad198885039b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg deleted file mode 100644 index 48e96aec6201..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg deleted file mode 100644 index 7699a554bae4..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg deleted file mode 100644 index 54966438d6da..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg deleted file mode 100644 index 217710ed392a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg deleted file mode 100644 index 557f383ef140..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg deleted file mode 100644 index 9a607d3be398..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg deleted file mode 100644 index 27a4e261430d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg deleted file mode 100644 index 6ab437376ac9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg deleted file mode 100644 index a07fd9d3343c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg deleted file mode 100644 index ebd1150930fc..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg deleted file mode 100644 index a82731fd0f6f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg deleted file mode 100644 index efbc7e7d2bc1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg deleted file mode 100644 index fd18ad222138..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg deleted file mode 100644 index 71d9a7283602..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg deleted file mode 100644 index 691de321114d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg deleted file mode 100644 index 2eede0c86d82..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg deleted file mode 100644 index 1a9f05da238e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg deleted file mode 100644 index 3c67bb2432c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg deleted file mode 100644 index 5a018ca116c5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg deleted file mode 100644 index 9df9996b2519..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg deleted file mode 100644 index e5b1f3601112..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg deleted file mode 100644 index 73061f624a4d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg deleted file mode 100644 index 6c55271db543..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg deleted file mode 100644 index 078b7f3ca596..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg deleted file mode 100644 index 7c2201d756a9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg deleted file mode 100644 index 78b3fc219c7f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg deleted file mode 100644 index ec5fb508fb54..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg deleted file mode 100644 index ebaef38672e7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg deleted file mode 100644 index a2ecd8951fc5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg deleted file mode 100644 index 2886bd063bf0..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg deleted file mode 100644 index a159993eb801..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg deleted file mode 100644 index 44ef561b9d82..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg deleted file mode 100644 index 9fbe6cc2d396..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg deleted file mode 100644 index ef918b151f48..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg deleted file mode 100644 index 74f82edf6f51..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg deleted file mode 100644 index e0bf2621cec7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg deleted file mode 100644 index 22335b2d6445..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg deleted file mode 100644 index b228eb881dc4..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg deleted file mode 100644 index 95588eee0ad9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg deleted file mode 100644 index 84f0a83a41d6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg deleted file mode 100644 index 0f5f6bd37818..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg deleted file mode 100644 index 88ec01584b52..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg deleted file mode 100644 index 9c83f7776d96..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg deleted file mode 100644 index cb9c6419ab41..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg deleted file mode 100644 index 82f881f1ef58..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg deleted file mode 100644 index 90952097ed49..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg deleted file mode 100644 index 42306cc6f258..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg deleted file mode 100644 index ca839565481c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg deleted file mode 100644 index 4a172fc9cfd8..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg deleted file mode 100644 index b249a46bdc68..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg deleted file mode 100644 index cc9a12fba995..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg deleted file mode 100644 index 710faa0ac489..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg deleted file mode 100644 index 1ae3cb6236ac..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg deleted file mode 100644 index 1861c6fda86f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg deleted file mode 100644 index 24dfbe3c552c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg deleted file mode 100644 index 1e7b7bc1d08f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg deleted file mode 100644 index cd1c24272388..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg deleted file mode 100644 index 7ea9317db840..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg deleted file mode 100644 index 3e9f9a865c4d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg deleted file mode 100644 index bce4703b7311..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg deleted file mode 100644 index 8c511ae16ada..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg deleted file mode 100644 index fb4b829cb20b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg deleted file mode 100644 index 1ac1ff7989f5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg deleted file mode 100644 index 6de712e80d55..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg deleted file mode 100644 index c364b6bc78ac..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg deleted file mode 100644 index 1d28fca2dcb1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg deleted file mode 100644 index 95e5854c3e08..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg deleted file mode 100644 index d2388f83ab79..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg deleted file mode 100644 index 8be72004993c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg deleted file mode 100644 index 622c53da79f6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg deleted file mode 100644 index f30bfa642c27..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg deleted file mode 100644 index 94cdab1a79a0..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg deleted file mode 100644 index 559e5b863820..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg deleted file mode 100644 index 5bbdbd28280e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png deleted file mode 100644 index 73706c82f1efa0aa4a5d9ef5013f84db1fd05cd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1268 zcmV#`d(gKZuGAh^z?EfGMZWWDpfU|ux;D6 zDv>>V_H6ceJYS`zrhc80l9IZ9{rZEdV%#c$^ZWhh0A?j8CtGp^&;sy=Is>?U`}POY z($WO%KM_d0S+C9j;;rUhuU7%ZlX7fR?SOdVbSHxVHy$Vj6z^HPckiC!MAzr@o#6^_ z@7}%Z0sNi(ni$In;eAtcPXW>Y%z@{J^6nq#?{N&cW5qvMt~GhL(Igio&3V-;N3%cZ_cG=pnVMAZ(kM=ZKwQAMVt^rrCUY!{V zg)|&8`?p+xnc*&C9DAQEbOlKMtrG7^h!v19HL5J&%9SghBtB6Ju=6>H@xK!|g(OOHd>e1h#72a# zXe6@Ev{)3XLV!qh(%h5yC6EWYmd29pRRzdci(}c-@Fy7L(PUc{0xpVWPjX*sK-`_I zfLi(zYUoYZ7gQA>V<&}M_Uw5nH9$>dChXd^E0L2M3H5U*c4iAViv<0cm&_vhZOxiB zhgJb#B6hyEk1s{Sy{{;ed0cnlyk35O{!QJxcRx7nAS`2tvtn!w1Nls40oSfw`;fiO z$Z_4eb*bDxF78GRP_ft%TuWL?Dj=)JC zo9*N}*MQ_pCxD_g(hNf05FWzrp{I|6*+g%{2!E-n@Y1=M`|iF?C2-izFUwB%WC6yqA+a`f8#uX7JFnEPKz z57hC+mb4#MlyjYU@Ng8848z$Z^H~u-z3njnz>8s7EhrFggnoFEd`>YwePrOxBOK=- zv)qgF-zY9{&_>?Jh}qD;j-|(Y(|G?MYz1Ub5O) \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg deleted file mode 100644 index 4d5c03f44e62..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg deleted file mode 100644 index 85492e752622..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg deleted file mode 100644 index 06ef74dbea90..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg deleted file mode 100644 index a719dfda7cac..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg deleted file mode 100644 index 729c1332ae7e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg deleted file mode 100644 index 0223061416e7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png deleted file mode 100644 index d869911213051d7fe9fc78c4b7aed508c96bf0a4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18151 zcmV);K!(4GP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3>vk{mgbrT^m;bp-6oaR3D%GB@bs_xE5y=2ksZ zEi%buGBU#HZU(5nMO9(${MY}v?qC1z@4No+AjJ zi{$(9`+oSj5I4^EMIF8U`BK-<8`-Zb?tlEwzc1_iL;vso@{PtS?ZOA87*7hxzyId% z3X*<@H2E{}-;f%w^J(yPNzuJ;#h*80LH=@kzy9?8&kOXIMgH}b`}^wu{_1awALq~a z)8E#z{;UyS{M#Rd^0)7&-yakI{K4t>6~({)AcVO8aXUZ1@7?|0^WELdl@+Z&5%m^3 z{CXQ+xLES^{#xZ%<9Fff_I?e1bw9na<=dNI{IW1YWLK^WIqWdQ4d?x7!MMa6Ph?MG zjK)Ukd!0QR(by$+QNO~CjUC&mvzHc+V=Hrtzpo{{&mHgcEOb732VNQjZ^rKa&%fON z?T7!HU+!LeOYHmawc@&>B8$t=&gs9riVX?(XWz)qY*x;N_-VNlL$jokODVOq(p?#4 z)>LyXwboVzaaCm^u&+FS2^^f}^4U|<<_w9&^Hb4EA$pvikpUO)NH ziYu+W%BriazQ&qH_*k}L)tYr1Hh0`<0~5RMw)-A?p5P8haq=mro_6{fXI^6MrkiiM z^|ssZxbyd}{p{*Le*G_YE&S|Sd^@GrwcoqOcU^10-XaK2iuQ~hi#f34O*=q9N9~#K zA?K)_)1LVeNs1D=$fCV*J7~w)!hAw3H~ikaKX&dv+BaAFf3$D$|Fv^YTlfEC=Nw!2 z&wcwhySBx1_IB*cLanJ!WFJ32eY)7ENNxW6KS%cQ5z>eah%EKgQCQ5)$7FtzV`T?G z>+9^WiO1jRV;b|^mFH!*SeNQ!8R_g4>-A^EJbeW&FL&5dDOO5iE$XpzEmc=mIqR?* z@f^FUZC1x`7AUPju!L$x+~!s5Pk=4%bho@`YsPCTD_QH#E}p)Z89_S-h>zlpXG0kvnyJ%3SR(AGtS-KuCS6EwIHSm@@M)qad zTBGN(ZLB_SB8g@TXFw4v$IYb`l6H?`v)En*bZ;s1CKGa4{qDM83WArN)F$6}{2t@p zaR$M+*J4u%xyg@QIz;BZAWE3M1S4*DBVb!HaG!T+E#JkB@e!p>R{DCbF|mJnov{+X z`8&rgc4Tp9XEiXqZ9*ObDWxs0qwZeHE_WN@y~CK7_0~nqwpw0eaPNT};iv8dF0rN* z_A$$MlB+oxiFjb7R4pz7^qgdUp2b?Q6ldGo#;-nYq}*FHD{ip-tn^F`E*@~?nYLI{ zvLn=y2%&u*H@?LMzPWZ1oBNn|G*Tk>sZDa{67{8zwoa(KkW1+h8w6Rq#Feq0(ELfg z6MaWez}nR{Sv$V002Q~o8O-; zCaJ(%kThehbk`;hw|08hnFw@3^3K%xgEt&!R~xm1ZDs96a(c4&`hFbvqYnYV$Br4j z-MO!Vq~LOWAU|7)FF(gD>?_O=!T|FoR{)=FX^hNHyMh2UL@r+!{~!HXwnyW$Y=Qe6 zEryf*4Q`Kk_x%!`K#2of&!^4`N+XU8B;>Y6iDQ>BJDjjrVwt(+dT!~<1f(T9Tj5NC z@9aVxo!o=*s++m-dwV<^t;OZD@!p_-7Gm2+P#I%obLs|pZ}i<6*wX5)0qoD2yjiKo zeVa^zO)d(UB7h=UZiK>F#Seb4N{@MjwYUJH^cH6z1(8ewud#EpMXEMZbjK5jec-4S zyDTe-9?D|P0sI7TYyt~B@-WK=qFlZ=@MB;+u|<_+1DtDE#Q?!Bx*>K2`Zo4mp(yMM z^su1`au%HRWr5m`dmt7Ao2QTj7Wp8nh*1u|iubiygzULbq{F%~pzq3@S# zqvydvdiSa%G9zBI;qhCO`-< zCmF+%Bi*KvxvUIZ1KQ^XRlvug)&w#^M*v|3IPL+4_h#w?@DT(c^*yXBDbzFlybkIW+cNpyRauW1I)0U<3zTH z0Io1{KHwusd(Po=rS?c1!XJ)@s|AgLl#(cdR0moHugL!rNQj=(ebk);#A2vj!-V@+ zf-*pfdWXc#OY;K-?29-d``E~jT1QHYOdtOG6+G`8PET0B*Z>!Ipxc1xgcMd|VW9P# zfEi+Fv0`>f*21Opq6Kv1StGPkGg(cNfg7wCJdqtRNzy{c1HI%|FQ#w>XFM^|8u@}S z_XjnHJW8>!0865n1R)yNlFi94uCuRYyR^8o%4ZwsBmr)Q` zddM-`!2*!uvyhD?qVXr61M88c@uEB|B@i43f@H-O;@4nkP;`o1*x`9u+X=(4xq#7{ z(9{hRF#;2KKc{bKoYtl!At;!XJ@AUlUdE&I9!M)mkt=0II9t5pj3hQ!mIl(f!RW;9 zf>&U=hI7~h2Em)+Afs`YD4?|4T!bQl40C!Qn+wO*Om55*b2&Ki* z9{1tawxtQlp|rwTBp{c>io-GB_)26TvINs*BK87Q93nSBe~r&VCpC7McrhnweTjL{ zssh8xCKOj{B#lV~6NzDTpd@3Pz(=I!47)8bv`Y7jx$xn`iK`;1$Nn!Y8P~&h0a{A$?K-$Ul`9CUj6z2PNPl1&d3Aoq2PRvBUT5!G*Kbk3W#VvIM9z{0Sk5!sagO6|4%I0oYcGvR_pqax-jflaXue z*@QLb0u2MvvZP<|hJ1zMmBD;c?glx}kmo`edr$&g2YY@SJoi_pM=T?*Bp=QQa^8m0 zLc5|c0CErn%+h6(<-k7LYIEe%z%Xw}k*?8dGUmA5v*NK&-IZoqDb{|kyubyR#%0Wt_RVv9J;d}jyDl6IAy zx#m>N1ghlz%{TG0fP;I%Q8U=2oMolYtE+CmSNWDQpYvKM1mjo zk5IQy`Jx?~FR&DtL7V zY|t?R_>smXL0~(DHCRL10Ul_1xleLtyC7ZM189%_PVhzD_#rNOR3ZbsJD@J0g!W|* z^--i07{@MPrb!=IvJ)?O+KTQ3oInuL6+Er*5FwlJCX%2lWrW$l%p*Uvy@B9Ww0V?O z?%0tB;I4`qqG}y-t52B&;@G-~g!PIpShas&h!#-~ac?#R@l2?~P2 zjyTLDx(~0&_+^5Z&9UBxlo_{y7zj`Y^7No1$j*g2z<@g>FpCkPlt^v_q;0haiK`o_ z9JSB2NzccMbY=lpMsa~nsP_iVX3tWIX^G*ph$_@Zm%c;=Pq|bqU)tOX{JJmsF+?38 zJh;P^pq-)@g<%LmL+mtdB{uX}?&+3BvJjll)>g6QU5~FfoZ!TDCY;Z*Jw;@PW|=t`O*% z=r2M>0J(8xF%!S+nJhrQto8<2kS5##jv2idr!(XX?g$N>U<(l+a*P1H@)m$PvJH_3 z$%0Xdoz`bG3`QPaDw+=|uQ22S)QxURz;aVjL;|lhL))G$>hhKm0Ww_ZK;&{!+2~mf zxmnN(m!TYT-2a?|D>)=oCzRkM6_0&42raO`2)`M?dEzTf1U486bdEyu^zh0|(--eb z$sWeeo}hxrWq=B@T=gO72K9ds+guGu<|TzdM8kUF7eU#R5FiD5ILmER^qSDxk%l5r zkl)5$k=9%Tq5%ZuA1KH7R0t<1W%UeEs5C=TL92V6p@Jqi&4*6j4)4$R71dJw;}0lf zgMp$#+-Q+h_QHkVaW5v(q}_*u@Dmc5g(qxk3bHT@;HfOu+i`#aBapA$1CUSHv$g_Y zcDjG;1J#)Od+D+GjKj?;#c$Oi9tj5(sQ_LU_zO(Kaz9}%V{rpOXGBEtUqY?JH^z}F=gx$KslsvBT=XxLmdIqH|(XHj8xJd;+2 zYeN&k2BB|R!$7RgIqWE8aCZXAfjRr ze{6)i5$D*kD?un4bwk32#YP|{dBYSTGIRyBUC0%}gLpFZD(qJ>F#{`LbR9_A*m8tI z0}sa_;gOe;+wenrwI<9IFY@Sfm28_T$bdAvgD&b^^$qB8H}+HXco9GcMY~jFjw*Xh zT@wTbJhO6*RF`IDJ8-r*qZ(g}I3d0x?!zrUZi>v+G^>%#O=^V_Hi(7*!Wn`Cqa=y; zX%HkO1lsGZPm))p75dbj322ivK8Yh#wIO5xfh-V`LhtH4?5naHaS(7~AQWOWsvB)& z7RD3Ibn#KyK+Ts~xp@}Z_ebkm>k_o9TX|%1;NsdY?1b-xrC`yETE@3-S|G2xj(bw8mb`T4L$! zqH54HhAseR%&Y7X4(JOoozHy{+j1&gQE!rIQqy1y!XP7(&2&R2BiWFYSX%W8xM4CH zO-Ax9EH~gCxaNzR?yQ4*#!1ztAs5;Ju2<+&M*}dqyKKS-HvTGO+^$#2h9u~+U-zio z4mlIqfPLUIAM%yj^V%Z!U@rFh#?HE<^^x&GZujSIbQvLAMu0fkK$?<`6sT(fkco zarayi(Rb9PNh?(wXCy=E_ zNE5o`whDCM#}Yl3oq7fY@!c|M5}`)e^7;G-PVW1a581(v4iQ`T&|r@E-4;~U;iK|O z9-c%ia!3InMXE~Z+Ej3H;Uq7nmK4EV?NLMGClDL)xG=~{q^TYhe2w(3XgL(AYGvEN zFmsAPuvhJ)ictYTwtGrYPHzNkzOen2<}?efjY_RtHyve;Eu79CLn-A zF$(6;pK5&Unt-deU`Y7T(w7f5`K;fGaP9)yE1#!Q8sxsEC?;&~wQGt9_+9fnk!V3U z-fIX07TG|00$&wl?hCz${wEeeryJNSyCI~C7Q>?@hhGdtH202}I6;3IVSa!kR2mtM z*~H~Tlm?{lqB6mWs``Q~keDEj-D%C)Kn-@Vh9Au&i``V31p>}3q)P@ZkgyQQK|WU% z3%oWOMJg|~$S%0tqiUtGd7Ux`l|~E|xDt_V*s_jjAV`vjES@y$>z8x$@;sGrtX#X5 z<}_gS{PTC!}6;#iJMt_`F2)OHB&iw?e)En2^6>bwQ*-j>sLA zA3nhy{H{+jD0%{cdT*nJLvika3Rk-8kxUI?hAudq^2xso=a-m0Vg~WPD%jE(7 z$3BrZkORl79ZpovCFcgbsIojkbI?BvI4430p@PzB>cnEZp4S74)nHLsVM(%G-EApX zt5KeMd6wf5I3l@sHaB2ND;7KEF{7%3U67f)yKP>S2~oQNQiWjO$5(($q+0^&`=HlN zN|;<6KneR?)yu)MacfhJSZ_|V4tb{~kFIim@hZ+k2Lz*aFA`1%|5Vi_$F3%bD^Jln zixgDTK*sYj=;*cC?{~up5k7K3W9ql~fiWvb-Bq>6SF1AW6|Lz5Ab}n2f1{0mJ-?yDSXLxf&OC8Oi>dsWkH>~ zg{M>+-spdX0F3v8d(Nwpq++HjFI)wQyfJiqCzB$?BpMBw2i;CM6OzJuwX0-8?T~Jl z2-h3}l>PJ=?iXFt&T9iEWSlfF!Ur}DZGc%w|1H!c1G^lvn(hmSoW3Cc8Z7KRGO|hy zs>Q?^Q6I;O$`FGbpe5J~%v_a-Xb4g{zYb;K!RsUg|0a zRohb>SO`{{Ynuy}sN}s|>0w!4WsJoDzF09N3mR>L8_jx&Zw3|1e>C)h6uu}nkDS4K z!>6jR_|;|Eun?F;y!lKdTTX<3A|=a_0_s;wCu*4GA4p`?sa zjpNgm*tjh%0h3kvL!7t@PecgDbwch33rmPNjPKBngdm$+S(k=}i5ESBa9BprK~P8{ ziD$!g8JLX5fh`7W{8k%&03rY0A}Yi;+otCHR4!M&hjm;v2o@swqgGMXWM;1D4b#wZ zC{AT~j46L}gU}l*+6Y}~Beg-uOz7?{HPDM36Qhs|#yY7zR@Hzet8;Z2&(hmgS@3XI znmw(J_0sT9ja|;6LxsG9*9SC`l2?)PgecnMa5=i$?kq0y?+*2z*msS2-A6G9Pn6Wl zJyJAEy+T(|#eh7?>o=|BA!*fgY&m3E-%ApHN78(%(QM?YrbI8>_EnlzY2sjZRQ;{2 zBBHT7agdDaPX}a;8e4&FoGQ3OyP3Pji8ZaKI-hX&LY2eIyA!V}-gSFFQK6=T{Ge$$ zu7DrxWiQYEW31ZuWmdTsClFO#7KW2+Q4RjQHO>U49CXT6$)L337eY(9iXq!Zcxjt2 z)Ra`;n~}5^GK2kF-3JsZ&IbhLQn(6{t_E`7^q9N&zg^`cSn(-+eY;94WISm^cq7hP zpr-!g$l%bcFintWzbd#~4&jj8CPEh86FkP|NLwM6$Uo>!C?ZYL(LbiP$5sQszUDa# z+G@&zI<)DlLrU&!(oSVCpeG~P>kqbTVpz%pYl76*P}GAdWD!;`tEzj?im#K?+<;{Y zo{M|nVgez@o7n5)OswD31O<*^XbIAz36!~4hKDCAnx+Rdq@(t7E>~U7f^vhm?72At zIs2trm%1h_x|%e^r$84$1d5=wNVhG3M{_%*=}_vhlgf7VfFyp=;4)y!eqe=FipRVY zk^5OkEU!wpWLAXb5#CZG2h3rSQ{UVl8KokzCTkW!pwTSM=aH`9=U4NdZ`@7;C9D8Z zYgGf_1g$Hm8tK)PkS)C3+9+xijRrt+OKLfT3M@_`g@)FKO~>tfBhdZbcm#H^L}ysU ztwB2Sphw7Lt3t8Wg%DD&u(~1#-XYFHzY9?q+x*($iIhS-qn(-qjc{_N;wrI(ept_S zcidDVaIkLH($z3YY3Og%gNCsligj{eG^mCf+JX`F)jW*CqQiLOOrS5kIxT@KQOV`i zmVuI^0t36kn)>)!>9DB$`(gXprkgY=3$pi)X790_laG37FPA*B{FCpS4c(Y&ME`-n zzd7)v`slij{n1oPEKx;o<+I{O@3EzGyhaqG@V2QAi-((h4p(FiWYR!p9oWjs6#>uUT;+HIs?^ z&>Yl!E2i$0n4-q_Iv>ao4J0h$rMW%?P<*dp@lYIEf`o(A(1GDh1K@k#t3BW!(GC}8 zE5a^l%Me;@Qj*O=rvnXhA^0~8jV4*F_O9xu0y!9H73_&lfMA_ShC&W^*q$5 zyeJn$S3qQkuXSP|>hE$k!CyDL zPw)nnM-iiJxEh*KLkU-La}ib-7AN8i>YqjZ`eYjSe+bZ|booG}Zdggqj=M%5Rn6dJ z9h|6y>QsJc#%HSO{0s2ZrV==4?5ozSo($KQ)MP@OgjYXO+lyo$UL!cK+V@72+hOlo zQ$--Dad}9+E0EdhDOGZ2Y17Xe_{u00M{@LV)%1oPWuR5h+R=kF*7nsr+tmp1^-;ra zJ_pV0FEj<7Vqp4-I^4!|cz?|ej#$rH>k6M=&<79x%t5mGm0i=oU>E6|tozK2azdWMkK|%6iCqc#c=VS}H%X zzQEl<2x|S2d~6y<4EJL~Z}9?_2BrwP%jrA^i5A((_t$1M$?U8_7mc=&Zm$xC6i_#= zqeQA&r1NC^+^BiHfEOD!i}=Ma_q<{zLS^&?@ZR2DX+HVc`9y;Qck9&nt>~ z9Y;$_R1Cs0ji2s>aYxpmxnS!sfZ~k8R7F46<}`TJ`fG1t__r>P%vaM3;R(Q<2c(@m z02ak9Z=pQ;pF=NrO zv#Il^IQ%S>MfjLT@>pANTyuc~m8*d>%zA|@Gv;)B6nchO2EzlKyHO1h%W6Uh8aeJS z_HbaN8+u@A=zo>0jey1Tdkbzyr92s{s{<`1f=4qU;Ll}=*)PBpJ%ACj`AI2=?9Tj0 zF&uTw>LwrR)u|BlV9;@1($XyzWDYo@G0H-WWsu=bS>7Uvs5$|3jWXS;f+fPuG(xvE zDSI`xt`X5v+?Z+?V16{U3kInQ0KuHp|K8TqKtEzcd8k1j#Z1jPXX^5ROaa@^^~pkbImim$G;YC@fT}w4o!)hiHuW-fGDf{jnd4}hOH3LC ziGiIN(zDPG=-YJIfPhtg>hckitGp>$Ip**{15-oDSB=E5cbGo5N=GqYsYu;8~!X zNoU=y`l#30HSVjvxl}6AJTY|WUC61=q(c?2!^&PEQsWz=0MV9? znQLZ8*9#T5g*MS_yXHG~+p5uBouJe3W8q#Lk*;SUSnxVosA@iMpyo0KHZ8m$Y| z8te<_g*DYIv8qVlS*@RvYc|t~g4Jb}1Hps((b-FJ zNdP~?(d2w|QXt$Y8F0vMKx8MvXA$kft$+hlWz+Ys=`8i8sRJ|+mP|zpNTssw*)=v> z-G-pezMA*mIxVXlV@uRK%$+UQ!wv9vUPn(CI|k&-kLcCrvdhrMfi#V8h*po2}r zQCnT(Eg4E5@7&K5Cj-R5CaEpd^^}$%t=+5iQPL@hs`4A~_v{wtfDauy{YVU|JbstZ zaO-5FPz$F#de-puI~a``sMVt({ei1umAVn_>U`S+5d2MMEx30bR>8+r^^Z&t$dy!$ z;2{w~1J$v;PC?ItxoU=v(*R3*)eoIm#WAT>iiQR2mgMcwa4y#nG$|4HMcVI6@}f^& z$|P-gXLuy%o{01sv&5fN70J*(cWMNHM20yvlMFu;_DH1|WIiz7HN!r&@-SV6t+_Fq z@5m7HLDh7fLDE>+(9~ABI>Nx6ls>j*Z}vAE{VJj^sGqZkPJxqj8s){Tx@gGOdq12d<=g}OD0h5F*gHHyxr>wp5L0;B0>Ct{_-IDB%F4<5YST@TpYB zbtKoCPT2m4E1klv_S-tH@2KX+;3hDPKgsQPWK3tAd3UH{K$-<>=2XPcY21t{I6An% zuSF=0t&)`Hpc;|1)*G79(Z8cZs)x0VcsU~pHO2A#8nDc_kxB1Jlj*@awM#{rMqJQf zT?KG_rk=}z4E;G5r3w2jLD1g0C^z*il=KciAulwIsY-}*j?p|&J)B$uSo z>?e(6*k09=jAa>BHNPY+wj5?lYA!y2Ly!0bA%NAGWZ#ncurt1890gi>e^|8Y`_1n?pkD0OHHF zKw5SfI^za%mm_$Tlz<_P2u4I<(YgFFN|jqlIzfKriFbAyxXwCD8r2L&7a+WSN4)1G zvjZ}UF3&q&0zzp(E|X8iPSCX6%3TK}8>$x7F@;S!>$J1fdKSwk9p=*P$MjnRooF?Q zGrtrM>Koat)%aixEb?|c7P#uX1}a?~AIktvt4x>X*7E7^q(L)rrm9XlKSQc$pM9ws zj*vfS%N-2})BtTo<$#_jg6Oz9M4NOV(EP4%+SN zgd!B)>;b^ROR8US>oFsyAx+J~<#8@@R{E*D$1xxouFj3r?P1G}h%h}7Lp_SDr#|Sh z9$Jl=vx@K?D}?dXGk-v8kWCXW!cUSFoa$Mo7hQ85@5Ys?_@)PH?6Y)WoA@pXcz7Kd z(~P#vh)!o|Xzx9?1k}}YTVx5|)jQ3>L{?7IrB#Nla1pBT!$o-J2F)%)Kov;S!Q-Oi zOswS4;b@`cdoBwBse>Gv18%fAxSjI0?G^>smX6xRNck(9ju!$q)NNUub}}4 zNHe+Pb&LxfCygGF>3pvai6cI?=H8|%;X2ltblO|T)kx1;_iGSfHxUp8(ds%H8E@jx zn+y}t+beD3Af-d`3md%*{32%CTW^hg^7iT*C!H!S87tnL4r`d#yoK5%MtDW_1<#ed zL5u_?s%GR_!}ll`%ytA)z5`^Zlh8zdQLbqWc|*IbPRs{{x!gyKSvQnTGxO)j^5|Mm z(&MUFWIaCx6fixNu6q#2b!@$!(!mXNY?%(C2F>QJszcP+;rx^_Oo9f$6xDQ8j2bri zk&fl0uRQE#{O8lNU|4dWL?bo8=BQ(FQKEBrJxdJd4R>O~;TjK<%jyp-MB-!ku=%m; zPC9+5M&BVu#rRbvQS8pt2^lkz8|1=y$@&mqKE9_mIL#&WsIE86K&T*rv6)9lQc?D5 z)2pk9*3x6P8UjdD2t75O7(@1||EcH2m}{?3xI=q~)LRKUjf+Yfh|EGXjisXldQb&x zjB48|CgA%D2o`LjdAa|Yj)PkW-y$VH^jMK^5EUVb#3D{=-pgay)c;fSpLe?IoM{6z z9H~b2#KR5TQPF{0J*0?a(byi|L&v1vNwM&xfS%?>0F3weEhA{4x1?tbsbH@$BygMT z*Z8O=YIoEmZqQm3i58v3C{5D!ydJ;TNQ%xJRz1=T_hw2FfCA;wqho)sTr4=NLH`7} zVg=Cwa0*U>kUx4r(tFm)cgAYsHj3}MGd)HLK7?mBi`_L0Ds0L`iTc=TETI$LnL~sy z5IpWX-KJ;N47Dw~PBl)|@^pY>>hX2Jh&=GCed)5BnggIMgpTqACbypSGVCa7bg)5w zMN)05JvxJ;cI(KP>v{;@2#@7;@DZYdm=N>vouSs823}8U5wDK4Q9Bb0QMo%zRw$|_ zCm)AX)A)@g1XLDcU8f>~4r=|J5?6V?>DggPbNd?l3wlfsB57k?(Ai$c3iEVWxh`|h zEsobp9azSqY2ok+l_%@zHC`hzS5H;&RSHB$*2x&sa#XcpQgIdLBFb-OpY((ZBX|g( z1#N2FRYz%-jvncmU8bFsFuz73l>6;9;;b%Gy&{?wRW9=xk<+a)Z7G6KvrAa<$J=w)U^1} z1B-}SmQhFc@^aqiH*WFjkEl!KI3kISLu*f+*==g_K^fs?Bk`s-#?UkX4quNzM3|8M z?=e%*%TLwJt2Cy=3h#MY_^r2~liP}V9zj)gacPuYy<8Yv<0v@Pd>x87VjeWG35rO} zya{(rAZg~Vj(2Glp9+{zAU{7g?29;)vK9i3QC6+oR%L9ci{i|#x%q6bpJ-P{a(G0AGeNas*> zc9xu1f2m~^iEmTkPS0c8BL^LUf6pG$V^Wc3gu|W#mKBxv6{q7LHQwLDUVr(9PY6uY zXkOzHN>(nbtTRi}cGgpsx*pMo5f%ZP zPE?8D42h_r8ysSAI!%L>A4Ly+cpOrCKz0brK_V@ALp7QQqH(fb=+^a=mN9RCj~9^~ zOIg{EPDq;kLlq)tPSrrTLDe9I4za6yu4W+jCc`o{9K+sr0H^6OOPU0L`_;qHm<0jB zEoc;<9b2+nC|&erP*)Mc<8s$)2~0gt^KOk%qK46{a=K?YJrxDe383FX%>X}|x|*Wi z+@O!Eqc-DBQRrB%S|`W_7E(uB5AwJTkme$58p1*4O*tbSt>KPG((^yrH9I2Ru9@hG z`0c4j4Z`K!bfgw=0N1==+z_Mh@gV(8fCl9vZZXL%;#Q^}PN&9te5oKNJzFPBx_F;` z{~A~Uq2?Vw)5oCFbOctzBH=w$sOjvNo)TN$GXmgNe59}6LzGPIs>A*uq9Zvf%$ENG z3$wuwY!fE-1%w_G!HTHt8m_v60FU=q=fmC_L)JHVO#|X83Y-Jfwx{{f?<6c&E)(Dh z(No^@GzmRfXLdvFQ*}V=(rF{?tBE!Z2tW#Av-DI&9mOCg%FshSq(VFIsI!@xpO%AN zviN$mXVaU4{lq@pqEf;!QV>ZRtmx-w8XFU*4 zMa!Z20&do8EJTOkn}SzoO@f|ChfW!KkZvsi1>&r~r$XqlpYRi~sDe)iQ*;I)Wk?=i zU^SM5fizE~r$8nRrY=4CRTW5$IJ}c9RRHVdi-@kw2qw~0TUg+I_1F>sm85ZOeNxCCc7#IUg1YSLWp5RW|lE0NlAE)uY36TdKcwc-sk=tAvI?) zz$X&VGQ+fqH;AV`&;VI;7KB}fpVpo$X8uo0zIC&faF z_TwJ@p{8FVmqM-*7&#VDfd;wh2mgcL-CFtBq?;6s1Klr<^Dznpc7aCCalVfor*Q)K zpMfjA?XT2J=5y%2bI}!wUbWco&W#?08mU+MF0Q*00030 zdQab3Gv8S=>S93NSTo;PGv8P<;8-*0T{+ERM&DR8-&r%@Su@~SG~ik^;94}}TsPrg zJl|L|-&ix>STo;QGv8S=;aWA|S~TNZG~Zb>-&r%?Sv22TGvHY>-&r)^Sv2EbHsxA2 z+*vf=Sv22SGv8S>-&ix?Sv22SGv8P<-dZ%`TsPoaGfqxUP*6}zOiWEpO-@cuPft%w zOiW8lOW;~H-dHpL|NsBf3TM4X)z{c9PmSJLGyeYm|NQ&?`S{{(O#Jfj-(Nf4TQ=C) z+T(Ch;A24HX-Mv@n&*ga=6_@R?C9TIIr!e!_S4DZa#Q-{-}u|p@U)}hXGZCfdFYLF z{rC0#_4E4Y;`!p-_0GiWorv=D^Y_`%^ToLG!L;RkU-|j^_SMYsx2Nisf98W{<8)U4 z{`~y!>*(p~;Nju*%fIx;yX~fu>6Coug=*w^T=w?&^1ZL%WkcU#KK;%M@w=?;qmSTU zFzoH^`s(K7<>uYo+}hjR;MmvV($DUxm+F{;jh#XJ{rv9m^wHSnzah< zif?tpTTH1)V!21-X)WY$E9iYD?vx(#qZ;(97yi);yT;nV<+NgZs#$cUQEj2`uboF_ zoNKy9sf9eoY&Z9|6a2~z_51Yc?epR0@7&_-%G2YmyVK3;!+@2#73|MtstinO!dqo~@JG*ywI z*N*?{hke3$h0APv#bjo*V6}BQ)L}K{b1LkPA^E%#__`A1^xwnH-~ag5=GW8M?$Gbl z&Em_(ik-m!@T#oan&haMcdSJD!!Pll8(A!95C8xG0d!JMQvg8b*k%9# z00Cl4M??UK1szBL000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jv414Kxkt8+M`q z01aD7L_t(|+SOcFR20b?o^$kg;2a(Sc~Id6!_lXGxaZ73GkIWU$QcGuK#-tB$zlQp zQGy9!O?xGobJlCv^_th!HLYpW-EcSW%{fe0bywHSRP|I3=sov;@Gw2y)!$Tof2_Y$ zsm3K?q4Q?=hXknpC*tonN$oD$psAs6>iq$;wQ3oeH2t+B@SCD$kU;;}hhRDr0w|MT z3r|7_B(U0&3rjL%<7#7U4W2k=Pc(!Xt~{{DwRcsd=rx#RC+6F$Yb~zRF`?^#kK7QO zmZ;NE#E{e$hXVF7$Ih&7ok4w9LQhF;LTUe-XQXB40rF%;Xx%QJk%ATDb%ngxg5$Y7|<)k&iI7^=i6 zn>8+_Fn0-D&{f7U8%$f9Nq~`3B3zm>j-|+qhlA-0V$@2++$=n($xru{pMsG#7YGoV zjB2Hluv36xiWRO*Rfa(@4y7pq8%x!`i1{#FNnM)23_l+z*=_)1lrK{ID#=OkSEL#h z(-S^m*$4-yv#Q4-8IYmbB?^6-FqgUT=?wMw#0YJSUKl4x$y!+9vx%ZkXzP>L#~9On zm=#MJBu1VBR{}X{gOqGa0H5l&M=#b%aYL+G8H`=o;88pL6wIodHmF@yQWWv$Rr4jc zpigSHDM3*Rhf9N>=CIi)E0_npi&n(_W+Cn+_4$QLh>?Q-s8AMLZ3c0JAr>2@+Tj^B z6eY8xsD~75ho2Y}!vgfefP0FK#MnjOmB4Pezz-|i%NH+Rwru{= zh3+sC*{NX#p@yN*o9TpvXa~c)@ZpPSARHIHWcjkCIEwOGcFzjf84r~_Kt7I2Hn{4A zi^>~IHeXt|dI_c|CU)nV42)-mJT2hbfmv&k8B1Hb2v?L=b}fkm{;XNfW(7%vNTd=j z#-3_$Cq{W4D~>9_wnF+;guxgFSVhVdr&lFXV*H{SHWWbb9N;I;rJ8FqAP?DRneACJ zsYYcw3y2NzlKq}TGgF6w?TWXCemf_Fg%BV|G0iu24dkvyfPz-!v2Yi2&=Q>b4Ddbg zWb~w%cHMloL|Dhd3*gGC2~z=p)zHk;<|T~TxW>fbOA7fLbHJZ2MYa%diO=@*g#5y? zVks*KO(nxrB#~JG!l^j^y8^;P->^+Y$E^t7W0O96= zsHmueoxnXEY$_ei3=EXxh4qg0&h~f01zH{@>ocr>;h9OgmmFC>d zVsFw=CUZLn-*a|H)PcTz=RP@00?{eZW~t7>FcqzQ4aMx5B!e$_-_%Na;)|7V`~yci znYdBn9fTceDRN_eAmX5!yj5?*3BP=kO+gC0gNWhpOLAEcuo_+bb)pMj2|;w8XVg+d z0~KCSZxIZHS_rUc4B#Y0EkzpravJ%TBA(zy@N=X?t>s^ zgAAU(O03Iiqq((=Z`YkY%THH4gMRRlY&ix3_>Css@RRS4<`}JZ=MiA8DAaP5V*Y_- zNl6hUD0Y7(*MYrh?XAv*6tle}D(bxM4;?7klM@ij=1Bz$v_^U4`&V#_r8n(!zUjeT zB8a*D{fP=V4)YiTzAbn!==A9HN2!x-g zGG!L>?W?)B(Tfg(x9q!20HeO5Yu{B@Xmu!S|+p%;UV5gzh0z8ricmnwjmhYTh)x4(p`hgT{4^p6k!eKLX| zCx3DowFsp^LIRj6tK1owdQjzeUp@Tp>ecst9YK-3|LOOvm$V8X{80=}t)1IAOg)J5 z{&&=u3lK*4kn%8x03rk>U-UF`1?D|S5Z;qV0d5A7`4Dk(px<-Q1t<*@g1hyy#B};m zjvip%_^THP*MDju4SEL!wSt|9p$2!NdQgL_8}if8IQpD2r~|nxJf@*1El&05pn;IX z&^XpZ@4qR>qZ$xV%SY<593EV`$X8SZy`#f&9Y6{E0&f&I(!nK@Y{kjxJ!pm-*NWbs z$HoRvT<`6DIXE)h&ys}M#UK+=wN5Rg9u&iULxS*XNYR#5EJ{a%#fYEZ&nTilv6^PM z-gV%q&BkXw)hL zk&1pc4z8a9ahLspZw9%Lis^t|Alzl(}f>?%B4jTT7@T zrb&GjsA`tz12Z*x2}N&Di^uy%#(LqG+g!idgaS%GseZ^`)X{_FU&(|N|JW;;$iZ#H zL;YH{wq;Lu&%j_WW<;KQI`XmxG3^j)ck88EuOephPwg3W^V@`=s>jXz8L+rYS`U+K zb%V}KFsVbMdu82NZ#O9^2b7qJgQ(>9O%i07xl*=T*FW--?#Bi^e0c%Nzr;#^Ai|d6 z12a*o;EeAZN#VqZXEr1K!_KbMts57^(q{(sAGAwkw(7pmVd9o}07x z)u^rIk|7ACv<-l2NtTgPXs6}ohu!WBKla1X<75yOU{6#_VgxVKkVn@nuu#m^TA3P^ z)e3lY z^)3x9u&9>I)qVao-(FbjxgOzLk48cvtVaXrz`K*+?ln9c5P>bpB5=(rnX3=sdv<^Q zv7jGXb@(&>ryu_zQk0K8Lm9ABp9PCCA@ZGfU?;oWNHSNVBfWxN_3h`*kDq_=cb*1Y zwZ|eQIp*;^Y~X{@G`&q0wsIIj3#X%A##~*&UiNtZW8trNf5a|FZgqbg7$L!4%XN~^ zf_e%X!xF7@bA^MTi93j9*nFKp*9_O**bLw#?$mp<4~XXKL+oYm{E`e}4WZdglLLR* zRF+QVJgELQTHLQ31YC<&n-@ahdJ3DqG_A=Lb9G-K2ul;*u{e|UFhd%tiws3qA1DK1 zg?;QMsP|fyLvQ#R>Z*uUJRHOpuOMPze{Z}nuT0J3P({>>;4!BPjGh+JhwWzofwW^0 z>>JFnDZqe^cI*<46U2H(R~K*){}liF*GFrPdVttaDIAOtG(JS(k*7l8d`6QM^I^bT z{T}DUmZwj4?|$;=(Nm|P4!?$QT!X(v=v^#GP>4Zv>uPI-&_~wpmJHs;K6*|jyi4Uc@rvmsa56cek(aQI)m#e^bQtm+8oeNti8+aUU|?-7Lk&hj!ybze)>4}gH`ud-KVflp^91I2{A0)^FWmjoa7 zapd<`E_kLP!cMm(GgmyunB6Rfic?iSi61gjDd;uxmqQ>p^ zd%b?DamySmGnY;t%1V3}wy8HEM`tmD@~XEpU%rXlP-Kt83Klab?$CX(YjU4g>3Wh{ z)P?vYdx=XucGAS2E}!n+3}>v_RGeRtl$z7(NG!_DuWQR#?_P8ZR86=9OjcBe&<3ks zkND4Jg)mL^I%VE0uK;EStKNY42hjoeg}urD1|w|7>_F^)VVD#Y9HRQamj43l^drmh S+%!G_0000x diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg deleted file mode 100644 index e7fa529fbad5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg deleted file mode 100644 index 09d92456dfbf..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg deleted file mode 100644 index 616649e71fec..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg deleted file mode 100644 index 86b88037dfa2..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg deleted file mode 100644 index c82fddf86b52..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg deleted file mode 100644 index ad24185a26a1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg deleted file mode 100644 index 3910c2941080..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg deleted file mode 100644 index df1d25f89b9e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html deleted file mode 100644 index a9b67364af59..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - Privacy Dashboard - - -

Links

- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css deleted file mode 100644 index b21ec65a2e2a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css +++ /dev/null @@ -1,148 +0,0 @@ -.material-design-ripple { - --mdc-ripple-fg-size: 0; - --mdc-ripple-left: 0; - --mdc-ripple-top: 0; - --mdc-ripple-fg-scale: 1; - --mdc-ripple-fg-translate-end: 0; - --mdc-ripple-fg-translate-start: 0; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - will-change: transform, opacity; - overflow: hidden; -} -.material-design-ripple::before, .material-design-ripple::after { - position: absolute; - border-radius: 50%; - opacity: 0; - pointer-events: none; - content: ""; -} -.material-design-ripple::before { - transition: opacity 15ms linear, background-color 15ms linear; - z-index: 1; - /* @alternate */ - z-index: var(--mdc-ripple-z-index, 1); -} -.material-design-ripple::after { - z-index: 0; - /* @alternate */ - z-index: var(--mdc-ripple-z-index, 0); -} -.material-design-ripple.mdc-ripple-upgraded::before { - transform: scale(var(--mdc-ripple-fg-scale, 1)); -} -.material-design-ripple.mdc-ripple-upgraded::after { - top: 0; - /* @noflip */ /*rtl:ignore*/ - left: 0; - transform: scale(0); - transform-origin: center center; -} -.material-design-ripple.mdc-ripple-upgraded--unbounded::after { - top: var(--mdc-ripple-top, 0); - /* @noflip */ /*rtl:ignore*/ - left: var(--mdc-ripple-left, 0); -} -.material-design-ripple.mdc-ripple-upgraded--foreground-activation::after { - animation: mdc-ripple-fg-radius-in 225ms forwards, mdc-ripple-fg-opacity-in 75ms forwards; -} -.material-design-ripple.mdc-ripple-upgraded--foreground-deactivation::after { - animation: mdc-ripple-fg-opacity-out 150ms; - transform: translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1)); -} -.material-design-ripple::before, .material-design-ripple::after { - top: calc(50% - 100%); - /* @noflip */ /*rtl:ignore*/ - left: calc(50% - 100%); - width: 200%; - height: 200%; -} -.material-design-ripple.mdc-ripple-upgraded::after { - width: var(--mdc-ripple-fg-size, 100%); - height: var(--mdc-ripple-fg-size, 100%); -} -.material-design-ripple::before, .material-design-ripple::after { - background-color: #000; - /* @alternate */ - background-color: var(--mdc-ripple-color, #000); -} -.material-design-ripple:hover::before, .material-design-ripple.mdc-ripple-surface--hover::before { - opacity: 0.04; - /* @alternate */ - opacity: var(--mdc-ripple-hover-opacity, 0.04); -} -.material-design-ripple.mdc-ripple-upgraded--background-focused::before, .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { - transition-duration: 75ms; - opacity: 0.12; - /* @alternate */ - opacity: var(--mdc-ripple-focus-opacity, 0.12); -} -.material-design-ripple:not(.mdc-ripple-upgraded)::after { - transition: opacity 150ms linear; -} -.material-design-ripple:not(.mdc-ripple-upgraded):active::after { - transition-duration: 75ms; - opacity: 0.12; - /* @alternate */ - opacity: var(--mdc-ripple-press-opacity, 0.12); -} -.material-design-ripple.mdc-ripple-upgraded { - --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.12); -} - -.body--theme-light .material-design-ripple::before, .body--theme-light .material-design-ripple::after { - background-color: black; - /* @alternate */ - background-color: var(--mdc-ripple-color, black); -} -.body--theme-light .material-design-ripple:hover::before, .body--theme-light .material-design-ripple.mdc-ripple-surface--hover::before { - opacity: 0; - /* @alternate */ - opacity: var(--mdc-ripple-hover-opacity, 0); -} -.body--theme-light .material-design-ripple.mdc-ripple-upgraded--background-focused::before, .body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { - transition-duration: 75ms; - opacity: 0.08; - /* @alternate */ - opacity: var(--mdc-ripple-focus-opacity, 0.08); -} -.body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded)::after { - transition: opacity 150ms linear; -} -.body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded):active::after { - transition-duration: 75ms; - opacity: 0.08; - /* @alternate */ - opacity: var(--mdc-ripple-press-opacity, 0.08); -} -.body--theme-light .material-design-ripple.mdc-ripple-upgraded { - --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.08); -} - -.body--theme-dark .material-design-ripple::before, .body--theme-dark .material-design-ripple::after { - background-color: white; - /* @alternate */ - background-color: var(--mdc-ripple-color, white); -} -.body--theme-dark .material-design-ripple:hover::before, .body--theme-dark .material-design-ripple.mdc-ripple-surface--hover::before { - opacity: 0; - /* @alternate */ - opacity: var(--mdc-ripple-hover-opacity, 0); -} -.body--theme-dark .material-design-ripple.mdc-ripple-upgraded--background-focused::before, .body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { - transition-duration: 75ms; - opacity: 0.3; - /* @alternate */ - opacity: var(--mdc-ripple-focus-opacity, 0.3); -} -.body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded)::after { - transition: opacity 150ms linear; -} -.body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded):active::after { - transition-duration: 75ms; - opacity: 0.3; - /* @alternate */ - opacity: var(--mdc-ripple-press-opacity, 0.3); -} -.body--theme-dark .material-design-ripple.mdc-ripple-upgraded { - --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.3); -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css deleted file mode 100644 index 2721c686a2f4..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css +++ /dev/null @@ -1,765 +0,0 @@ -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Logo */ -/* Font groupings */ -.uppercase { - font-size: 12px; - color: #888888; - text-transform: uppercase; - letter-spacing: 0.1em; - font-weight: bold; -} - -/* Lists */ -/* Images & icons */ -/* Cross-platform background image */ -* { - box-sizing: border-box; -} - -/* Normalize File */ -/*! normalize.scss v0.1.0 | MIT License | based on git.io/normalize */ -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ -html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ -body { - margin: 0; -} - -/* HTML5 display definitions - ========================================================================== */ -/** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. - */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -/** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. - */ -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. - */ -[hidden], -template { - display: none; -} - -/* Links - ========================================================================== */ -/** - * Remove the gray background color from active links in IE 10. - */ -a { - background-color: transparent; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ -a:active, -a:hover { - outline: 0; -} - -/* Text-level semantics - ========================================================================== */ -/** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. - */ -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. - */ -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari and Chrome. - */ -dfn { - font-style: italic; -} - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. - */ -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/** - * Address styling not present in IE 8/9. - */ -mark { - background: #ff0; - color: #000; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* Embedded content - ========================================================================== */ -/** - * Remove border when inside `a` element in IE 8/9/10. - */ -img { - border: 0; -} - -/** - * Correct overflow not hidden in IE 9/10/11. - */ -svg:not(:root) { - overflow: hidden; -} - -/* Grouping content - ========================================================================== */ -/** - * Address margin not present in IE 8/9 and Safari. - */ -figure { - margin: 1em 40px; -} - -/** - * Address differences between Firefox and other browsers. - */ -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} - -/** - * Contain overflow in all browsers. - */ -pre { - overflow: auto; -} - -/** - * Address odd `em`-unit font size rendering in all browsers. - */ -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -/* Forms - ========================================================================== */ -/** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. - */ -/** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. - */ -button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address `overflow` set to `hidden` in IE 8/9/10/11. - */ -button { - overflow: visible; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. - */ -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ -button, -html input[type=button], -input[type=reset], -input[type=submit] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ -input { - line-height: normal; -} - -/** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ -input[type=checkbox], -input[type=radio] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. - */ -input[type=number]::-webkit-inner-spin-button, -input[type=number]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome - * (include `-moz` to future-proof). - */ -input[type=search] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). - */ -input[type=search]::-webkit-search-cancel-button, -input[type=search]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Define consistent border, margin, and padding. - */ -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Remove default vertical scrollbar in IE 8/9/10/11. - */ -textarea { - overflow: auto; -} - -/** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. - */ -optgroup { - font-weight: bold; -} - -/* Tables - ========================================================================== */ -/** - * Remove most spacing between table cells. - */ -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} - -/** - * DDG Extension Resets & Base Styles - */ -h1, -h2, -h3, -h4, -h5, -h5, -p, -div { - margin: 0; - padding: 0; -} - -section, -ul, -ol, -li { - margin: 0; - padding: 0; - position: relative; -} - -.environment--android form, -.environment--android input, -.environment--android select, -.environment--android option, -.environment--android button, -.environment--ios form, -.environment--ios input, -.environment--ios select, -.environment--ios option, -.environment--ios button { - outline: none; -} -.environment--android form *, -.environment--android input *, -.environment--android select *, -.environment--android option *, -.environment--android button *, -.environment--ios form *, -.environment--ios input *, -.environment--ios select *, -.environment--ios option *, -.environment--ios button * { - outline: none; -} - -button { - border: none; - background-color: #ffffff; - padding: 0; -} - -/* Fonts */ -input, -textarea, -select { - color: #333333; -} - -.body--theme-dark input, -.body--theme-dark textarea { - color: rgba(255, 255, 255, 0.9); -} -.body--theme-dark input, -.body--theme-dark textarea { - background-color: #333333; -} - -.body--theme-dark.environment--windows select { - background-color: rgba(255, 255, 255, 0.06); - border-color: #444; - color: rgba(255, 255, 255, 0.9); -} - -.body--theme-dark.environment--windows select > option { - background-color: #333333; -} - -.bold { - font-weight: bold; -} - -strong { - font-weight: bold; -} -.environment--browser strong { - font-weight: 600; -} - -/* Links */ -a { - color: var(--color-accent-blue); - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -.environment--ios a.link-action:visited, .environment--ios a.link-action:active, .environment--ios a.link-action:hover, .environment--android a.link-action:visited, .environment--android a.link-action:active, .environment--android a.link-action:hover { - text-decoration: none; -} -a.link-action--text { - padding: 16px 0; - display: block; -} -a.link-action--text-short { - display: block; - padding: 12px 0; -} -a.link-action--text-micro { - display: block; - padding: 8px 0; -} -a.link-action--rounded { - border-radius: 12px; - padding-top: 14px; - padding-bottom: 14px; -} -.environment--ios a.link-action--rounded { - font-size: 14px; - padding-top: 16px; - padding-bottom: 16px; -} -.environment--windows a.link-action--rounded { - line-height: 22px; - font-size: 14px; - padding-top: 16px; - padding-bottom: 16px; -} -.environment--browser a.link-action--rounded { - line-height: 18px; - font-size: 14px; - padding-top: 12px; - padding-bottom: 12px; -} - -/** - * DDG Extension Helper Classes - */ -/* Hide element */ -.is-hidden { - display: none; -} - -/* Position */ -.pull-right { - position: absolute; - right: 16px; -} - -.pull-left { - position: absolute; - left: 16px; -} - -/* Display */ -.block { - display: block; -} - -/* Floats */ -.float-left { - float: left; -} - -.float-right { - float: right; -} - -.clearfix { - clear: both; - height: 0; - line-height: 0; -} - -/* Text Centering */ -.text--center { - text-align: center; -} - -.height-full { - height: 100%; -} - -.text--left { - text-align: left; -} - -/* Text Wrap */ -.text--balance { - text-wrap: balance; -} - -/* Borders */ -.border--top { - border-top: 1px solid var(--color-lines-light); -} - -.border--bottom { - border-bottom: 1px solid var(--color-lines-light); -} - -.border-light--top { - border-top: 1px solid var(--color-lines-lighter); -} - -.border--top--inner { - position: relative; -} -.border--top--inner:before { - content: ""; - border-top: 1px solid var(--color-lines-light); - position: absolute; - top: 0; - left: 0; - right: 0; -} - -.padding-x { - padding-left: 16px; - padding-right: 16px; -} - -.padding-y { - padding-top: 16px; - padding-bottom: 16px; -} - -.padding-y-third { - padding-top: 24px; - padding-bottom: 24px; -} - -.padding-y--reduced { - padding-top: 14px; - padding-bottom: 14px; -} -.environment--ios .padding-y--reduced, .environment--android .padding-y--reduced { - padding-top: 8.5px; - padding-bottom: 8.5px; -} - -.padding-bottom-half { - padding-bottom: 10px; -} - -.bg-primary { - background: white; -} - -.padding-x-double { - padding-left: 32px; - padding-right: 32px; -} - -.padding-x-third { - padding-left: 24px; - padding-right: 24px; -} - -.padding-x-xl { - padding-left: 44px; - padding-right: 44px; -} - -.padded--top { - padding: 24px 0 0; -} - -.padded--no-bottom-padding { - padding-bottom: 0; -} - -/* Icons */ -/* Standard icon display within the extension */ -.icon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - /* you'll need to set the background image within each instance of .icon */ -} -.icon.icon__close { - width: 14px; - height: 14px; - background-image: url("../../img/close.svg"); -} -.icon.icon__arrow { - width: 12px; - height: 12px; - background-size: contain; - background-image: url("../../img/refresh-assets/chevron.svg"); -} -.body--theme-dark .icon.icon__arrow { - background-image: url("../../img/refresh-assets/chevron--light.svg"); -} -.icon.icon__arrow.icon__arrow--left { - transform: rotate(180deg); -} -.icon.icon__arrow.icon__arrow--large { - width: 7px; - margin-top: -20px; - background-image: url("../../img/arrow--large.svg"); -} -.icon.icon__back-arrow { - background-size: contain; - background-image: url("../../img/refresh-assets/back-arrow.svg"); -} -.body--theme-dark .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-arrow--light.svg"); -} -.environment--android .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-arrow-android.svg"); -} -.body--theme-dark.environment--android .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-arrow-android--light.svg"); -} -.environment--ios .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-chevron-ios.svg"); - width: 20px; - height: 20px; -} -.environment--ios .icon.icon__back-arrow:before { - content: attr(data-icon-text); - display: block; - height: 20px; - line-height: 20px; - margin-left: 20px; -} -.body--theme-dark.environment--ios .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-chevron-ios--light.svg"); -} - -.separator { - width: 1px; - height: 18px; - background-color: rgba(0, 0, 0, 0.05); - display: inline-block; - vertical-align: bottom; - margin: 0 7px; -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css deleted file mode 100644 index 4d02f2bf9b19..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css +++ /dev/null @@ -1,4095 +0,0 @@ -@charset "UTF-8"; -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Logo */ -/* Font groupings */ -.uppercase { - font-size: 12px; - color: #888888; - text-transform: uppercase; - letter-spacing: 0.1em; - font-weight: bold; -} - -/* Lists */ -/* Images & icons */ -/* Cross-platform background image */ -/** - * We are using a subset of DDG fonts that are compatible with Chrome: - */ -@font-face { - font-family: "DDG_ProximaNova"; - src: url("/public/font/ProximaNova-Reg-webfont.woff") format("woff"); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: "DDG_ProximaNova"; - src: url("/public/font/ProximaNova-Sbold-webfont.woff") format("woff"); - font-weight: 600; - font-style: bold; -} -.token-body { - font-family: system, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 13px; - font-weight: 400; - line-height: 16px; -} -.token-body.environment--android { - font-size: 14px; - font-weight: 400; - line-height: 20px; -} -.token-body.environment--browser { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 18px; -} - -.token-body-em { - font-size: 13px; - font-weight: 600; - line-height: 16px; -} -.environment--android .token-body-em { - font-size: 14px; - font-weight: 500; - line-height: 20px; -} -.environment--ios .token-body-em { - font-size: 15px; - font-weight: 600; - line-height: 22px; -} -.environment--browser .token-body-em { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-weight: 600; - font-size: 14px; - line-height: 20px; -} - -/* Mac/System Keywords/Title 2 (Emphasis) */ -.token-title-2-em { - font-size: 17px; - font-style: normal; - font-weight: 600; - line-height: 22px; -} - -.token-title-3 { - font-size: 15px; - font-weight: 400; - line-height: 20px; -} -.environment--ios .token-title-3 { - font-size: 16px; - line-height: 22px; - letter-spacing: 0; -} -.environment--android .token-title-3 { - font-size: 16px; - line-height: 20px; - letter-spacing: 0; -} -.environment--browser .token-title-3 { - font-family: "DDG_ProximaNova"; - font-size: 16px; - line-height: 20px; -} - -.token-ios-title-3 { - font-size: 20px; - font-weight: 600; - line-height: 1.25; -} - -.token-title-3-em { - font-size: 16px; - font-weight: 600; - line-height: 22px; -} -.environment--android .token-title-3-em { - font-size: 16px; - line-height: 20px; -} -.token-title-3-em .environment--windows { - font-size: 16px; - font-weight: 600; - line-height: 1.25; -} -.environment--browser .token-title-3-em { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-size: 16px; - line-height: 20px; -} - -.token-breakage-form-body { - font-size: 13px; - font-weight: 400; - line-height: 16px; -} -.environment--android .token-breakage-form-body { - font-size: 16px; - font-weight: 400; - line-height: 20px; - letter-spacing: 0em; -} -.environment--browser .token-breakage-form-body { - font-size: 14px; - font-weight: 400; - line-height: 18px; -} -.environment--windows .token-breakage-form-body { - font-size: 14px; - font-weight: 400; - line-height: 20px; -} - -.token-headline-2 { - font-size: 20px; - font-weight: 500; - line-height: 1.2; -} - -.token-label-em { - font-size: 13px; - font-weight: 600; - line-height: 13px; -} -.environment--android .token-label-em { - font-size: 15px; - font-weight: 700; - line-height: 21px; - letter-spacing: 0em; -} -.environment--browser .token-label-em { - font-size: 13px; - font-weight: 600; - line-height: 13px; -} - -.token-search-input { - font-weight: 400; - font-size: 15px; - line-height: 20px; -} - -.token-bold { - font-weight: 600; -} - -@media (prefers-reduced-motion: reduce) { - * { - transition: none !important; - } -} - -/* Popup */ -body { - font-family: system, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 13px; - font-weight: 400; - line-height: 16px; - overflow: hidden; - user-select: none; - -webkit-user-select: none; - -webkit-tap-highlight-color: transparent; - --width: 360px; - --height: 100vh; - --bg: #eee; - --page-bg: #ffffff; - --page-outer-bg: #eee; - --color-text-primary: rgba(0, 0, 0, 0.84); - --color-text-secondary: rgba(0, 0, 0, 0.6); - --color-accent-blue: #3969ef; - --color-accent-blue-active: #1e42a4; - --color-lines-light: rgba(0, 0, 0, 0.12); - --color-lines-lighter: rgba(0, 0, 0, 0.06); - --color-hover-bg: rgba(0, 0, 0, 0.06); - --color-system-lines: rgba(0, 0, 0, 0.09); - --size-unit: 16px; - --size-unit-half: calc(var(--size-unit) / 2); - --size-unit-double: calc(var(--size-unit) * 2); - --btn-accent-border-radius: 8px; - --btn-accent-border: 0.5px solid rgba(40, 145, 255, 0.05); - --btn-accent-bg: linear-gradient(180deg, #4690f7 0%, #307bf7 100%); - --btn-accent-bg-hover: linear-gradient(180deg, #4690f7 0%, #307bf7 100%); - --btn-accent-bg-active: linear-gradient(0deg, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.12)), - linear-gradient(180deg, #1f8aff 0%, #0173ff 100%); - --btn-accent-color: #ffffff; - --btn-accent-shadow: 0px 0px 1px rgba(40, 145, 255, 0.05), 0px 1px 1px rgba(40, 145, 255, 0.1); - color: var(--color-text-primary); - background: var(--bg); - width: var(--width); - height: var(--height); -} -body.environment--android { - font-size: 14px; - font-weight: 400; - line-height: 20px; -} -body.environment--browser { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 18px; -} -body.environment--ios { - --width: 100%; - --height: -webkit-fill-available; -} -body.environment--android { - --width: 100%; -} -body.environment--macos[data-screen=toggleReport] { - --height: auto; -} -body.environment--browser { - --height: 600px; -} -body.environment--windows { - --bg: #ffffff; - --btn-accent-border-radius: none; - --btn-accent-border: 0.5px solid rgba(40, 145, 255, 0.05); - --btn-accent-bg: #3969ef; - --btn-accent-bg-hover: #2b55ca; - --btn-accent-bg-active: #1e42a4; - --btn-accent-shadow: none; -} -body.body--theme-light.environment--ios, body.body--theme-light.environment--android { - --bg: #ffffff; -} -body.body--theme-dark { - --text: rgba(255, 255, 255, 0.9); - --page-bg: #333333; - --bg: #34383b; - --page-outer-bg: #34383b; - --color-text-primary: rgba(255, 255, 255, 0.84); - --color-text-secondary: rgba(255, 255, 255, 0.6); - --color-accent-blue: #7295f6; - --color-accent-blue-active: #8fabf9; - --color-lines-light: rgba(255, 255, 255, 0.18); - --color-lines-lighter: rgba(255, 255, 255, 0.09); - --color-hover-bg: rgba(255, 255, 255, 0.12); - --color-system-lines: rgba(255, 255, 255, 0.09); -} -body.body--theme-dark.environment--windows { - --btn-accent-color: #000000; - --btn-accent-bg: #7295f6; - --btn-accent-bg-hover: #557ff3; - --btn-accent-bg-active: #3969ef; -} -body.body--theme-dark.environment--android { - --bg: #111111; - --page-bg: #111111; -} -body.body--theme-dark.environment--ios { - --bg: #222222; - --page-bg: #222222; -} - -.app-height { - height: var(--height); -} - -#popup-container { - display: block; -} -#popup-container section::-webkit-scrollbar { - display: none; -} -#popup-container .text-line-after-icon { - margin-left: 12px; -} -#popup-container .sliding-subview { - background-color: var(--page-bg); -} - -body { - /* 'toggle' here means the wrapping container, a button element */ - --toggle-width: 32px; - --toggle-height: 18px; - --toggle-opacity: 1; - --toggle-opacity-disabled: 1; - /* the 'knob', also referred to as the 'handle' */ - --handle-size: 16px; - --handle-offset: 1px; - --handle-color: #ffffff; - --handle-color-off: #ffffff; - --handle-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.25); - /* the 'track' is the underlying colored background */ - --track-color: #007aff; - --track-outline: none; - --track-outline-off: none; - --track-color-off: #d8d8d8; - /* the 'spinner' is only used on ios/macos */ - --toggle-spinner-size: 18px; -} -body.environment--ios { - --toggle-width: 51px; - --toggle-height: 31px; - --toggle-spinner-size: 31px; - --handle-size: 27px; - --handle-offset: 2px; - --track-color: #21c000; -} -body.environment--android { - --toggle-width: 51px; - --toggle-height: 31px; - --toggle-spinner-size: 31px; - --handle-size: 24px; - --handle-offset: 4px; - --handle-shadow: none; - --track-color: #3969ef; - --track-color-off: rgba(136, 136, 136, 0.5); -} -body.environment--android.body--theme-dark { - --track-color: #7295f6; - --track-color-off: rgba(204, 204, 204, 0.5); -} -body.environment--windows { - --toggle-width: 40px; - --toggle-height: 20px; - --handle-size: 10px; - --handle-offset: 5px; - --handle-color-off: rgba(0, 0, 0, 0.9); - --handle-shadow: none; - --track-color: #3969ef; - --track-color-off: #ffffff; - --track-outline: 1px solid var(--track-color); - --track-outline-off: 1px solid rgba(0, 0, 0, 0.48); - --toggle-opacity-disabled: 0.6; -} - -.toggle-button { - z-index: 0; - margin: 0; - padding: 0; - border: none; - background-color: transparent; - text-align: left; - position: relative; - border-radius: 100px; - opacity: var(--toggle-opacity); - width: var(--toggle-width); - height: var(--toggle-height); -} -.toggle-button[disabled] { - opacity: var(--toggle-opacity-disabled); -} - -.toggle-button__track { - z-index: -1; - position: absolute; - right: 0; - top: 0; - overflow: visible; - border-radius: 100px; - border: var(--track-outline); - width: var(--toggle-width); - height: var(--toggle-height); - background-color: var(--track-color); -} -[aria-checked=false] .toggle-button__track { - background-color: var(--track-color-off); - border: var(--track-outline-off); -} - -.toggle-button__handle { - z-index: 2; - position: absolute; - border-radius: 100px; - top: 50%; - transform: translateY(-50%); - transition: all 0.2s ease; - box-shadow: var(--handle-shadow); - background-color: var(--handle-color); - width: var(--handle-size); - height: var(--handle-size); - right: var(--handle-offset); -} -[aria-checked=false] .toggle-button__handle { - right: calc(100% - var(--handle-size) - var(--handle-offset)); - background-color: var(--handle-color-off); -} - -.toggle-spinner { - margin: 0 auto; - height: var(--toggle-spinner-size); - width: var(--toggle-spinner-size); -} - -.page { - display: flex; - flex-direction: column; -} -.environment--browser .page, .environment--ios .page, .environment--android .page { - height: 100%; -} - -.page-inner { - display: flex; - flex-direction: column; - flex-flow: column; - z-index: 1; - overflow-y: auto; - -ms-overflow-style: none; - scrollbar-width: none; - background: var(--page-bg); -} -.page-inner::-webkit-scrollbar { - display: none; -} -.environment--browser .page-inner, .environment--ios .page-inner, .environment--android .page-inner { - height: 100%; -} -.page-inner[data-with-permissions=true] { - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.05), 0px 1px 0px rgba(0, 0, 0, 0.1); -} - -.page-outer { - z-index: 0; - background: var(--page-outer-bg); -} - -.header { - padding-left: 16px; - padding-right: 16px; - border-bottom: 1px solid var(--color-lines-light); -} -.environment--macos .header { - padding-top: 16px; - padding-bottom: 2px; -} -.environment--windows .header { - padding-top: 16px; -} -.environment--browser .header { - padding-top: 6px; -} -.environment--android .header { - padding-bottom: 10px; -} -.environment--ios .header { - padding-bottom: 10px; -} - -.header--breakage { - padding-left: 16px; - padding-right: 16px; - padding-bottom: 16px; - border-bottom: 0; -} -.environment--macos .header--breakage, .environment--windows .header--breakage { - padding-bottom: 16px; -} -.environment--browser .header--breakage { - padding-top: 16px; - padding-bottom: 12px; -} - -.header-spacer { - padding-top: 24px; -} -.environment--macos .header-spacer { - padding-top: 20px; -} -.environment--windows .header-spacer { - padding-top: 20px; -} -.environment--browser .header-spacer { - padding-top: 12px; -} - -.footer { - margin-top: auto; -} -.environment--macos .footer, .environment--windows .footer { - padding-bottom: 20px; -} - -.site-info { - margin-top: 0; -} -.environment--browser .site-info { - height: 100%; -} -.environment--ios .site-info > :last-child { - padding-bottom: 18px; -} -.site-info .list-wrapper { - background-color: var(--page-bg); -} -.site-info .default-list { - padding-bottom: 0; -} -.site-info:has(.page-outer) .page-inner { - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.05), 0px 1px 0px rgba(0, 0, 0, 0.1); -} - -.site-info__page-permission label { - display: flex; - justify-content: space-between; - overflow: hidden; - padding: 16px 0; -} -.site-info__page-permission select { - float: right; - max-width: 170px; -} -.site-info__page-permission + .site-info__page-permission { - border-top: 1px solid var(--color-lines-light); -} - -.site-info__li--manage-permissions { - padding: 5px 16px 0; -} - -.site-info__page-permission__icon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - margin-right: 8px; -} -.site-info__page-permission__icon[data-icon=geolocation] { - background-image: url("../../img/refresh-assets/permissions-location.svg"); -} -.body--theme-dark .site-info__page-permission__icon[data-icon=geolocation] { - background-image: url("../../img/refresh-assets/permissions-location-light.svg"); -} -.site-info__page-permission__icon[data-icon=microphone] { - background-image: url("../../img/refresh-assets/permissions-microphone.svg"); - margin-top: -2px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=microphone] { - background-image: url("../../img/refresh-assets/permissions-microphone-light.svg"); -} -.site-info__page-permission__icon[data-icon=camera] { - background-image: url("../../img/refresh-assets/permissions-camera.svg"); - width: 16px; - height: 12px; - margin-top: -2px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=camera] { - background-image: url("../../img/refresh-assets/permissions-camera-light.svg"); -} -.site-info__page-permission__icon[data-icon=popups] { - background-image: url("../../img/refresh-assets/permissions-popups.svg"); -} -.body--theme-dark .site-info__page-permission__icon[data-icon=popups] { - background-image: url("../../img/refresh-assets/permissions-popups-light.svg"); -} -.site-info__page-permission__icon[data-icon=externalScheme] { - background-image: url("../../img/refresh-assets/permissions-externalScheme.svg"); - margin-top: -4px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=externalScheme] { - background-image: url("../../img/refresh-assets/permissions-externalScheme-light.svg"); -} -.site-info__page-permission__icon[data-icon=notification] { - background-image: url("../../img/refresh-assets/permissions-notification.svg"); - width: 16px; - height: 14px; - margin-top: -4px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=notification] { - background-image: url("../../img/refresh-assets/permissions-notification-light.svg"); -} - -.site-info__protection-wrapper { - padding: 16px; -} - -.site-info__protection { - opacity: 1; - margin-top: 0; - padding-right: 10px; -} - -.site-info-toggle { - color: #333333; - display: flex; - align-items: center; -} -.body--theme-dark .site-info-toggle { - color: rgba(255, 255, 255, 0.9); -} - -.site-info__toggle-container { - margin-left: auto; - text-align: center; - display: flex; - width: var(--toggle-width); - height: var(--toggle-height); -} - -.card { - background-color: var(--page-bg); -} -.environment--browser .card { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -.card-list--bordered { - border: 1px solid var(--color-lines-light); - border-radius: 12px; - position: relative; - z-index: 0; - overflow: hidden; -} - -.main-nav { - border: 1px solid var(--color-lines-light); - border-radius: 12px; - position: relative; - z-index: 0; - overflow: hidden; -} - -.main-nav__row { - position: relative; - /* - The following avoids height shifts when hovering over nav rows. - - Each row has an :after element that provides the separator line. When hovering a row, we need to change the color of any adjacent separators (i.e. the current row and the row above it). - - We do that by targeting the current row directly, then use a :has selector to also target the previous sibling of the current row. - - We also use the :not selector to exclude any rows marked as no-hover. - */ -} -.main-nav__row:after { - content: " "; - display: block; - width: calc(100% - 32px); - height: 1px; - background: var(--color-lines-light); - position: absolute; - bottom: -0.5px; - left: 16px; -} -.main-nav__row:not(.no-hover):hover:after, .main-nav__row:has(+ :not(.no-hover):hover):after { - background-color: var(--page-bg); -} -.main-nav__row:last-child { - border-bottom: none; -} -.main-nav__row:last-child:after { - display: none; -} - -.main-nav__item { - z-index: 10; - position: relative; - display: flex; - height: 44px; - align-items: center; - -webkit-touch-callout: none; -} -.environment--ios .main-nav__item, .environment--android .main-nav__item { - height: 48px; -} -.environment--browser .main-nav__item { - height: 40px; -} -.main-nav__item:has(.main-nav__icon) .main-nav__text { - margin-left: 10px; -} - -.main-nav__item--link { - color: var(--color-text-primary); -} -.environment--example .main-nav__item--link:focus, .environment--browser .main-nav__item--link:focus, .environment--windows .main-nav__item--link:focus, .environment--macos .main-nav__item--link:focus { - outline: 0; - text-decoration: underline; -} -.environment--example .main-nav__item--link:visited, .environment--example .main-nav__item--link:active, .environment--example .main-nav__item--link:hover, .environment--browser .main-nav__item--link:visited, .environment--browser .main-nav__item--link:active, .environment--browser .main-nav__item--link:hover, .environment--windows .main-nav__item--link:visited, .environment--windows .main-nav__item--link:active, .environment--windows .main-nav__item--link:hover, .environment--macos .main-nav__item--link:visited, .environment--macos .main-nav__item--link:active, .environment--macos .main-nav__item--link:hover { - text-decoration: none; - background: var(--color-hover-bg); -} -.environment--ios .main-nav__item--link:active { - opacity: 0.5; -} - -.main-nav__icon { - width: 18px; - height: 18px; - z-index: 1; - margin-left: 19px; - background-repeat: no-repeat; - background-size: cover; - flex-shrink: 0; -} - -.main-nav__text { - display: block; - z-index: 1; - margin-left: 16px; - margin-right: 10px; - line-height: 1; - /** TODO: Move */ -} -.environment--ios .main-nav__text { - line-height: 1.3333333333; -} -.environment--android .main-nav__text { - line-height: 1.4285714286; -} -.environment--macos .main-nav__text { - line-height: 1.2307692308; -} -.environment--windows .main-nav__text { - line-height: 1.2857142857; -} - -.main-nav__chev { - width: 7px; - height: 18px; - margin-left: auto; - margin-right: 16px; - background-repeat: no-repeat; - background-size: 7px; - background-position: center center; - opacity: 60%; - background-image: url("../../img/refresh-assets/chevron.svg"); -} -.body--theme-dark .main-nav__chev { - background-image: url("../../img/refresh-assets/chevron--light.svg"); -} -.environment--ios .main-nav__chev, .environment--android .main-nav__chev { - opacity: 24%; -} - -.icon-small--info { - background-image: url("../../img/status--info.svg"); -} - -.icon-small--blocked, -.icon-small--secure { - background-image: url("../../img/refresh-assets/Check-Color-16.svg"); -} - -.icon-small--warning, -.icon-small--insecure { - background-image: url("../../img/refresh-assets/Error-Color-16.svg"); -} - -.search { - display: flex; - align-items: center; - padding: 8px; - background: #ffffff; - height: 56px; -} -.body--theme-dark .search { - background-color: #333333; -} - -.search-form { - flex: 1; - display: flex; - margin-right: 8px; -} - -.search-form__input { - -moz-appearance: none; - outline: medium none; - border: medium none; - padding-left: 46px; - z-index: 1; - color: #333333; - height: 40px; - background-color: #eee; - background-image: url("../../img/logo-small-new.svg"); - background-repeat: no-repeat; - background-position: 10px 8px; - background-size: 24px; - border-radius: 10px 0 0 10px; - flex-grow: 1; -} -.body--theme-dark .search-form__input { - background-color: rgba(255, 255, 255, 0.12); -} -.search-form__input::placeholder { - color: #999999; -} - -.search-form__go { - display: flex; - align-items: center; - justify-content: center; - background-color: #eee; - height: 40px; - width: 42px; - padding: 0 0.64em; - min-height: 1.8em; - -moz-appearance: none; - cursor: pointer; - text-align: center; - border: medium none; - outline: medium none; - z-index: 2; - border-radius: 0 10px 10px 0; -} -.search-form__go svg { - position: relative; - top: -1px; - left: -1px; -} -.search-form__go .loupe-handle { - fill: currentColor; - opacity: 0.8; -} -.search-form__go .loupe-glass { - stroke: currentColor; - opacity: 0.8; -} -.body--theme-dark .search-form__go { - background-color: rgba(255, 255, 255, 0.12); -} -.body--theme-dark .search-form__go:hover, .body--theme-dark .search-form__go:focus { - background-color: rgba(255, 255, 255, 0.2); -} -.search-form__go:hover, .search-form__go:focus { - background-color: #2950bf; - color: white; -} -[data-focussed=true] .search-form__go, .search-form__go.go--focused { - background-color: #3969ef; - color: white; -} -[data-focussed=true] .search-form__go:hover, [data-focussed=true] .search-form__go:focus, .search-form__go.go--focused:hover, .search-form__go.go--focused:focus { - background-color: #2950bf; -} - -/* cog-button */ -.cog-button { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - background-position: center; - background-repeat: no-repeat; - background-color: transparent; - border-radius: 3px; -} -.cog-button:hover, .cog-button:active, .cog-button:focus { - background-color: #eee; -} -.body--theme-dark .cog-button:hover, .body--theme-dark .cog-button:active, .body--theme-dark .cog-button:focus { - background-color: #444; -} -.cog-button .settings-cog { - fill: black; -} -.body--theme-dark .cog-button .settings-cog { - fill: white; - opacity: 0.8; -} - -.fire-button { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - background-position: center; - background-repeat: no-repeat; - background-color: transparent; - border-radius: 3px; -} -.fire-button:hover, .fire-button:active, .fire-button:focus { - background-color: #eee; -} -.body--theme-dark .fire-button:hover, .body--theme-dark .fire-button:active, .body--theme-dark .fire-button:focus { - background-color: #444; -} -.fire-button .fire-icon { - fill: black; -} -.body--theme-dark .fire-button .fire-icon { - fill: white; - opacity: 0.8; -} - -.large-icon-container { - height: 96px; - background-position: center center; - background-repeat: no-repeat; - margin-bottom: 24px; - background-size: contain; -} - -.medium-icon-container { - height: 72px; - background-position: center center; - background-repeat: no-repeat; - margin-bottom: 16px; - background-size: contain; -} - -.hero-icon--breakage-form { - background-image: url("../../img/refresh-assets/Breakage-128.svg"); - margin-bottom: 20px; -} -.environment--browser .hero-icon--breakage-form { - margin-bottom: 16px; -} - -.hero-icon--toggle-report { - background-image: url("../../img/refresh-assets/Breakage-128.svg"); - margin-bottom: 0; -} - -.hero-icon--toggle-report-sent { - background-image: url("../../img/refresh-assets/breakage-sent.svg"); -} - -.hero-icon--tracker-network { - background-image: url("../../img/refresh-assets/Network-128.svg"); -} - -.hero-icon--insecure-connection, -.hero-icon--trackers-blocked, -.hero-icon--connection-none, -.hero-icon--connection-invalid { - background-image: url("../../img/refresh-assets/Unlocked-128.svg"); -} - -.hero-icon--major-networks-blocked { - background-image: url("../../img/refresh-assets/Shield-128.svg"); -} - -.hero-icon--protections-off, -.hero-icon--major-networks-warning, -.hero-icon--major-networks-protections-off { - background-image: url("../../img/refresh-assets/Block-Disabled-128.svg"); -} - -.hero-icon--info, -.hero-icon--major-networks-info { - background-image: url("../../img/refresh-assets/Block-Info-128.svg"); -} - -.hero-icon--no-activity, -.hero-icon--major-networks-no-activity { - background-image: url("../../img/refresh-assets/Counter-128.svg"); -} - -.hero-icon--connection-secure, -.hero-icon--connection-upgraded { - background-image: url("../../img/refresh-assets/Locked-128.svg"); -} - -.hero-icon--cookies-managed { - background-image: url("../../img/refresh-assets/Cookies-Managed-128.svg"); -} - -.hero-icon--cookies-hidden { - background-image: url("../../img/refresh-assets/Cookies-Hidden-128.svg"); -} - -.hero-icon--phishing, -.hero-icon--connection-phishing { - background-image: url("../../img/refresh-assets/Phishing-128.svg"); -} - -.hero-icon--chat { - background-image: url("../../img/refresh-assets/chat-private-128.svg"); -} - -.hero-icon--switch-shield { - background-image: url("../../img/refresh-assets/switch-shield-128.svg"); -} - -.key-insight { - position: relative; - padding-bottom: 24px; - text-align: center; -} -.key-insight[data-suffix=about-link] { - padding-bottom: 12px; -} -.environment--browser .key-insight { - background-color: transparent; -} -.environment--ios .key-insight { - padding-top: 6px; -} -.key-insight .token-title-3-em { - margin-bottom: 8px; -} - -.key-insight__icon { - height: 96px; - background-position: center center; - background-repeat: no-repeat; - margin-bottom: 24px; - background-size: contain; -} -.environment--macos .key-insight__icon { - margin-bottom: 20px; -} -.environment--windows .key-insight__icon { - margin-bottom: 20px; -} -.environment--browser .key-insight__icon { - margin-bottom: 12px; -} - -.environment--macos .key-insight--main { - padding-bottom: 20px; -} -.environment--windows .key-insight--main { - padding-bottom: 20px; -} -.environment--browser .key-insight--main { - padding-bottom: 12px; -} - -.key-insight--breakage { - padding-bottom: 20px; -} -.environment--browser .key-insight--breakage { - padding-bottom: 16px; -} -.environment--windows .key-insight--breakage { - padding-bottom: 12px; -} - -body { - --nav-height: 56px; -} -body.environment--macos, body.environment--browser, body.environment--windows, body.environment--example { - --nav-height: var(--size-unit-double); -} - -.top-nav { - text-align: center; - position: fixed; - z-index: 1; - width: 100%; - height: var(--nav-height); - background: var(--page-bg); -} - -.top-nav__spacer { - height: var(--nav-height); -} - -.top-nav__back { - position: absolute; - padding: var(--size-unit-half); - left: var(--size-unit-half); - top: 50%; - transform: translateY(-50%); - display: flex; - color: var(--color-text-primary); -} -.top-nav__back:hover, .top-nav__back:focus, .top-nav__back:active { - text-decoration: none; -} -.environment--android .top-nav__back { - border-radius: 100%; - left: 10px; -} -.environment--ios .top-nav__back { - font-size: 17px; - font-weight: 400; - left: 0; -} -.environment--ios .top-nav__back:active { - opacity: 0.5; -} -.environment--macos .top-nav__back, .environment--browser .top-nav__back, .environment--windows .top-nav__back, .environment--example .top-nav__back { - border-radius: 0; - bottom: 0; - padding: 0; - height: 32px; - width: 32px; -} -.environment--macos .top-nav__back .icon, .environment--browser .top-nav__back .icon, .environment--windows .top-nav__back .icon, .environment--example .top-nav__back .icon { - position: absolute; - left: 50%; - transform: translateX(-50%) translateY(100%); - width: 15px; - height: 15px; -} - -.top-nav__done { - position: absolute; - padding: 0 var(--size-unit-half); - right: var(--size-unit-half); - height: var(--nav-height); - line-height: var(--nav-height); - color: var(--color-text-primary); -} -.top-nav__done:hover, .top-nav__done:focus, .top-nav__done:active { - text-decoration: none; -} -.environment--ios .top-nav__done { - font-size: 17px; - font-weight: 600; - font-weight: 600; -} -.environment--ios .top-nav__done:active { - opacity: 0.5; -} -.environment--macos .top-nav__done { - height: auto; - line-height: normal; - bottom: 0; -} - -.top-nav__cancel { - position: absolute; - padding: 0 var(--size-unit-half); - right: var(--size-unit-half); - height: var(--nav-height); - line-height: var(--nav-height); - color: var(--color-text-primary); -} -.top-nav__cancel:hover, .top-nav__cancel:focus, .top-nav__cancel:active { - text-decoration: none; -} -.environment--ios .top-nav__cancel { - font-size: 17px; -} -.environment--ios .top-nav__cancel:active { - opacity: 0.5; -} - -.top-nav__title { - position: absolute; - height: var(--nav-height); - line-height: 1.1; - color: var(--color-text-primary); - left: 50%; - transform: translateX(-50%); - display: flex; - align-items: center; -} -.environment--ios .top-nav__title { - font-size: 17px; - font-weight: 600; -} -.environment--ios .top-nav__title:active { - opacity: 0.5; -} -.environment--android .top-nav__title { - transform: unset; - left: 72px; - top: 2px; - font-size: 20px; - font-weight: 500; -} -.environment--android .top-nav__title:active { - opacity: 0.5; -} - -.status-list--right .status-list__item { - padding-left: 0; - padding-right: 40px; -} -.status-list--right .status-list__item:before { - left: auto; - right: 0; -} - -.status-list__item { - padding-left: 40px; - list-style-type: none; - line-height: 22px; - margin-bottom: 23px; -} -.status-list__item:last-child { - margin-bottom: 0; -} -.status-list__item:before { - content: ""; - position: absolute; - left: 0; - height: 20px; - width: 23px; - top: -1px; - background-repeat: no-repeat; - background-position-y: center; - min-height: 22px; - max-height: 30px; -} - -.status-list__item--good:before { - background-image: url("../../img/status--good.svg"); -} - -.status-list__item--bad:before { - background-image: url("../../img/status--bad.svg"); -} - -.status-list__item--mixed:before { - background-image: url("../../img/status--mixed.svg"); -} - -/* privacy practices uses the modifier 'poor' */ -.status-list__item--poor:before { - background-image: url("../../img/status--bad.svg"); -} - -.icon-list { - position: relative; - display: flex; - justify-content: center; -} - -.icon-list__item { - display: flex; - align-items: center; -} - -.icon-list__count { - display: inline-block; - letter-spacing: -0.7px; -} - -.icon-list__icon { - border-radius: 50%; - overflow: hidden; - background-size: contain; - margin: 0; - width: 20px; - height: 20px; -} -.icon-list__icon.color-1 { - background-color: #94b3af; -} -.icon-list__icon.color-2 { - background-color: #727998; -} -.icon-list__icon.color-3 { - background-color: #645468; -} -.icon-list__icon.color-4 { - background-color: #4d5f7f; -} -.icon-list__icon.color-5 { - background-color: #855db6; -} -.icon-list__icon.color-6 { - background-color: #5e5adb; -} -.icon-list__icon.color-7 { - background-color: #678fff; -} -.icon-list__icon.color-8 { - background-color: #6bb4ef; -} -.icon-list__icon.color-9 { - background-color: #4a9bae; -} -.icon-list__icon.color-10 { - background-color: #66c4c6; -} -.icon-list__icon.color-11 { - background-color: #55d388; -} -.icon-list__icon.color-12 { - background-color: #99db7a; -} -.icon-list__icon.color-13 { - background-color: #eccc7b; -} -.icon-list__icon.color-14 { - background-color: #e7a538; -} -.icon-list__icon.color-15 { - background-color: #dd6b4c; -} -.icon-list__icon.color-16 { - background-color: #d65d62; -} -.icon-list__icon.A { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/A.svg"); -} -.icon-list__icon.B { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/B.svg"); -} -.icon-list__icon.C { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/C.svg"); -} -.icon-list__icon.D { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/D.svg"); -} -.icon-list__icon.E { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/E.svg"); -} -.icon-list__icon.F { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/F.svg"); -} -.icon-list__icon.G { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/G.svg"); -} -.icon-list__icon.H { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/H.svg"); -} -.icon-list__icon.I { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/I.svg"); -} -.icon-list__icon.J { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/J.svg"); -} -.icon-list__icon.K { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/K.svg"); -} -.icon-list__icon.L { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/L.svg"); -} -.icon-list__icon.M { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/M.svg"); -} -.icon-list__icon.N { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/N.svg"); -} -.icon-list__icon.O { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/O.svg"); -} -.icon-list__icon.P { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/P.svg"); -} -.icon-list__icon.Q { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Q.svg"); -} -.icon-list__icon.R { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/R.svg"); -} -.icon-list__icon.S { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/S.svg"); -} -.icon-list__icon.T { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/T.svg"); -} -.icon-list__icon.U { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/U.svg"); -} -.icon-list__icon.V { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/V.svg"); -} -.icon-list__icon.W { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/W.svg"); -} -.icon-list__icon.X { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/X.svg"); -} -.icon-list__icon.Y { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Y.svg"); -} -.icon-list__icon.Z { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Z.svg"); -} -.icon-list__icon.adjust { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adjust.svg"); - background-color: transparent; -} -.icon-list__icon.adobe { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adobe.svg"); - background-color: transparent; -} -.icon-list__icon.amazon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amazon.svg"); - background-color: transparent; -} -.icon-list__icon.amplitude { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amplitude.svg"); - background-color: transparent; -} -.icon-list__icon.appnexus { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appnexus.svg"); - background-color: transparent; -} -.icon-list__icon.appsflyer { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appsflyer.svg"); - background-color: transparent; -} -.icon-list__icon.beeswax { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/beeswax.svg"); - background-color: transparent; -} -.icon-list__icon.branchmetrics { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/branchmetrics.svg"); - background-color: transparent; -} -.icon-list__icon.braze { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/braze.svg"); - background-color: transparent; -} -.icon-list__icon.bugsnag { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/bugsnag.svg"); - background-color: transparent; -} -.icon-list__icon.chartbeat { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/chartbeat.svg"); - background-color: transparent; -} -.icon-list__icon.comscore { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/comscore.svg"); - background-color: transparent; -} -.icon-list__icon.criteo { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/criteo.svg"); - background-color: transparent; -} -.icon-list__icon.facebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/facebook.svg"); - background-color: transparent; -} -.icon-list__icon.google { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/google.svg"); - background-color: transparent; -} -.icon-list__icon.googleadsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg"); - background-color: transparent; -} -.icon-list__icon.googleanalyticsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg"); - background-color: transparent; -} -.icon-list__icon.indexexchange { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/indexexchange.svg"); - background-color: transparent; -} -.icon-list__icon.iponweb { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/iponweb.svg"); - background-color: transparent; -} -.icon-list__icon.instagramfacebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/instagramfacebook.svg"); - background-color: transparent; -} -.icon-list__icon.kochava { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/kochava.svg"); - background-color: transparent; -} -.icon-list__icon.linkedin { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/linkedin.svg"); - background-color: transparent; -} -.icon-list__icon.liveramp { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/liveramp.svg"); - background-color: transparent; -} -.icon-list__icon.mediamath { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mediamath.svg"); - background-color: transparent; -} -.icon-list__icon.microsoft { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/microsoft.svg"); - background-color: transparent; -} -.icon-list__icon.mixpanel { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mixpanel.svg"); - background-color: transparent; -} -.icon-list__icon.neustar { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/neustar.svg"); - background-color: transparent; -} -.icon-list__icon.newrelic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/newrelic.svg"); - background-color: transparent; -} -.icon-list__icon.openx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/openx.svg"); - background-color: transparent; -} -.icon-list__icon.oracle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/oracle.svg"); - background-color: transparent; -} -.icon-list__icon.outbrain { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/outbrain.svg"); - background-color: transparent; -} -.icon-list__icon.pinterest { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pinterest.svg"); - background-color: transparent; -} -.icon-list__icon.pubmatic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pubmatic.svg"); - background-color: transparent; -} -.icon-list__icon.quantcast { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/quantcast.svg"); - background-color: transparent; -} -.icon-list__icon.magnite { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/magnite.svg"); - background-color: transparent; -} -.icon-list__icon.rythmone { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/rythmone.svg"); - background-color: transparent; -} -.icon-list__icon.salesforce { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/salesforce.svg"); - background-color: transparent; -} -.icon-list__icon.sharetrough { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/sharetrough.svg"); - background-color: transparent; -} -.icon-list__icon.smaato { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/smaato.svg"); - background-color: transparent; -} -.icon-list__icon.spotx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/spotx.svg"); - background-color: transparent; -} -.icon-list__icon.taboola { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/taboola.svg"); - background-color: transparent; -} -.icon-list__icon.tapad { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/tapad.svg"); - background-color: transparent; -} -.icon-list__icon.thenielsencompany { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thenielsencompany.svg"); - background-color: transparent; -} -.icon-list__icon.thetradedesk { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thetradedesk.svg"); - background-color: transparent; -} -.icon-list__icon.twitter { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/twitter.svg"); - background-color: transparent; -} -.icon-list__icon.urbanairship { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/urbanairship.svg"); - background-color: transparent; -} -.icon-list__icon.verizonmedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/verizonmedia.svg"); - background-color: transparent; -} -.icon-list__icon.warnermedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/warnermedia.svg"); - background-color: transparent; -} -.icon-list__icon.xaxis { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/xaxis.svg"); - background-color: transparent; -} -.icon-list__icon.yahoojapan { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yahoojapan.svg"); - background-color: transparent; -} -.icon-list__icon.yandex { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yandex.svg"); - background-color: transparent; -} -.icon-list__icon.youtubegoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/youtubegoogle.svg"); - background-color: transparent; -} -.icon-list__icon.zeotap { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/zeotap.svg"); - background-color: transparent; -} - -.icon-list__blocked-icon { - border-radius: 100%; - position: absolute; -} -.icon-list__blocked-icon svg path { - shape-rendering: geometricPrecision; -} -.icon-list__blocked-icon svg circle { - shape-rendering: geometricPrecision; -} -.body--theme-dark .icon-list__blocked-icon circle { - fill: #222; -} - -[data-company-icon-position]:nth-child(n+2):nth-child(odd) { - margin-left: -8px; -} - -[data-company-icon-position]:nth-child(n+2):nth-child(even) { - margin-right: -8px; -} - -[data-company-icon-size=large] { - z-index: 4; - display: block; - box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.1), 0px 4px 8px rgba(0, 0, 0, 0.08); - height: 96px; - width: 96px; -} -[data-company-icon-size=large] .icon-list__icon { - margin: 0; - width: 64px; - height: 64px; -} -[data-company-icon-size=large] .icon-list__blocked-icon { - bottom: 14px; - right: 14px; - width: 30px; - height: 30px; -} -.environment--browser [data-company-icon-size=large] .icon-list__blocked-icon { - bottom: 10px; - right: 10px; -} - -[data-company-icon-size=medium] { - z-index: 3; - box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.08), 0px 2px 4px rgba(0, 0, 0, 0.1); - height: 64px; - width: 64px; -} -[data-company-icon-size=medium] .icon-list__icon { - margin: 0; - width: 32px; - height: 32px; -} -[data-company-icon-size=medium] .icon-list__blocked-icon { - width: 24px; - height: 24px; - bottom: 8px; - right: 8px; -} - -[data-company-icon-size=small] { - z-index: 2; - border: 1px solid #f2f2f2; - box-shadow: 0px 1px 0px rgba(125, 125, 125, 0.06); - height: 48px; - width: 48px; -} -[data-company-icon-size=small] .icon-list__icon { - margin: 0; - width: 20px; - height: 20px; -} -[data-company-icon-size=small] .icon-list__blocked-icon { - width: 24px; - height: 24px; - bottom: 3px; - right: 3px; -} - -.icon-list__wrapper { - background-color: #ffffff; - border-radius: 50%; - position: relative; - display: flex; - color: rgba(0, 0, 0, 0.85); - align-items: center; - justify-content: center; -} -.body--theme-dark .icon-list__wrapper { - background-color: #222; - border-color: #222; - color: rgba(255, 255, 255, 0.85); -} - -.icon-list__wrapper--count { - border: 1px solid var(--color-lines-light); - height: 46px; - width: 46px; - background: #fafafa; - font-size: 16px; -} - -.tracker-networks__explainer { - padding: 0 32px 0; -} -.tracker-networks__explainer .about-link { - display: block; - padding-top: 8px; - margin-bottom: 20px; -} - -.section-list-header { - color: var(--color-text-secondary); - padding: 12px 0; - text-align: center; - border-top: 1px solid var(--color-lines-light); - border-bottom: 1px solid var(--color-lines-light); -} -.section-list-header[data-section-name=adAttribution] { - padding-bottom: 4px; -} - -.icon-major-networks-blocked { - background-image: url("../../img/refresh-assets/Check-Color-16.svg"); -} - -.icon-major-networks-warning { - background-image: url("../../img/refresh-assets/Error-Color-16.svg"); -} - -.icon-major-networks-info { - background-image: url("../../img/status--info.svg"); -} - -.icon-major-networks-mixed { - background-image: url("../../img/refresh-assets/Stop-Grey-16.svg"); -} - -.site-info__tracker__icon { - border-radius: 50%; - overflow: hidden; - background-size: contain; - margin-right: 8px; -} -.site-info__tracker__icon.color-1 { - background-color: #94b3af; -} -.site-info__tracker__icon.color-2 { - background-color: #727998; -} -.site-info__tracker__icon.color-3 { - background-color: #645468; -} -.site-info__tracker__icon.color-4 { - background-color: #4d5f7f; -} -.site-info__tracker__icon.color-5 { - background-color: #855db6; -} -.site-info__tracker__icon.color-6 { - background-color: #5e5adb; -} -.site-info__tracker__icon.color-7 { - background-color: #678fff; -} -.site-info__tracker__icon.color-8 { - background-color: #6bb4ef; -} -.site-info__tracker__icon.color-9 { - background-color: #4a9bae; -} -.site-info__tracker__icon.color-10 { - background-color: #66c4c6; -} -.site-info__tracker__icon.color-11 { - background-color: #55d388; -} -.site-info__tracker__icon.color-12 { - background-color: #99db7a; -} -.site-info__tracker__icon.color-13 { - background-color: #eccc7b; -} -.site-info__tracker__icon.color-14 { - background-color: #e7a538; -} -.site-info__tracker__icon.color-15 { - background-color: #dd6b4c; -} -.site-info__tracker__icon.color-16 { - background-color: #d65d62; -} -.site-info__tracker__icon.A { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/A.svg"); -} -.site-info__tracker__icon.B { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/B.svg"); -} -.site-info__tracker__icon.C { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/C.svg"); -} -.site-info__tracker__icon.D { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/D.svg"); -} -.site-info__tracker__icon.E { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/E.svg"); -} -.site-info__tracker__icon.F { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/F.svg"); -} -.site-info__tracker__icon.G { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/G.svg"); -} -.site-info__tracker__icon.H { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/H.svg"); -} -.site-info__tracker__icon.I { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/I.svg"); -} -.site-info__tracker__icon.J { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/J.svg"); -} -.site-info__tracker__icon.K { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/K.svg"); -} -.site-info__tracker__icon.L { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/L.svg"); -} -.site-info__tracker__icon.M { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/M.svg"); -} -.site-info__tracker__icon.N { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/N.svg"); -} -.site-info__tracker__icon.O { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/O.svg"); -} -.site-info__tracker__icon.P { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/P.svg"); -} -.site-info__tracker__icon.Q { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Q.svg"); -} -.site-info__tracker__icon.R { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/R.svg"); -} -.site-info__tracker__icon.S { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/S.svg"); -} -.site-info__tracker__icon.T { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/T.svg"); -} -.site-info__tracker__icon.U { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/U.svg"); -} -.site-info__tracker__icon.V { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/V.svg"); -} -.site-info__tracker__icon.W { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/W.svg"); -} -.site-info__tracker__icon.X { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/X.svg"); -} -.site-info__tracker__icon.Y { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Y.svg"); -} -.site-info__tracker__icon.Z { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Z.svg"); -} -.site-info__tracker__icon.adjust { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adjust.svg"); - background-color: transparent; -} -.site-info__tracker__icon.adobe { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adobe.svg"); - background-color: transparent; -} -.site-info__tracker__icon.amazon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amazon.svg"); - background-color: transparent; -} -.site-info__tracker__icon.amplitude { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amplitude.svg"); - background-color: transparent; -} -.site-info__tracker__icon.appnexus { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appnexus.svg"); - background-color: transparent; -} -.site-info__tracker__icon.appsflyer { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appsflyer.svg"); - background-color: transparent; -} -.site-info__tracker__icon.beeswax { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/beeswax.svg"); - background-color: transparent; -} -.site-info__tracker__icon.branchmetrics { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/branchmetrics.svg"); - background-color: transparent; -} -.site-info__tracker__icon.braze { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/braze.svg"); - background-color: transparent; -} -.site-info__tracker__icon.bugsnag { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/bugsnag.svg"); - background-color: transparent; -} -.site-info__tracker__icon.chartbeat { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/chartbeat.svg"); - background-color: transparent; -} -.site-info__tracker__icon.comscore { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/comscore.svg"); - background-color: transparent; -} -.site-info__tracker__icon.criteo { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/criteo.svg"); - background-color: transparent; -} -.site-info__tracker__icon.facebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/facebook.svg"); - background-color: transparent; -} -.site-info__tracker__icon.google { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/google.svg"); - background-color: transparent; -} -.site-info__tracker__icon.googleadsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.googleanalyticsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.indexexchange { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/indexexchange.svg"); - background-color: transparent; -} -.site-info__tracker__icon.iponweb { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/iponweb.svg"); - background-color: transparent; -} -.site-info__tracker__icon.instagramfacebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/instagramfacebook.svg"); - background-color: transparent; -} -.site-info__tracker__icon.kochava { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/kochava.svg"); - background-color: transparent; -} -.site-info__tracker__icon.linkedin { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/linkedin.svg"); - background-color: transparent; -} -.site-info__tracker__icon.liveramp { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/liveramp.svg"); - background-color: transparent; -} -.site-info__tracker__icon.mediamath { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mediamath.svg"); - background-color: transparent; -} -.site-info__tracker__icon.microsoft { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/microsoft.svg"); - background-color: transparent; -} -.site-info__tracker__icon.mixpanel { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mixpanel.svg"); - background-color: transparent; -} -.site-info__tracker__icon.neustar { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/neustar.svg"); - background-color: transparent; -} -.site-info__tracker__icon.newrelic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/newrelic.svg"); - background-color: transparent; -} -.site-info__tracker__icon.openx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/openx.svg"); - background-color: transparent; -} -.site-info__tracker__icon.oracle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/oracle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.outbrain { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/outbrain.svg"); - background-color: transparent; -} -.site-info__tracker__icon.pinterest { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pinterest.svg"); - background-color: transparent; -} -.site-info__tracker__icon.pubmatic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pubmatic.svg"); - background-color: transparent; -} -.site-info__tracker__icon.quantcast { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/quantcast.svg"); - background-color: transparent; -} -.site-info__tracker__icon.magnite { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/magnite.svg"); - background-color: transparent; -} -.site-info__tracker__icon.rythmone { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/rythmone.svg"); - background-color: transparent; -} -.site-info__tracker__icon.salesforce { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/salesforce.svg"); - background-color: transparent; -} -.site-info__tracker__icon.sharetrough { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/sharetrough.svg"); - background-color: transparent; -} -.site-info__tracker__icon.smaato { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/smaato.svg"); - background-color: transparent; -} -.site-info__tracker__icon.spotx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/spotx.svg"); - background-color: transparent; -} -.site-info__tracker__icon.taboola { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/taboola.svg"); - background-color: transparent; -} -.site-info__tracker__icon.tapad { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/tapad.svg"); - background-color: transparent; -} -.site-info__tracker__icon.thenielsencompany { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thenielsencompany.svg"); - background-color: transparent; -} -.site-info__tracker__icon.thetradedesk { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thetradedesk.svg"); - background-color: transparent; -} -.site-info__tracker__icon.twitter { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/twitter.svg"); - background-color: transparent; -} -.site-info__tracker__icon.urbanairship { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/urbanairship.svg"); - background-color: transparent; -} -.site-info__tracker__icon.verizonmedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/verizonmedia.svg"); - background-color: transparent; -} -.site-info__tracker__icon.warnermedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/warnermedia.svg"); - background-color: transparent; -} -.site-info__tracker__icon.xaxis { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/xaxis.svg"); - background-color: transparent; -} -.site-info__tracker__icon.yahoojapan { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yahoojapan.svg"); - background-color: transparent; -} -.site-info__tracker__icon.yandex { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yandex.svg"); - background-color: transparent; -} -.site-info__tracker__icon.youtubegoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/youtubegoogle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.zeotap { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/zeotap.svg"); - background-color: transparent; -} - -.site-info__tracker__icon--company { - width: 24px !important; - height: 24px !important; - flex-shrink: 0; -} - -.site-info__domain { - overflow: hidden; - text-overflow: ellipsis; - padding-right: 12px; - display: flex; - align-items: center; -} - -.site-info__trackers__company-list--bordered { - border-top: 1px solid var(--color-lines-light); -} - -.site-info__trackers__company-list-item { - margin-top: 16px; - margin-bottom: 16px; -} - -.site-info__trackers__company-list-item + .site-info__trackers__company-list-item { - padding-top: 16px; - border-top: 1px solid var(--color-lines-lighter); -} -.body--theme-dark .site-info__trackers__company-list-item + .site-info__trackers__company-list-item { - border-top: 1px solid rgba(255, 255, 255, 0.06); -} - -.site-info__trackers__company-list__url-list .url-list-item { - display: flex; - margin-top: 8px; - align-items: baseline; -} -.site-info__trackers__company-list__url-list .url { - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - direction: rtl; - padding-right: 10px; - line-height: 18px; -} -.site-info__trackers__company-list__url-list .category { - padding: 1px 8px; - border-radius: 33px; - color: var(--color-text-secondary); - background-color: var(--color-lines-lighter); - white-space: nowrap; - text-align: right; -} - -.page-connection__certificate-value { - text-align: right; - color: #666; -} -.body--theme-dark .page-connection__certificate-value { - color: #aaa; -} - -.page-connection__certificate-details { - padding: 18px 0; -} -.page-connection__certificate-details h3 { - color: #111111; - margin-bottom: 14px; -} -.body--theme-dark .page-connection__certificate-details h3 { - color: rgba(255, 255, 255, 0.9); -} -.page-connection__certificate-details > div { - color: #333333; - display: flex; - margin-top: 6px; - justify-content: space-between; -} -.body--theme-dark .page-connection__certificate-details > div { - color: rgba(255, 255, 255, 0.9); -} -.page-connection__certificate-details + .page-connection__certificate-details { - border-top: 1px solid var(--color-lines-lighter); -} -.body--theme-dark .page-connection__certificate-details + .page-connection__certificate-details { - border-top: 1px solid var(--color-lines-lighter); -} - -.environment--browser .breakage-form { - padding-bottom: 0; -} - -.breakage-form__content { - z-index: 1; - position: relative; - text-align: center; -} -[data-state=sent] .breakage-form__content { - display: none; -} - -.breakage-form__close-container { - top: 13px; - right: 15px; - position: absolute; -} - -.form__icon--wrapper { - padding-bottom: 5px; - margin: 0 20px; - position: relative; -} - -.breakage-form__element { - display: flex; - flex-direction: column; - gap: 24px; - opacity: 1; - transition: all 0.2s ease-in-out; -} -.breakage-form__element.is-transparent { - opacity: 0; - max-height: 0; - overflow: hidden; -} - -.breakage-form__title { - padding: 5px 0 0; -} - -.breakage-form__advise { - display: none; -} -[data-state=idle] .breakage-form__advise { - display: block; -} - -.form__label__select { - display: block; - text-align: left; -} - -.form__group { - display: flex; - flex-direction: column; - gap: 16px; -} - -.form__select { - width: 100%; -} - -.form__select select { - cursor: pointer; - display: block; - width: 100%; - min-height: 20px; - border: 1px solid var(--color-lines-light); - border-radius: 4px; -} -.environment--ios .form__select select { - height: 34px; -} -.environment--windows .form__select select { - min-height: 34px; -} - -.form__textarea { - resize: none; - width: 100%; - height: 88px; - display: block; - box-sizing: border-box; - padding: var(--size-unit-half) var(--size-unit); - border: 1px solid var(--color-lines-light); - border-radius: 4px; - font-size: 13px; - line-height: 16px; -} -.form__textarea::placeholder { - color: rgba(0, 0, 0, 0.6); -} -.body--theme-dark .form__textarea { - background-color: rgba(255, 255, 255, 0.12); - border-color: var(--color-lines-light); -} -.body--theme-dark .form__textarea::placeholder { - color: rgba(255, 255, 255, 0.6); -} -.environment--macos .form__textarea { - height: 102px; -} -.environment--windows .form__textarea { - height: 102px; - line-height: 20px; -} - -.form__submit { - text-align: center; - padding: 10px 12px; - cursor: pointer; - display: block; - text-decoration: none; - width: 100%; - box-shadow: var(--btn-accent-shadow); - border-radius: var(--btn-accent-border-radius); - border: var(--btn-accent-border); - color: var(--btn-accent-color); - background: var(--btn-accent-bg); - /* https://www.figma.com/file/DBZiXJRgTTJTuBeWAPyE5h/Desktop-Components?node-id=9113%3A130956&t=de8DMDVt8GbRBQub-0 */ -} -.form__submit:hover { - background: var(--btn-accent-bg-hover); -} -.form__submit:active { - background: var(--btn-accent-bg-active); -} -.environment--windows .form__submit { - /* Windows/Label */ - box-shadow: none; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 19px; - border-radius: 4px; -} -.environment--windows .form__submit:focus { - /* todo(Shane): where does this live? */ - box-shadow: 0px 0px 0px 1px #ffffff, 0px 0px 0px 3px #3969ef; -} -.environment--windows .form__submit:active { - box-shadow: none; -} - -.breakage-form__footer { - padding-bottom: 24px; - padding-top: 24px; - text-align: center; -} -.body--theme-dark .breakage-form__footer { - color: rgba(255, 255, 255, 0.5); -} -.environment--browser .breakage-form__footer { - margin-top: auto; -} -[data-state=sent] .breakage-form__footer { - display: none; -} - -.breakage-form__inner { - height: calc(100% - var(--nav-height)); - display: flex; - flex-direction: column; -} - -.thanks { - text-align: center; - padding-bottom: 20px; - transition: all 0.2s ease-in-out; - opacity: 1; - display: none; -} -[data-state=sent] .thanks { - display: block; -} - -.thanks__primary { - font-size: 15px; - font-style: normal; - font-weight: 800; - line-height: 20px; /* 133.333% */ - margin-bottom: 8px; -} -.environment--macos .thanks__primary, .environment--macos .thanks__primary { - font-size: 17px; - font-style: normal; - font-weight: 600; - line-height: 22px; /* 129.412% */ -} - -.thanks__secondary { - font-size: 16px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} -.environment--macos .thanks__secondary { - font-size: 15px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} - -/* Android-specific styles */ -.environment--android { - --btn-accent-bg: #3969ef; - --btn-accent-bg-hover: #1e42a4; - --btn-accent-bg-active: #1e42a4; - --btn-accent-color: #fff; - --form-select-bg: none; - --form-select-color: rgba(0, 0, 0, 0.6); - --form-select-border-color: rgba(0, 0, 0, 0.3); - --form-select-chevron: url("../../img/refresh-assets/chevron.svg"); - /** - * prevent the empty element from taking any screen height - */ -} -.environment--android ddg-android-breakage-dialog { - position: absolute; -} -.environment--android .breakage-form .form__submit { - height: calc(var(--size-unit) * 3); -} -.environment--android .breakage-form .breakage-form__input--dropdown { - position: relative; -} -.environment--android .breakage-form .breakage-form__input--dropdown select { - appearance: none; - background: var(--form-select-bg); - border: 1px solid var(--form-select-border-color); - border-radius: var(--size-unit-half); - color: var(--form-select-color); - font-size: var(--size-unit); - padding: var(--size-unit); -} -.environment--android .breakage-form .breakage-form__input--dropdown::after { - content: ""; - position: absolute; - right: var(--size-unit); - top: calc(1.25 * var(--size-unit)); - background-image: var(--form-select-chevron); - width: 8px; - height: 14px; - transform: rotate(90deg); - opacity: 0.75; -} -.environment--android .breakage-form textarea { - border-radius: var(--size-unit-half); - border-color: var(--form-select-border-color); - font-size: var(--size-unit); - line-height: 1.25; - height: calc(var(--size-unit) * 7); - padding: var(--size-unit); - background: none; -} -.environment--android .breakage-form .breakage-form__content.padding-x-double { - padding-left: var(--size-unit); - padding-right: var(--size-unit); -} -.environment--android.body--theme-dark { - --btn-accent-bg: #7295f6; - --btn-accent-bg-hover: #3969ef; - --btn-accent-bg-active: #3969ef; - --btn-accent-color: rgba(0, 0, 0, 0.84); - --form-select-color: rgba(255, 255, 255, 0.9); - --form-select-border-color: rgba(255, 255, 255, 0.3); - --form-select-chevron: url("../../img/refresh-assets/chevron--light.svg"); -} - -.email-alias { - margin-bottom: var(--size-unit); -} - -.email-alias__button { - display: block; - padding: 5px 10px; - background: var(--color-lines-lighter); - border: 1px solid transparent; - width: 100%; - border-radius: 8px; - vertical-align: middle; -} -.email-alias__button svg { - vertical-align: middle; - position: relative; - top: -1px; - left: -4px; -} -.email-alias__button svg path { - fill: currentColor; -} -.email-alias__button:hover, .email-alias__button:focus, .email-alias__button:active { - background: var(--color-lines-light); -} -.email-alias__button[data-state=added] { - background: white; - border-color: var(--color-lines-lighter); -} -.body--theme-dark .email-alias__button { - border: 1px solid transparent; -} -.body--theme-dark .email-alias__button:hover, .body--theme-dark .email-alias__button:focus, .body--theme-dark .email-alias__button:active { - background: rgba(255, 255, 255, 0.25); -} -.body--theme-dark .email-alias__button[data-state=added] { - border: 1px solid rgba(255, 255, 255, 0.18); - background: transparent; -} - -.cta-screen { - padding-top: 24px; -} - -.cta { - max-width: 85%; - margin: 0 auto; - margin-top: 32px; -} - -.cta__icon { - width: 100px; - height: 100px; - margin-left: auto; - margin-right: auto; - display: flex; - justify-content: center; - align-items: center; -} - -.cta__title { - font-size: 16px; - line-height: 20px; - margin-top: 14px; -} - -.cta__text { - font-size: 16px; - line-height: 22px; - font-weight: normal; - margin-top: 2px; -} - -.cta__action { - text-align: center; - margin-top: 22px; -} - -.cta__button { - display: inline-block; - background: var(--color-accent-blue); - border-radius: 8px; - padding: 10px 16px; - max-width: 250px; - font-style: normal; - font-weight: 600; - font-size: 13px; - line-height: 14px; - color: #ffffff; -} -.cta__button:hover, .cta__button:focus { - background-color: #2950bf; - text-decoration: none; -} -.body--theme-dark .cta__button { - color: #222222; -} -.body--theme-dark .cta__button:hover, .body--theme-dark .cta__button:focus { - background-color: #4271f3; - text-decoration: none; -} - -.note { - background: #fff0c2; - border-radius: 12px; - padding: 12px 16px; -} -.body--theme-dark .note { - background: rgba(255, 222, 122, 0.18); -} - -.note--nested { - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.note--nested--alt { - background: #ccdaff; -} -.body--theme-dark .note--nested--alt { - background: rgba(85, 127, 243, 0.18); -} - -.note--key-insight { - margin-top: 12px; - margin-left: -16px; - margin-right: -16px; -} - -#fire-button-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 100; - background-color: rgba(0, 0, 0, 0.6); - border: 0px; - color: rgba(0, 0, 0, 0.84); -} -.body--theme-dark #fire-button-container { - color: rgba(255, 255, 255, 0.84); -} - -#fire-button-header { - font-weight: 600; - font-size: 17px; - text-align: center; - padding-bottom: 4px; -} - -#fire-button-content { - box-sizing: border-box; - /* Auto layout */ - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 16px; - gap: 12px; - background: #ffffff; - /* Tints-Shades/Shade 12% */ - border: 1px solid rgba(0, 0, 0, 0.12); - /* Shadows/On Light/Elevation 90 */ - box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1), 0px 20px 40px rgba(0, 0, 0, 0.08); - border-radius: 16px; -} -.body--theme-dark #fire-button-content { - background-color: #333333; - border: 1px solid rgba(255, 255, 255, 0.12); -} - -#fire-button-burn { - background: #3969ef; - color: #fff; - font-weight: 600; - font-size: 15px; - line-height: 16px; -} -.body--theme-dark #fire-button-burn { - background: #7295f6; - color: rgba(0, 0, 0, 0.84); -} -#fire-button-burn:hover { - background: #2b55ca; -} -#fire-button-burn:active { - background: #1e42a4; -} - -#fire-button-cancel { - font-weight: 600; - font-size: 15px; - line-height: 16px; - background-color: rgba(0, 0, 0, 0.06); -} -.body--theme-dark #fire-button-cancel { - background-color: rgba(0, 0, 0, 0.18); -} -.body--theme-dark #fire-button-cancel:hover { - background: rgba(0, 0, 0, 0.09); -} -#fire-button-cancel:hover { - background: rgba(0, 0, 0, 0.03); -} -#fire-button-cancel:active { - background: rgba(0, 0, 0, 0.06); -} - -#fire-button-row { - display: flex; - justify-content: center; - align-items: center; - gap: 12px; - align-self: stretch; -} - -#fire-button-row > button { - display: flex; - height: 40px; - justify-content: center; - align-items: center; - gap: 10px; - flex: 1 0 0; - border-radius: 8px; -} - -#fire-button-summary { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 12px; - padding-top: 4px; - padding-bottom: 4px; -} - -#fire-button-summary .fire-button-disclaimer { - font-size: 15px; -} - -#fire-button-summary p { - text-align: center; - font-weight: 400; - font-size: 15px; - line-height: 22px; -} - -#fire-button-opts { - width: 100%; - height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - border-radius: 8px; - display: inline-block; - position: relative; - overflow: hidden; - line-height: 2.2; - border: 1px solid #ddd; - background-color: #fafafa; - color: #333; - padding: 0 32px 0 0.75em; - vertical-align: middle; - margin-bottom: 0; - cursor: pointer; - -webkit-appearance: none !important; - -moz-appearance: none !important; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACVSURBVHgB7dXtCYAgEMbxq0ZqjtZwqBZomVqgaepAQUTzzrcvPT8QP+TRHyEiAgAA+L3NrlFz6pecdhnFnPHmqiJnxVlDskjpOZEl8/y2+xrsV+J8GLe/66AKuUA/JhcZi9upkiTQj0lFdolj0kA/Zo3sXeLYRHpfH0HTOKa5QSe8Sad5HCsJZGFkl7gWhvwtAAAAyj31qB2UieFidQAAAABJRU5ErkJggg==); - background-position: 100%; - background-repeat: no-repeat; - background-size: 20px; -} -#fire-button-opts:hover { - background-color: #fff; -} -#fire-button-opts select { - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - -o-appearance: none; - appearance: none; - background: none; - cursor: pointer; - margin: 0; - padding: 0 32px 0 0.75em; - position: relative; - display: block; - font-size: 1em; - line-height: inherit; - min-width: 10em; - width: 140% !important; - height: 2.2em !important; - outline: none !important; - border: none !important; -} -@media (prefers-color-scheme: dark) { - #fire-button-opts { - border: 1px solid #444; - background-color: #333; - color: #fafafa; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACFSURBVHgB7dVdCoAgEATg3e7XNTxUZ+pOxoIPJf3suGYPzQcSxC6OoihCRET0bznn2YaAWvtaJlnLSEBf2vWFQk5AbfKELDXuxYRVu3G7k0jt8JCfhfMEeDOcIsUn52sp38M/VV2kEyigebgEXcMZOKC5CNk9XEh17sZeCK8hrwUREVHIBuQ4wvCLsemUAAAAAElFTkSuQmCC); - } - #fire-button-opts:hover { - background-color: #444; - } -} - -.protection-toggle__row { - padding: 12px; -} -.environment--browser .protection-toggle__row { - padding-top: 11px; - padding-bottom: 11px; -} -.environment--ios .protection-toggle__row { - padding: 8.5px 16px; - font-size: 15px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} -.environment--android .protection-toggle__row { - padding: 8.5px 16px; - font-size: 15px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} -.environment--windows .protection-toggle__row { - padding: 10px 16px; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 24px; -} -.environment--macos .protection-toggle__row { - padding-top: 13px; - padding-bottom: 13px; -} - -.protection-toggle__row--alt { - background: #ccdaff; -} -.body--theme-dark .protection-toggle__row--alt { - background: rgba(85, 127, 243, 0.18); -} -.environment--ios .protection-toggle__row--alt { - padding: 12px 16px; -} -.environment--android .protection-toggle__row--alt { - padding: 12px 16px; -} - -/* Generic menu list styling */ -.default-list { - list-style-type: none; - padding-left: 0; - margin-top: 0; -} -.default-list li .icon__arrow { - right: 15px; - top: calc(50% - 6px); -} -.environment--browser .default-list li .icon__arrow { - right: 10px; -} - -/* Sliding subviews */ -.sliding-subview { - position: absolute; - top: 0; - left: 100%; - width: 100%; - height: 100%; - box-sizing: border-box; -} -.sliding-subview.sliding-subview--root { - position: relative; - top: 0; - left: 0; - transition: left 0.3s ease-in-out; -} -.sliding-subview.sliding-subview--root.sliding-subview--immediate { - transition: none; -} -.sliding-subview.sliding-subview--root.sliding-subview--open { - left: -100%; -} - -/* Sliding subviews */ -.sliding-subview-v2 { - position: absolute; - top: 0; - width: var(--width); - height: var(--height); - box-sizing: border-box; -} -.sliding-subview-v2:not(.sliding-subview-v2--root) { - overflow-y: auto; -} - -.sliding-subview-v2--root { - position: absolute; - top: 0; - left: 0; -} - -.sliding-subview-v2--animating { - transition: transform 0.3s ease-in-out; -} - -.platform-limitations { - padding: 16px 0; - text-align: center; -} - -.button[data-size=small] { - line-height: 13px; - height: 20px; - padding: 0px 12px; - border-radius: 5px; -} -.button[data-size=big] { - height: 50px; - padding: 0px 24px; - /* Button */ - font-size: 15px; - font-style: normal; - font-weight: 600; - line-height: 20px; /* 133.333% */ -} -.button[data-size=desktop-large] { - height: 29px; - padding: 0px 12px; -} -.button[data-variant=desktop-standard] { - background: rgba(0, 0, 0, 0.06); - border-radius: 6px; - color: rgba(0, 0, 0, 0.84); -} -.button[data-variant=desktop-standard]:hover { - background: rgba(0, 0, 0, 0.09); -} -.button[data-variant=desktop-standard]:active { - background: rgba(0, 0, 0, 0.12); -} -.button[data-variant=desktop-standard]:disabled { - opacity: 0.8; -} -.body--theme-dark .button[data-variant=desktop-standard] { - background: rgba(255, 255, 255, 0.12); - color: rgba(255, 255, 255, 0.84); -} -.body--theme-dark .button[data-variant=desktop-standard]:hover { - background: rgba(255, 255, 255, 0.18); -} -.body--theme-dark .button[data-variant=desktop-standard]:active { - background: rgba(255, 255, 255, 0.24); -} -.button[data-variant=desktop-standard][data-size=desktop-large] { - font-size: 14px; - font-weight: 400; - height: 40px; - padding: 0 16px; -} -.button[data-variant=desktop-vibrancy] { - border-radius: 6px; - background: rgba(0, 0, 0, 0.1); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); -} -.button[data-variant=desktop-vibrancy]:active { - border-radius: 6px; - background: rgba(0, 0, 0, 0.2); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); -} -.body--theme-dark .button[data-variant=desktop-vibrancy] { - border-radius: 6px; - background: rgba(255, 255, 255, 0.28); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); -} -.body--theme-dark .button[data-variant=desktop-vibrancy]:active { - border-radius: 6px; - background: rgba(255, 255, 255, 0.35); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); -} -.button[data-variant=ios-secondary] { - justify-content: center; - align-items: center; - gap: 8px; - flex-shrink: 0; - border-radius: 8px; - border: 1px solid var(--color-accent-blue); - color: var(--color-accent-blue); - text-align: center; - background: transparent; -} -.button[data-variant=ios-secondary]:active { - background: rgba(57, 105, 239, 0.2); - color: var(--color-accent-blue-active); -} - -.button-bar[data-layout=horizontal] { - display: grid; - gap: 12px; - grid-template-columns: 1fr 1fr; -} -.button-bar[data-layout=vertical] { - display: flex; - gap: 12px; - flex-direction: column; -} -.button-bar[data-layout=vertical] > * { - width: 100%; -} -.environment--android .button-bar[data-layout=vertical] { - gap: 8px; -} - -.text-link-as-button:hover { - text-decoration: underline; -} -.text-link-as-button:active { - text-decoration: none; -} - -.stack { - display: flex; - flex-direction: column; - gap: 24px; - width: 100%; -} -.stack[data-debug=true] > * { - outline: 1px dotted black; -} - -.scrollable { - height: 280px; - overflow-y: scroll; - border-radius: 6px; - border: 1px solid rgba(0, 0, 0, 0.1); - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - background: rgb(252, 252, 252); - padding: 16px 20px 20px 16px; -} -.body--theme-dark .scrollable { - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - background: rgb(57, 57, 57); - border-color: rgba(255, 255, 255, 0.09); -} - -.data-list__content { - font-size: 14px; - font-weight: 400; - line-height: 1.4285714286; -} -.environment--android .data-list__content { - font-size: 14px; - font-weight: 400; - line-height: 1.2857142857; -} -.environment--ios .data-list__content, .environment--macos .data-list__content { - font-size: 13px; - font-weight: 400; - line-height: 1.3846153846; -} -.environment--android .data-list__content--breakage, .environment--browser .data-list__content--breakage, .environment--ios .data-list__content--breakage, .environment--macos .data-list__content--breakage, .environment--windows .data-list__content--breakage { - font-size: 13px; - line-height: 1.3846153846; -} - -.data-list__heading { - font-weight: 600; -} -.environment--android .data-list__heading { - font-weight: 700; -} - -.data-list { - list-style: none; -} - -.data-list__item { - word-wrap: anywhere; - color: var(--color-text-secondary); - position: relative; - padding-left: 20px; -} -.data-list__item + .data-list__item { - margin-top: 3px; -} - -.data-list__item::before { - content: "•"; - font-size: 12px; - position: absolute; - left: 8px; - top: 8px; - transform: translateY(-50%); - color: currentColor; -} - -.ios-separator { - padding-top: 16px; - border-top: 1px solid var(--color-system-lines); -} - -.fade-in { - opacity: 0; - visibility: hidden; - animation-name: fade-in; - animation-fill-mode: forwards; - animation-duration: 1s; -} - -@keyframes fade-in { - from { - opacity: 0; - visibility: hidden; - } - to { - opacity: 1; - visibility: visible; - } -} -.environment--macos .toggle-report[data-opener=dashboard] .top-nav { - opacity: 0; - visibility: hidden; -} - -.environment--ios [data-toggle-report=child], -.environment--android [data-toggle-report=child] { - opacity: 0; - visibility: hidden; -} - -.environment--ios [data-toggle-report=child][data-ready=true], -.environment--android [data-toggle-report=child][data-ready=true] { - opacity: 1; - visibility: visible; -} - -.toggle-report__heading { - margin-bottom: 24px; -} - -.toggle-report__scroller { - margin-bottom: 16px; -} -.toggle-report__scroller .scrollable::-webkit-scrollbar { - width: 14px; -} -.toggle-report__scroller .scrollable::-webkit-scrollbar-track { - border-radius: 6px; -} -.toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, 0.1); - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - border: 2px solid rgb(252, 252, 252); - border-radius: 6px; -} -.body--theme-dark .toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - border-color: rgb(57, 57, 57); - background: rgba(0, 0, 0, 0.3); -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js deleted file mode 100644 index 1900913d49e9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js +++ /dev/null @@ -1,5042 +0,0 @@ -"use strict"; -(() => { - var __defProp = Object.defineProperty; - var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; - var __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); - return value; - }; - - // node_modules/@lit/reactive-element/css-tag.js - var t = globalThis; - var e = t.ShadowRoot && (void 0 === t.ShadyCSS || t.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype; - var s = Symbol(); - var o = /* @__PURE__ */ new WeakMap(); - var n = class { - constructor(t4, e6, o5) { - if (this._$cssResult$ = true, o5 !== s) - throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); - this.cssText = t4, this.t = e6; - } - get styleSheet() { - let t4 = this.o; - const s2 = this.t; - if (e && void 0 === t4) { - const e6 = void 0 !== s2 && 1 === s2.length; - e6 && (t4 = o.get(s2)), void 0 === t4 && ((this.o = t4 = new CSSStyleSheet()).replaceSync(this.cssText), e6 && o.set(s2, t4)); - } - return t4; - } - toString() { - return this.cssText; - } - }; - var r = (t4) => new n("string" == typeof t4 ? t4 : t4 + "", void 0, s); - var i = (t4, ...e6) => { - const o5 = 1 === t4.length ? t4[0] : e6.reduce((e7, s2, o6) => e7 + ((t5) => { - if (true === t5._$cssResult$) - return t5.cssText; - if ("number" == typeof t5) - return t5; - throw Error("Value passed to 'css' function must be a 'css' function result: " + t5 + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); - })(s2) + t4[o6 + 1], t4[0]); - return new n(o5, t4, s); - }; - var S = (s2, o5) => { - if (e) - s2.adoptedStyleSheets = o5.map((t4) => t4 instanceof CSSStyleSheet ? t4 : t4.styleSheet); - else - for (const e6 of o5) { - const o6 = document.createElement("style"), n5 = t.litNonce; - void 0 !== n5 && o6.setAttribute("nonce", n5), o6.textContent = e6.cssText, s2.appendChild(o6); - } - }; - var c = e ? (t4) => t4 : (t4) => t4 instanceof CSSStyleSheet ? ((t5) => { - let e6 = ""; - for (const s2 of t5.cssRules) - e6 += s2.cssText; - return r(e6); - })(t4) : t4; - - // node_modules/@lit/reactive-element/reactive-element.js - var { is: i2, defineProperty: e2, getOwnPropertyDescriptor: r2, getOwnPropertyNames: h, getOwnPropertySymbols: o2, getPrototypeOf: n2 } = Object; - var a = globalThis; - var c2 = a.trustedTypes; - var l = c2 ? c2.emptyScript : ""; - var p = a.reactiveElementPolyfillSupport; - var d = (t4, s2) => t4; - var u = { toAttribute(t4, s2) { - switch (s2) { - case Boolean: - t4 = t4 ? l : null; - break; - case Object: - case Array: - t4 = null == t4 ? t4 : JSON.stringify(t4); - } - return t4; - }, fromAttribute(t4, s2) { - let i4 = t4; - switch (s2) { - case Boolean: - i4 = null !== t4; - break; - case Number: - i4 = null === t4 ? null : Number(t4); - break; - case Object: - case Array: - try { - i4 = JSON.parse(t4); - } catch (t5) { - i4 = null; - } - } - return i4; - } }; - var f = (t4, s2) => !i2(t4, s2); - var y = { attribute: true, type: String, converter: u, reflect: false, hasChanged: f }; - Symbol.metadata ??= Symbol("metadata"), a.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap(); - var b = class extends HTMLElement { - static addInitializer(t4) { - this._$Ei(), (this.l ??= []).push(t4); - } - static get observedAttributes() { - return this.finalize(), this._$Eh && [...this._$Eh.keys()]; - } - static createProperty(t4, s2 = y) { - if (s2.state && (s2.attribute = false), this._$Ei(), this.elementProperties.set(t4, s2), !s2.noAccessor) { - const i4 = Symbol(), r5 = this.getPropertyDescriptor(t4, i4, s2); - void 0 !== r5 && e2(this.prototype, t4, r5); - } - } - static getPropertyDescriptor(t4, s2, i4) { - const { get: e6, set: h4 } = r2(this.prototype, t4) ?? { get() { - return this[s2]; - }, set(t5) { - this[s2] = t5; - } }; - return { get() { - return e6?.call(this); - }, set(s3) { - const r5 = e6?.call(this); - h4.call(this, s3), this.requestUpdate(t4, r5, i4); - }, configurable: true, enumerable: true }; - } - static getPropertyOptions(t4) { - return this.elementProperties.get(t4) ?? y; - } - static _$Ei() { - if (this.hasOwnProperty(d("elementProperties"))) - return; - const t4 = n2(this); - t4.finalize(), void 0 !== t4.l && (this.l = [...t4.l]), this.elementProperties = new Map(t4.elementProperties); - } - static finalize() { - if (this.hasOwnProperty(d("finalized"))) - return; - if (this.finalized = true, this._$Ei(), this.hasOwnProperty(d("properties"))) { - const t5 = this.properties, s2 = [...h(t5), ...o2(t5)]; - for (const i4 of s2) - this.createProperty(i4, t5[i4]); - } - const t4 = this[Symbol.metadata]; - if (null !== t4) { - const s2 = litPropertyMetadata.get(t4); - if (void 0 !== s2) - for (const [t5, i4] of s2) - this.elementProperties.set(t5, i4); - } - this._$Eh = /* @__PURE__ */ new Map(); - for (const [t5, s2] of this.elementProperties) { - const i4 = this._$Eu(t5, s2); - void 0 !== i4 && this._$Eh.set(i4, t5); - } - this.elementStyles = this.finalizeStyles(this.styles); - } - static finalizeStyles(s2) { - const i4 = []; - if (Array.isArray(s2)) { - const e6 = new Set(s2.flat(1 / 0).reverse()); - for (const s3 of e6) - i4.unshift(c(s3)); - } else - void 0 !== s2 && i4.push(c(s2)); - return i4; - } - static _$Eu(t4, s2) { - const i4 = s2.attribute; - return false === i4 ? void 0 : "string" == typeof i4 ? i4 : "string" == typeof t4 ? t4.toLowerCase() : void 0; - } - constructor() { - super(), this._$Ep = void 0, this.isUpdatePending = false, this.hasUpdated = false, this._$Em = null, this._$Ev(); - } - _$Ev() { - this._$ES = new Promise((t4) => this.enableUpdating = t4), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t4) => t4(this)); - } - addController(t4) { - (this._$EO ??= /* @__PURE__ */ new Set()).add(t4), void 0 !== this.renderRoot && this.isConnected && t4.hostConnected?.(); - } - removeController(t4) { - this._$EO?.delete(t4); - } - _$E_() { - const t4 = /* @__PURE__ */ new Map(), s2 = this.constructor.elementProperties; - for (const i4 of s2.keys()) - this.hasOwnProperty(i4) && (t4.set(i4, this[i4]), delete this[i4]); - t4.size > 0 && (this._$Ep = t4); - } - createRenderRoot() { - const t4 = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); - return S(t4, this.constructor.elementStyles), t4; - } - connectedCallback() { - this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(true), this._$EO?.forEach((t4) => t4.hostConnected?.()); - } - enableUpdating(t4) { - } - disconnectedCallback() { - this._$EO?.forEach((t4) => t4.hostDisconnected?.()); - } - attributeChangedCallback(t4, s2, i4) { - this._$AK(t4, i4); - } - _$EC(t4, s2) { - const i4 = this.constructor.elementProperties.get(t4), e6 = this.constructor._$Eu(t4, i4); - if (void 0 !== e6 && true === i4.reflect) { - const r5 = (void 0 !== i4.converter?.toAttribute ? i4.converter : u).toAttribute(s2, i4.type); - this._$Em = t4, null == r5 ? this.removeAttribute(e6) : this.setAttribute(e6, r5), this._$Em = null; - } - } - _$AK(t4, s2) { - const i4 = this.constructor, e6 = i4._$Eh.get(t4); - if (void 0 !== e6 && this._$Em !== e6) { - const t5 = i4.getPropertyOptions(e6), r5 = "function" == typeof t5.converter ? { fromAttribute: t5.converter } : void 0 !== t5.converter?.fromAttribute ? t5.converter : u; - this._$Em = e6, this[e6] = r5.fromAttribute(s2, t5.type), this._$Em = null; - } - } - requestUpdate(t4, s2, i4) { - if (void 0 !== t4) { - if (i4 ??= this.constructor.getPropertyOptions(t4), !(i4.hasChanged ?? f)(this[t4], s2)) - return; - this.P(t4, s2, i4); - } - false === this.isUpdatePending && (this._$ES = this._$ET()); - } - P(t4, s2, i4) { - this._$AL.has(t4) || this._$AL.set(t4, s2), true === i4.reflect && this._$Em !== t4 && (this._$Ej ??= /* @__PURE__ */ new Set()).add(t4); - } - async _$ET() { - this.isUpdatePending = true; - try { - await this._$ES; - } catch (t5) { - Promise.reject(t5); - } - const t4 = this.scheduleUpdate(); - return null != t4 && await t4, !this.isUpdatePending; - } - scheduleUpdate() { - return this.performUpdate(); - } - performUpdate() { - if (!this.isUpdatePending) - return; - if (!this.hasUpdated) { - if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) { - for (const [t6, s3] of this._$Ep) - this[t6] = s3; - this._$Ep = void 0; - } - const t5 = this.constructor.elementProperties; - if (t5.size > 0) - for (const [s3, i4] of t5) - true !== i4.wrapped || this._$AL.has(s3) || void 0 === this[s3] || this.P(s3, this[s3], i4); - } - let t4 = false; - const s2 = this._$AL; - try { - t4 = this.shouldUpdate(s2), t4 ? (this.willUpdate(s2), this._$EO?.forEach((t5) => t5.hostUpdate?.()), this.update(s2)) : this._$EU(); - } catch (s3) { - throw t4 = false, this._$EU(), s3; - } - t4 && this._$AE(s2); - } - willUpdate(t4) { - } - _$AE(t4) { - this._$EO?.forEach((t5) => t5.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t4)), this.updated(t4); - } - _$EU() { - this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = false; - } - get updateComplete() { - return this.getUpdateComplete(); - } - getUpdateComplete() { - return this._$ES; - } - shouldUpdate(t4) { - return true; - } - update(t4) { - this._$Ej &&= this._$Ej.forEach((t5) => this._$EC(t5, this[t5])), this._$EU(); - } - updated(t4) { - } - firstUpdated(t4) { - } - }; - b.elementStyles = [], b.shadowRootOptions = { mode: "open" }, b[d("elementProperties")] = /* @__PURE__ */ new Map(), b[d("finalized")] = /* @__PURE__ */ new Map(), p?.({ ReactiveElement: b }), (a.reactiveElementVersions ??= []).push("2.0.4"); - - // node_modules/lit-html/lit-html.js - var n3 = globalThis; - var c3 = n3.trustedTypes; - var h2 = c3 ? c3.createPolicy("lit-html", { createHTML: (t4) => t4 }) : void 0; - var f2 = "$lit$"; - var v = `lit$${Math.random().toFixed(9).slice(2)}$`; - var m = "?" + v; - var _ = `<${m}>`; - var w = document; - var lt = () => w.createComment(""); - var st = (t4) => null === t4 || "object" != typeof t4 && "function" != typeof t4; - var g = Array.isArray; - var $ = (t4) => g(t4) || "function" == typeof t4?.[Symbol.iterator]; - var x = "[ \n\f\r]"; - var T = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g; - var E = /-->/g; - var k = />/g; - var O = RegExp(`>|${x}(?:([^\\s"'>=/]+)(${x}*=${x}*(?:[^ -\f\r"'\`<>=]|("|')|))|$)`, "g"); - var S2 = /'/g; - var j = /"/g; - var M = /^(?:script|style|textarea|title)$/i; - var P = (t4) => (i4, ...s2) => ({ _$litType$: t4, strings: i4, values: s2 }); - var ke = P(1); - var Oe = P(2); - var Se = P(3); - var R = Symbol.for("lit-noChange"); - var D = Symbol.for("lit-nothing"); - var V = /* @__PURE__ */ new WeakMap(); - var I = w.createTreeWalker(w, 129); - function N(t4, i4) { - if (!g(t4) || !t4.hasOwnProperty("raw")) - throw Error("invalid template strings array"); - return void 0 !== h2 ? h2.createHTML(i4) : i4; - } - var U = (t4, i4) => { - const s2 = t4.length - 1, e6 = []; - let h4, o5 = 2 === i4 ? "" : 3 === i4 ? "" : "", n5 = T; - for (let i5 = 0; i5 < s2; i5++) { - const s3 = t4[i5]; - let r5, l2, c4 = -1, a2 = 0; - for (; a2 < s3.length && (n5.lastIndex = a2, l2 = n5.exec(s3), null !== l2); ) - a2 = n5.lastIndex, n5 === T ? "!--" === l2[1] ? n5 = E : void 0 !== l2[1] ? n5 = k : void 0 !== l2[2] ? (M.test(l2[2]) && (h4 = RegExp("" === l2[0] ? (n5 = h4 ?? T, c4 = -1) : void 0 === l2[1] ? c4 = -2 : (c4 = n5.lastIndex - l2[2].length, r5 = l2[1], n5 = void 0 === l2[3] ? O : '"' === l2[3] ? j : S2) : n5 === j || n5 === S2 ? n5 = O : n5 === E || n5 === k ? n5 = T : (n5 = O, h4 = void 0); - const u2 = n5 === O && t4[i5 + 1].startsWith("/>") ? " " : ""; - o5 += n5 === T ? s3 + _ : c4 >= 0 ? (e6.push(r5), s3.slice(0, c4) + f2 + s3.slice(c4) + v + u2) : s3 + v + (-2 === c4 ? i5 : u2); - } - return [N(t4, o5 + (t4[s2] || "") + (2 === i4 ? "" : 3 === i4 ? "" : "")), e6]; - }; - var B = class _B { - constructor({ strings: t4, _$litType$: i4 }, s2) { - let e6; - this.parts = []; - let h4 = 0, o5 = 0; - const n5 = t4.length - 1, r5 = this.parts, [l2, a2] = U(t4, i4); - if (this.el = _B.createElement(l2, s2), I.currentNode = this.el.content, 2 === i4 || 3 === i4) { - const t5 = this.el.content.firstChild; - t5.replaceWith(...t5.childNodes); - } - for (; null !== (e6 = I.nextNode()) && r5.length < n5; ) { - if (1 === e6.nodeType) { - if (e6.hasAttributes()) - for (const t5 of e6.getAttributeNames()) - if (t5.endsWith(f2)) { - const i5 = a2[o5++], s3 = e6.getAttribute(t5).split(v), n6 = /([.?@])?(.*)/.exec(i5); - r5.push({ type: 1, index: h4, name: n6[2], strings: s3, ctor: "." === n6[1] ? Y : "?" === n6[1] ? Z : "@" === n6[1] ? q : G }), e6.removeAttribute(t5); - } else - t5.startsWith(v) && (r5.push({ type: 6, index: h4 }), e6.removeAttribute(t5)); - if (M.test(e6.tagName)) { - const t5 = e6.textContent.split(v), i5 = t5.length - 1; - if (i5 > 0) { - e6.textContent = c3 ? c3.emptyScript : ""; - for (let s3 = 0; s3 < i5; s3++) - e6.append(t5[s3], lt()), I.nextNode(), r5.push({ type: 2, index: ++h4 }); - e6.append(t5[i5], lt()); - } - } - } else if (8 === e6.nodeType) - if (e6.data === m) - r5.push({ type: 2, index: h4 }); - else { - let t5 = -1; - for (; -1 !== (t5 = e6.data.indexOf(v, t5 + 1)); ) - r5.push({ type: 7, index: h4 }), t5 += v.length - 1; - } - h4++; - } - } - static createElement(t4, i4) { - const s2 = w.createElement("template"); - return s2.innerHTML = t4, s2; - } - }; - function z(t4, i4, s2 = t4, e6) { - if (i4 === R) - return i4; - let h4 = void 0 !== e6 ? s2.o?.[e6] : s2.l; - const o5 = st(i4) ? void 0 : i4._$litDirective$; - return h4?.constructor !== o5 && (h4?._$AO?.(false), void 0 === o5 ? h4 = void 0 : (h4 = new o5(t4), h4._$AT(t4, s2, e6)), void 0 !== e6 ? (s2.o ??= [])[e6] = h4 : s2.l = h4), void 0 !== h4 && (i4 = z(t4, h4._$AS(t4, i4.values), h4, e6)), i4; - } - var F = class { - constructor(t4, i4) { - this._$AV = [], this._$AN = void 0, this._$AD = t4, this._$AM = i4; - } - get parentNode() { - return this._$AM.parentNode; - } - get _$AU() { - return this._$AM._$AU; - } - u(t4) { - const { el: { content: i4 }, parts: s2 } = this._$AD, e6 = (t4?.creationScope ?? w).importNode(i4, true); - I.currentNode = e6; - let h4 = I.nextNode(), o5 = 0, n5 = 0, r5 = s2[0]; - for (; void 0 !== r5; ) { - if (o5 === r5.index) { - let i5; - 2 === r5.type ? i5 = new et(h4, h4.nextSibling, this, t4) : 1 === r5.type ? i5 = new r5.ctor(h4, r5.name, r5.strings, this, t4) : 6 === r5.type && (i5 = new K(h4, this, t4)), this._$AV.push(i5), r5 = s2[++n5]; - } - o5 !== r5?.index && (h4 = I.nextNode(), o5++); - } - return I.currentNode = w, e6; - } - p(t4) { - let i4 = 0; - for (const s2 of this._$AV) - void 0 !== s2 && (void 0 !== s2.strings ? (s2._$AI(t4, s2, i4), i4 += s2.strings.length - 2) : s2._$AI(t4[i4])), i4++; - } - }; - var et = class _et { - get _$AU() { - return this._$AM?._$AU ?? this.v; - } - constructor(t4, i4, s2, e6) { - this.type = 2, this._$AH = D, this._$AN = void 0, this._$AA = t4, this._$AB = i4, this._$AM = s2, this.options = e6, this.v = e6?.isConnected ?? true; - } - get parentNode() { - let t4 = this._$AA.parentNode; - const i4 = this._$AM; - return void 0 !== i4 && 11 === t4?.nodeType && (t4 = i4.parentNode), t4; - } - get startNode() { - return this._$AA; - } - get endNode() { - return this._$AB; - } - _$AI(t4, i4 = this) { - t4 = z(this, t4, i4), st(t4) ? t4 === D || null == t4 || "" === t4 ? (this._$AH !== D && this._$AR(), this._$AH = D) : t4 !== this._$AH && t4 !== R && this._(t4) : void 0 !== t4._$litType$ ? this.$(t4) : void 0 !== t4.nodeType ? this.T(t4) : $(t4) ? this.k(t4) : this._(t4); - } - O(t4) { - return this._$AA.parentNode.insertBefore(t4, this._$AB); - } - T(t4) { - this._$AH !== t4 && (this._$AR(), this._$AH = this.O(t4)); - } - _(t4) { - this._$AH !== D && st(this._$AH) ? this._$AA.nextSibling.data = t4 : this.T(w.createTextNode(t4)), this._$AH = t4; - } - $(t4) { - const { values: i4, _$litType$: s2 } = t4, e6 = "number" == typeof s2 ? this._$AC(t4) : (void 0 === s2.el && (s2.el = B.createElement(N(s2.h, s2.h[0]), this.options)), s2); - if (this._$AH?._$AD === e6) - this._$AH.p(i4); - else { - const t5 = new F(e6, this), s3 = t5.u(this.options); - t5.p(i4), this.T(s3), this._$AH = t5; - } - } - _$AC(t4) { - let i4 = V.get(t4.strings); - return void 0 === i4 && V.set(t4.strings, i4 = new B(t4)), i4; - } - k(t4) { - g(this._$AH) || (this._$AH = [], this._$AR()); - const i4 = this._$AH; - let s2, e6 = 0; - for (const h4 of t4) - e6 === i4.length ? i4.push(s2 = new _et(this.O(lt()), this.O(lt()), this, this.options)) : s2 = i4[e6], s2._$AI(h4), e6++; - e6 < i4.length && (this._$AR(s2 && s2._$AB.nextSibling, e6), i4.length = e6); - } - _$AR(t4 = this._$AA.nextSibling, i4) { - for (this._$AP?.(false, true, i4); t4 && t4 !== this._$AB; ) { - const i5 = t4.nextSibling; - t4.remove(), t4 = i5; - } - } - setConnected(t4) { - void 0 === this._$AM && (this.v = t4, this._$AP?.(t4)); - } - }; - var G = class { - get tagName() { - return this.element.tagName; - } - get _$AU() { - return this._$AM._$AU; - } - constructor(t4, i4, s2, e6, h4) { - this.type = 1, this._$AH = D, this._$AN = void 0, this.element = t4, this.name = i4, this._$AM = e6, this.options = h4, s2.length > 2 || "" !== s2[0] || "" !== s2[1] ? (this._$AH = Array(s2.length - 1).fill(new String()), this.strings = s2) : this._$AH = D; - } - _$AI(t4, i4 = this, s2, e6) { - const h4 = this.strings; - let o5 = false; - if (void 0 === h4) - t4 = z(this, t4, i4, 0), o5 = !st(t4) || t4 !== this._$AH && t4 !== R, o5 && (this._$AH = t4); - else { - const e7 = t4; - let n5, r5; - for (t4 = h4[0], n5 = 0; n5 < h4.length - 1; n5++) - r5 = z(this, e7[s2 + n5], i4, n5), r5 === R && (r5 = this._$AH[n5]), o5 ||= !st(r5) || r5 !== this._$AH[n5], r5 === D ? t4 = D : t4 !== D && (t4 += (r5 ?? "") + h4[n5 + 1]), this._$AH[n5] = r5; - } - o5 && !e6 && this.j(t4); - } - j(t4) { - t4 === D ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t4 ?? ""); - } - }; - var Y = class extends G { - constructor() { - super(...arguments), this.type = 3; - } - j(t4) { - this.element[this.name] = t4 === D ? void 0 : t4; - } - }; - var Z = class extends G { - constructor() { - super(...arguments), this.type = 4; - } - j(t4) { - this.element.toggleAttribute(this.name, !!t4 && t4 !== D); - } - }; - var q = class extends G { - constructor(t4, i4, s2, e6, h4) { - super(t4, i4, s2, e6, h4), this.type = 5; - } - _$AI(t4, i4 = this) { - if ((t4 = z(this, t4, i4, 0) ?? D) === R) - return; - const s2 = this._$AH, e6 = t4 === D && s2 !== D || t4.capture !== s2.capture || t4.once !== s2.once || t4.passive !== s2.passive, h4 = t4 !== D && (s2 === D || e6); - e6 && this.element.removeEventListener(this.name, this, s2), h4 && this.element.addEventListener(this.name, this, t4), this._$AH = t4; - } - handleEvent(t4) { - "function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t4) : this._$AH.handleEvent(t4); - } - }; - var K = class { - constructor(t4, i4, s2) { - this.element = t4, this.type = 6, this._$AN = void 0, this._$AM = i4, this.options = s2; - } - get _$AU() { - return this._$AM._$AU; - } - _$AI(t4) { - z(this, t4); - } - }; - var si = { M: f2, P: v, A: m, C: 1, L: U, R: F, D: $, V: z, I: et, H: G, N: Z, U: q, B: Y, F: K }; - var Re = n3.litHtmlPolyfillSupport; - Re?.(B, et), (n3.litHtmlVersions ??= []).push("3.2.0"); - var Q = (t4, i4, s2) => { - const e6 = s2?.renderBefore ?? i4; - let h4 = e6._$litPart$; - if (void 0 === h4) { - const t5 = s2?.renderBefore ?? null; - e6._$litPart$ = h4 = new et(i4.insertBefore(lt(), t5), t5, void 0, s2 ?? {}); - } - return h4._$AI(t4), h4; - }; - - // node_modules/lit-element/lit-element.js - var h3 = class extends b { - constructor() { - super(...arguments), this.renderOptions = { host: this }, this.o = void 0; - } - createRenderRoot() { - const t4 = super.createRenderRoot(); - return this.renderOptions.renderBefore ??= t4.firstChild, t4; - } - update(t4) { - const e6 = this.render(); - this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t4), this.o = Q(e6, this.renderRoot, this.renderOptions); - } - connectedCallback() { - super.connectedCallback(), this.o?.setConnected(true); - } - disconnectedCallback() { - super.disconnectedCallback(), this.o?.setConnected(false); - } - render() { - return R; - } - }; - h3._$litElement$ = true, h3["finalized"] = true, globalThis.litElementHydrateSupport?.({ LitElement: h3 }); - var f3 = globalThis.litElementPolyfillSupport; - f3?.({ LitElement: h3 }); - (globalThis.litElementVersions ??= []).push("4.1.0"); - - // node_modules/lit-html/is-server.js - var co = false; - - // node_modules/lit-html/directives/map.js - function* oo(o5, f4) { - if (void 0 !== o5) { - let i4 = 0; - for (const t4 of o5) - yield f4(t4, i4++); - } - } - - // node_modules/tslib/tslib.es6.js - function __decorate(decorators, target, key, desc) { - var c4 = arguments.length, r5 = c4 < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d2; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") - r5 = Reflect.decorate(decorators, target, key, desc); - else - for (var i4 = decorators.length - 1; i4 >= 0; i4--) - if (d2 = decorators[i4]) - r5 = (c4 < 3 ? d2(r5) : c4 > 3 ? d2(target, key, r5) : d2(target, key)) || r5; - return c4 > 3 && r5 && Object.defineProperty(target, key, r5), r5; - } - - // node_modules/@lit/reactive-element/decorators/custom-element.js - var t2 = (t4) => (e6, o5) => { - void 0 !== o5 ? o5.addInitializer(() => { - customElements.define(t4, e6); - }) : customElements.define(t4, e6); - }; - - // node_modules/@lit/reactive-element/decorators/property.js - var o3 = { attribute: true, type: String, converter: u, reflect: false, hasChanged: f }; - var r3 = (t4 = o3, e6, r5) => { - const { kind: n5, metadata: i4 } = r5; - let s2 = globalThis.litPropertyMetadata.get(i4); - if (void 0 === s2 && globalThis.litPropertyMetadata.set(i4, s2 = /* @__PURE__ */ new Map()), s2.set(r5.name, t4), "accessor" === n5) { - const { name: o5 } = r5; - return { set(r6) { - const n6 = e6.get.call(this); - e6.set.call(this, r6), this.requestUpdate(o5, n6, t4); - }, init(e7) { - return void 0 !== e7 && this.P(o5, void 0, t4), e7; - } }; - } - if ("setter" === n5) { - const { name: o5 } = r5; - return function(r6) { - const n6 = this[o5]; - e6.call(this, r6), this.requestUpdate(o5, n6, t4); - }; - } - throw Error("Unsupported decorator location: " + n5); - }; - function n4(t4) { - return (e6, o5) => "object" == typeof o5 ? r3(t4, e6, o5) : ((t5, e7, o6) => { - const r5 = e7.hasOwnProperty(o6); - return e7.constructor.createProperty(o6, r5 ? { ...t5, wrapped: true } : t5), r5 ? Object.getOwnPropertyDescriptor(e7, o6) : void 0; - })(t4, e6, o5); - } - - // node_modules/@lit/reactive-element/decorators/state.js - function r4(r5) { - return n4({ ...r5, state: true, attribute: false }); - } - - // node_modules/@lit/reactive-element/decorators/base.js - var e3 = (e6, t4, c4) => (c4.configurable = true, c4.enumerable = true, Reflect.decorate && "object" != typeof t4 && Object.defineProperty(e6, t4, c4), c4); - - // node_modules/@lit/reactive-element/decorators/query.js - function e4(e6, r5) { - return (n5, s2, i4) => { - const o5 = (t4) => t4.renderRoot?.querySelector(e6) ?? null; - if (r5) { - const { get: e7, set: r6 } = "object" == typeof s2 ? n5 : i4 ?? (() => { - const t4 = Symbol(); - return { get() { - return this[t4]; - }, set(e8) { - this[t4] = e8; - } }; - })(); - return e3(n5, s2, { get() { - let t4 = e7.call(this); - return void 0 === t4 && (t4 = o5(this), (null !== t4 || this.hasUpdated) && r6.call(this, t4)), t4; - } }); - } - return e3(n5, s2, { get() { - return o5(this); - } }); - }; - } - - // node_modules/@lit/reactive-element/decorators/query-assigned-elements.js - function o4(o5) { - return (e6, n5) => { - const { slot: r5, selector: s2 } = o5 ?? {}, c4 = "slot" + (r5 ? `[name=${r5}]` : ":not([name])"); - return e3(e6, n5, { get() { - const t4 = this.renderRoot?.querySelector(c4), e7 = t4?.assignedElements(o5) ?? []; - return void 0 === s2 ? e7 : e7.filter((t5) => t5.matches(s2)); - } }); - }; - } - - // node_modules/@material/web/elevation/internal/elevation.js - var Elevation = class extends h3 { - connectedCallback() { - super.connectedCallback(); - this.setAttribute("aria-hidden", "true"); - } - render() { - return ke``; - } - }; - - // node_modules/@material/web/elevation/internal/elevation-styles.js - var styles = i`:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}:host{display:flex;pointer-events:none;transition-property:box-shadow,opacity}.shadow::before,.shadow::after{content:"";transition-property:box-shadow,opacity;--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000))}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15} -`; - - // node_modules/@material/web/elevation/elevation.js - var MdElevation = class MdElevation2 extends Elevation { - }; - MdElevation.styles = [styles]; - MdElevation = __decorate([ - t2("md-elevation") - ], MdElevation); - - // node_modules/@material/web/internal/controller/attachable-controller.js - var ATTACHABLE_CONTROLLER = Symbol("attachableController"); - var FOR_ATTRIBUTE_OBSERVER; - if (!co) { - FOR_ATTRIBUTE_OBSERVER = new MutationObserver((records) => { - for (const record of records) { - record.target[ATTACHABLE_CONTROLLER]?.hostConnected(); - } - }); - } - var AttachableController = class { - get htmlFor() { - return this.host.getAttribute("for"); - } - set htmlFor(htmlFor) { - if (htmlFor === null) { - this.host.removeAttribute("for"); - } else { - this.host.setAttribute("for", htmlFor); - } - } - get control() { - if (this.host.hasAttribute("for")) { - if (!this.htmlFor || !this.host.isConnected) { - return null; - } - return this.host.getRootNode().querySelector(`#${this.htmlFor}`); - } - return this.currentControl || this.host.parentElement; - } - set control(control) { - if (control) { - this.attach(control); - } else { - this.detach(); - } - } - /** - * Creates a new controller for an `Attachable` element. - * - * @param host The `Attachable` element. - * @param onControlChange A callback with two parameters for the previous and - * next control. An `Attachable` element may perform setup or teardown - * logic whenever the control changes. - */ - constructor(host, onControlChange) { - this.host = host; - this.onControlChange = onControlChange; - this.currentControl = null; - host.addController(this); - host[ATTACHABLE_CONTROLLER] = this; - FOR_ATTRIBUTE_OBSERVER?.observe(host, { attributeFilter: ["for"] }); - } - attach(control) { - if (control === this.currentControl) { - return; - } - this.setCurrentControl(control); - this.host.removeAttribute("for"); - } - detach() { - this.setCurrentControl(null); - this.host.setAttribute("for", ""); - } - /** @private */ - hostConnected() { - this.setCurrentControl(this.control); - } - /** @private */ - hostDisconnected() { - this.setCurrentControl(null); - } - setCurrentControl(control) { - this.onControlChange(this.currentControl, control); - this.currentControl = control; - } - }; - - // node_modules/@material/web/focus/internal/focus-ring.js - var EVENTS = ["focusin", "focusout", "pointerdown"]; - var FocusRing = class extends h3 { - constructor() { - super(...arguments); - this.visible = false; - this.inward = false; - this.attachableController = new AttachableController(this, this.onControlChange.bind(this)); - } - get htmlFor() { - return this.attachableController.htmlFor; - } - set htmlFor(htmlFor) { - this.attachableController.htmlFor = htmlFor; - } - get control() { - return this.attachableController.control; - } - set control(control) { - this.attachableController.control = control; - } - attach(control) { - this.attachableController.attach(control); - } - detach() { - this.attachableController.detach(); - } - connectedCallback() { - super.connectedCallback(); - this.setAttribute("aria-hidden", "true"); - } - /** @private */ - handleEvent(event) { - if (event[HANDLED_BY_FOCUS_RING]) { - return; - } - switch (event.type) { - default: - return; - case "focusin": - this.visible = this.control?.matches(":focus-visible") ?? false; - break; - case "focusout": - case "pointerdown": - this.visible = false; - break; - } - event[HANDLED_BY_FOCUS_RING] = true; - } - onControlChange(prev, next) { - if (co) - return; - for (const event of EVENTS) { - prev?.removeEventListener(event, this); - next?.addEventListener(event, this); - } - } - update(changed) { - if (changed.has("visible")) { - this.dispatchEvent(new Event("visibility-changed")); - } - super.update(changed); - } - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], FocusRing.prototype, "visible", void 0); - __decorate([ - n4({ type: Boolean, reflect: true }) - ], FocusRing.prototype, "inward", void 0); - var HANDLED_BY_FOCUS_RING = Symbol("handledByFocusRing"); - - // node_modules/@material/web/focus/internal/focus-ring-styles.js - var styles2 = i`:host{animation-delay:0s,calc(var(--md-focus-ring-duration, 600ms)*.25);animation-duration:calc(var(--md-focus-ring-duration, 600ms)*.25),calc(var(--md-focus-ring-duration, 600ms)*.75);animation-timing-function:cubic-bezier(0.2, 0, 0, 1);box-sizing:border-box;color:var(--md-focus-ring-color, var(--md-sys-color-secondary, #625b71));display:none;pointer-events:none;position:absolute}:host([visible]){display:flex}:host(:not([inward])){animation-name:outward-grow,outward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));inset:calc(-1*var(--md-focus-ring-outward-offset, 2px));outline:var(--md-focus-ring-width, 3px) solid currentColor}:host([inward]){animation-name:inward-grow,inward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border:var(--md-focus-ring-width, 3px) solid currentColor;inset:var(--md-focus-ring-inward-offset, 0px)}@keyframes outward-grow{from{outline-width:0}to{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes outward-shrink{from{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-grow{from{border-width:0}to{border-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-shrink{from{border-width:var(--md-focus-ring-active-width, 8px)}}@media(prefers-reduced-motion){:host{animation:none}} -`; - - // node_modules/@material/web/focus/md-focus-ring.js - var MdFocusRing = class MdFocusRing2 extends FocusRing { - }; - MdFocusRing.styles = [styles2]; - MdFocusRing = __decorate([ - t2("md-focus-ring") - ], MdFocusRing); - - // node_modules/lit-html/directive.js - var t3 = { ATTRIBUTE: 1, CHILD: 2, PROPERTY: 3, BOOLEAN_ATTRIBUTE: 4, EVENT: 5, ELEMENT: 6 }; - var e5 = (t4) => (...e6) => ({ _$litDirective$: t4, values: e6 }); - var i3 = class { - constructor(t4) { - } - get _$AU() { - return this._$AM._$AU; - } - _$AT(t4, e6, i4) { - this.t = t4, this._$AM = e6, this.i = i4; - } - _$AS(t4, e6) { - return this.update(t4, e6); - } - update(t4, e6) { - return this.render(...e6); - } - }; - - // node_modules/lit-html/directives/class-map.js - var Rt = e5(class extends i3 { - constructor(s2) { - if (super(s2), s2.type !== t3.ATTRIBUTE || "class" !== s2.name || s2.strings?.length > 2) - throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute."); - } - render(t4) { - return " " + Object.keys(t4).filter((s2) => t4[s2]).join(" ") + " "; - } - update(t4, [s2]) { - if (void 0 === this.st) { - this.st = /* @__PURE__ */ new Set(), void 0 !== t4.strings && (this.nt = new Set(t4.strings.join(" ").split(/\s/).filter((t5) => "" !== t5))); - for (const t5 in s2) - s2[t5] && !this.nt?.has(t5) && this.st.add(t5); - return this.render(s2); - } - const i4 = t4.element.classList; - for (const t5 of this.st) - t5 in s2 || (i4.remove(t5), this.st.delete(t5)); - for (const t5 in s2) { - const r5 = !!s2[t5]; - r5 === this.st.has(t5) || this.nt?.has(t5) || (r5 ? (i4.add(t5), this.st.add(t5)) : (i4.remove(t5), this.st.delete(t5))); - } - return R; - } - }); - - // node_modules/@material/web/internal/motion/animation.js - var EASING = { - STANDARD: "cubic-bezier(0.2, 0, 0, 1)", - STANDARD_ACCELERATE: "cubic-bezier(.3,0,1,1)", - STANDARD_DECELERATE: "cubic-bezier(0,0,0,1)", - EMPHASIZED: "cubic-bezier(.3,0,0,1)", - EMPHASIZED_ACCELERATE: "cubic-bezier(.3,0,.8,.15)", - EMPHASIZED_DECELERATE: "cubic-bezier(.05,.7,.1,1)" - }; - - // node_modules/@material/web/ripple/internal/ripple.js - var PRESS_GROW_MS = 450; - var MINIMUM_PRESS_MS = 225; - var INITIAL_ORIGIN_SCALE = 0.2; - var PADDING = 10; - var SOFT_EDGE_MINIMUM_SIZE = 75; - var SOFT_EDGE_CONTAINER_RATIO = 0.35; - var PRESS_PSEUDO = "::after"; - var ANIMATION_FILL = "forwards"; - var State; - (function(State2) { - State2[State2["INACTIVE"] = 0] = "INACTIVE"; - State2[State2["TOUCH_DELAY"] = 1] = "TOUCH_DELAY"; - State2[State2["HOLDING"] = 2] = "HOLDING"; - State2[State2["WAITING_FOR_CLICK"] = 3] = "WAITING_FOR_CLICK"; - })(State || (State = {})); - var EVENTS2 = [ - "click", - "contextmenu", - "pointercancel", - "pointerdown", - "pointerenter", - "pointerleave", - "pointerup" - ]; - var TOUCH_DELAY_MS = 150; - var FORCED_COLORS = co ? null : window.matchMedia("(forced-colors: active)"); - var Ripple = class extends h3 { - constructor() { - super(...arguments); - this.disabled = false; - this.hovered = false; - this.pressed = false; - this.rippleSize = ""; - this.rippleScale = ""; - this.initialSize = 0; - this.state = State.INACTIVE; - this.checkBoundsAfterContextMenu = false; - this.attachableController = new AttachableController(this, this.onControlChange.bind(this)); - } - get htmlFor() { - return this.attachableController.htmlFor; - } - set htmlFor(htmlFor) { - this.attachableController.htmlFor = htmlFor; - } - get control() { - return this.attachableController.control; - } - set control(control) { - this.attachableController.control = control; - } - attach(control) { - this.attachableController.attach(control); - } - detach() { - this.attachableController.detach(); - } - connectedCallback() { - super.connectedCallback(); - this.setAttribute("aria-hidden", "true"); - } - render() { - const classes = { - "hovered": this.hovered, - "pressed": this.pressed - }; - return ke`
`; - } - update(changedProps) { - if (changedProps.has("disabled") && this.disabled) { - this.hovered = false; - this.pressed = false; - } - super.update(changedProps); - } - /** - * TODO(b/269799771): make private - * @private only public for slider - */ - handlePointerenter(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.hovered = true; - } - /** - * TODO(b/269799771): make private - * @private only public for slider - */ - handlePointerleave(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.hovered = false; - if (this.state !== State.INACTIVE) { - this.endPressAnimation(); - } - } - handlePointerup(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - if (this.state === State.HOLDING) { - this.state = State.WAITING_FOR_CLICK; - return; - } - if (this.state === State.TOUCH_DELAY) { - this.state = State.WAITING_FOR_CLICK; - this.startPressAnimation(this.rippleStartEvent); - return; - } - } - async handlePointerdown(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.rippleStartEvent = event; - if (!this.isTouch(event)) { - this.state = State.WAITING_FOR_CLICK; - this.startPressAnimation(event); - return; - } - if (this.checkBoundsAfterContextMenu && !this.inBounds(event)) { - return; - } - this.checkBoundsAfterContextMenu = false; - this.state = State.TOUCH_DELAY; - await new Promise((resolve) => { - setTimeout(resolve, TOUCH_DELAY_MS); - }); - if (this.state !== State.TOUCH_DELAY) { - return; - } - this.state = State.HOLDING; - this.startPressAnimation(event); - } - handleClick() { - if (this.disabled) { - return; - } - if (this.state === State.WAITING_FOR_CLICK) { - this.endPressAnimation(); - return; - } - if (this.state === State.INACTIVE) { - this.startPressAnimation(); - this.endPressAnimation(); - } - } - handlePointercancel(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.endPressAnimation(); - } - handleContextmenu() { - if (this.disabled) { - return; - } - this.checkBoundsAfterContextMenu = true; - this.endPressAnimation(); - } - determineRippleSize() { - const { height, width } = this.getBoundingClientRect(); - const maxDim = Math.max(height, width); - const softEdgeSize = Math.max(SOFT_EDGE_CONTAINER_RATIO * maxDim, SOFT_EDGE_MINIMUM_SIZE); - const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE); - const hypotenuse = Math.sqrt(width ** 2 + height ** 2); - const maxRadius = hypotenuse + PADDING; - this.initialSize = initialSize; - this.rippleScale = `${(maxRadius + softEdgeSize) / initialSize}`; - this.rippleSize = `${initialSize}px`; - } - getNormalizedPointerEventCoords(pointerEvent) { - const { scrollX, scrollY } = window; - const { left, top } = this.getBoundingClientRect(); - const documentX = scrollX + left; - const documentY = scrollY + top; - const { pageX, pageY } = pointerEvent; - return { x: pageX - documentX, y: pageY - documentY }; - } - getTranslationCoordinates(positionEvent) { - const { height, width } = this.getBoundingClientRect(); - const endPoint = { - x: (width - this.initialSize) / 2, - y: (height - this.initialSize) / 2 - }; - let startPoint; - if (positionEvent instanceof PointerEvent) { - startPoint = this.getNormalizedPointerEventCoords(positionEvent); - } else { - startPoint = { - x: width / 2, - y: height / 2 - }; - } - startPoint = { - x: startPoint.x - this.initialSize / 2, - y: startPoint.y - this.initialSize / 2 - }; - return { startPoint, endPoint }; - } - startPressAnimation(positionEvent) { - if (!this.mdRoot) { - return; - } - this.pressed = true; - this.growAnimation?.cancel(); - this.determineRippleSize(); - const { startPoint, endPoint } = this.getTranslationCoordinates(positionEvent); - const translateStart = `${startPoint.x}px, ${startPoint.y}px`; - const translateEnd = `${endPoint.x}px, ${endPoint.y}px`; - this.growAnimation = this.mdRoot.animate({ - top: [0, 0], - left: [0, 0], - height: [this.rippleSize, this.rippleSize], - width: [this.rippleSize, this.rippleSize], - transform: [ - `translate(${translateStart}) scale(1)`, - `translate(${translateEnd}) scale(${this.rippleScale})` - ] - }, { - pseudoElement: PRESS_PSEUDO, - duration: PRESS_GROW_MS, - easing: EASING.STANDARD, - fill: ANIMATION_FILL - }); - } - async endPressAnimation() { - this.rippleStartEvent = void 0; - this.state = State.INACTIVE; - const animation = this.growAnimation; - let pressAnimationPlayState = Infinity; - if (typeof animation?.currentTime === "number") { - pressAnimationPlayState = animation.currentTime; - } else if (animation?.currentTime) { - pressAnimationPlayState = animation.currentTime.to("ms").value; - } - if (pressAnimationPlayState >= MINIMUM_PRESS_MS) { - this.pressed = false; - return; - } - await new Promise((resolve) => { - setTimeout(resolve, MINIMUM_PRESS_MS - pressAnimationPlayState); - }); - if (this.growAnimation !== animation) { - return; - } - this.pressed = false; - } - /** - * Returns `true` if - * - the ripple element is enabled - * - the pointer is primary for the input type - * - the pointer is the pointer that started the interaction, or will start - * the interaction - * - the pointer is a touch, or the pointer state has the primary button - * held, or the pointer is hovering - */ - shouldReactToEvent(event) { - if (this.disabled || !event.isPrimary) { - return false; - } - if (this.rippleStartEvent && this.rippleStartEvent.pointerId !== event.pointerId) { - return false; - } - if (event.type === "pointerenter" || event.type === "pointerleave") { - return !this.isTouch(event); - } - const isPrimaryButton = event.buttons === 1; - return this.isTouch(event) || isPrimaryButton; - } - /** - * Check if the event is within the bounds of the element. - * - * This is only needed for the "stuck" contextmenu longpress on Chrome. - */ - inBounds({ x: x2, y: y2 }) { - const { top, left, bottom, right } = this.getBoundingClientRect(); - return x2 >= left && x2 <= right && y2 >= top && y2 <= bottom; - } - isTouch({ pointerType }) { - return pointerType === "touch"; - } - /** @private */ - async handleEvent(event) { - if (FORCED_COLORS?.matches) { - return; - } - switch (event.type) { - case "click": - this.handleClick(); - break; - case "contextmenu": - this.handleContextmenu(); - break; - case "pointercancel": - this.handlePointercancel(event); - break; - case "pointerdown": - await this.handlePointerdown(event); - break; - case "pointerenter": - this.handlePointerenter(event); - break; - case "pointerleave": - this.handlePointerleave(event); - break; - case "pointerup": - this.handlePointerup(event); - break; - default: - break; - } - } - onControlChange(prev, next) { - if (co) - return; - for (const event of EVENTS2) { - prev?.removeEventListener(event, this); - next?.addEventListener(event, this); - } - } - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], Ripple.prototype, "disabled", void 0); - __decorate([ - r4() - ], Ripple.prototype, "hovered", void 0); - __decorate([ - r4() - ], Ripple.prototype, "pressed", void 0); - __decorate([ - e4(".surface") - ], Ripple.prototype, "mdRoot", void 0); - - // node_modules/@material/web/ripple/internal/ripple-styles.js - var styles3 = i`:host{display:flex;margin:auto;pointer-events:none}:host([disabled]){display:none}@media(forced-colors: active){:host{display:none}}:host,.surface{border-radius:inherit;position:absolute;inset:0;overflow:hidden}.surface{-webkit-tap-highlight-color:rgba(0,0,0,0)}.surface::before,.surface::after{content:"";opacity:0;position:absolute}.surface::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));inset:0;transition:opacity 15ms linear,background-color 15ms linear}.surface::after{background:radial-gradient(closest-side, var(--md-ripple-pressed-color, var(--md-sys-color-on-surface, #1d1b20)) max(100% - 70px, 65%), transparent 100%);transform-origin:center center;transition:opacity 375ms linear}.hovered::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-ripple-hover-opacity, 0.08)}.pressed::after{opacity:var(--md-ripple-pressed-opacity, 0.12);transition-duration:105ms} -`; - - // node_modules/@material/web/ripple/ripple.js - var MdRipple = class MdRipple2 extends Ripple { - }; - MdRipple.styles = [styles3]; - MdRipple = __decorate([ - t2("md-ripple") - ], MdRipple); - - // node_modules/@material/web/internal/aria/aria.js - var ARIA_PROPERTIES = [ - "role", - "ariaAtomic", - "ariaAutoComplete", - "ariaBusy", - "ariaChecked", - "ariaColCount", - "ariaColIndex", - "ariaColSpan", - "ariaCurrent", - "ariaDisabled", - "ariaExpanded", - "ariaHasPopup", - "ariaHidden", - "ariaInvalid", - "ariaKeyShortcuts", - "ariaLabel", - "ariaLevel", - "ariaLive", - "ariaModal", - "ariaMultiLine", - "ariaMultiSelectable", - "ariaOrientation", - "ariaPlaceholder", - "ariaPosInSet", - "ariaPressed", - "ariaReadOnly", - "ariaRequired", - "ariaRoleDescription", - "ariaRowCount", - "ariaRowIndex", - "ariaRowSpan", - "ariaSelected", - "ariaSetSize", - "ariaSort", - "ariaValueMax", - "ariaValueMin", - "ariaValueNow", - "ariaValueText" - ]; - var ARIA_ATTRIBUTES = ARIA_PROPERTIES.map(ariaPropertyToAttribute); - function isAriaAttribute(attribute) { - return ARIA_ATTRIBUTES.includes(attribute); - } - function ariaPropertyToAttribute(property) { - return property.replace("aria", "aria-").replace(/Elements?/g, "").toLowerCase(); - } - - // node_modules/@material/web/internal/aria/delegate.js - var privateIgnoreAttributeChangesFor = Symbol("privateIgnoreAttributeChangesFor"); - function mixinDelegatesAria(base) { - var _a2; - if (co) { - return base; - } - class WithDelegatesAriaElement extends base { - constructor() { - super(...arguments); - this[_a2] = /* @__PURE__ */ new Set(); - } - attributeChangedCallback(name, oldValue, newValue) { - if (!isAriaAttribute(name)) { - super.attributeChangedCallback(name, oldValue, newValue); - return; - } - if (this[privateIgnoreAttributeChangesFor].has(name)) { - return; - } - this[privateIgnoreAttributeChangesFor].add(name); - this.removeAttribute(name); - this[privateIgnoreAttributeChangesFor].delete(name); - const dataProperty = ariaAttributeToDataProperty(name); - if (newValue === null) { - delete this.dataset[dataProperty]; - } else { - this.dataset[dataProperty] = newValue; - } - this.requestUpdate(ariaAttributeToDataProperty(name), oldValue); - } - getAttribute(name) { - if (isAriaAttribute(name)) { - return super.getAttribute(ariaAttributeToDataAttribute(name)); - } - return super.getAttribute(name); - } - removeAttribute(name) { - super.removeAttribute(name); - if (isAriaAttribute(name)) { - super.removeAttribute(ariaAttributeToDataAttribute(name)); - this.requestUpdate(); - } - } - } - _a2 = privateIgnoreAttributeChangesFor; - setupDelegatesAriaProperties(WithDelegatesAriaElement); - return WithDelegatesAriaElement; - } - function setupDelegatesAriaProperties(ctor) { - for (const ariaProperty of ARIA_PROPERTIES) { - const ariaAttribute = ariaPropertyToAttribute(ariaProperty); - const dataAttribute = ariaAttributeToDataAttribute(ariaAttribute); - const dataProperty = ariaAttributeToDataProperty(ariaAttribute); - ctor.createProperty(ariaProperty, { - attribute: ariaAttribute, - noAccessor: true - }); - ctor.createProperty(Symbol(dataAttribute), { - attribute: dataAttribute, - noAccessor: true - }); - Object.defineProperty(ctor.prototype, ariaProperty, { - configurable: true, - enumerable: true, - get() { - return this.dataset[dataProperty] ?? null; - }, - set(value) { - const prevValue = this.dataset[dataProperty] ?? null; - if (value === prevValue) { - return; - } - if (value === null) { - delete this.dataset[dataProperty]; - } else { - this.dataset[dataProperty] = value; - } - this.requestUpdate(ariaProperty, prevValue); - } - }); - } - } - function ariaAttributeToDataAttribute(ariaAttribute) { - return `data-${ariaAttribute}`; - } - function ariaAttributeToDataProperty(ariaAttribute) { - return ariaAttribute.replace(/-\w/, (dashLetter) => dashLetter[1].toUpperCase()); - } - - // node_modules/@material/web/labs/behaviors/element-internals.js - var internals = Symbol("internals"); - var privateInternals = Symbol("privateInternals"); - function mixinElementInternals(base) { - class WithElementInternalsElement extends base { - get [internals]() { - if (!this[privateInternals]) { - this[privateInternals] = this.attachInternals(); - } - return this[privateInternals]; - } - } - return WithElementInternalsElement; - } - - // node_modules/@material/web/internal/controller/form-submitter.js - function setupFormSubmitter(ctor) { - if (co) { - return; - } - ctor.addInitializer((instance) => { - const submitter = instance; - submitter.addEventListener("click", async (event) => { - const { type, [internals]: elementInternals } = submitter; - const { form } = elementInternals; - if (!form || type === "button") { - return; - } - await new Promise((resolve) => { - setTimeout(resolve); - }); - if (event.defaultPrevented) { - return; - } - if (type === "reset") { - form.reset(); - return; - } - form.addEventListener("submit", (submitEvent) => { - Object.defineProperty(submitEvent, "submitter", { - configurable: true, - enumerable: true, - get: () => submitter - }); - }, { capture: true, once: true }); - elementInternals.setFormValue(submitter.value); - form.requestSubmit(); - }); - }); - } - - // node_modules/@material/web/internal/events/form-label-activation.js - function dispatchActivationClick(element) { - const event = new MouseEvent("click", { bubbles: true }); - element.dispatchEvent(event); - return event; - } - function isActivationClick(event) { - if (event.currentTarget !== event.target) { - return false; - } - if (event.composedPath()[0] !== event.target) { - return false; - } - if (event.target.disabled) { - return false; - } - return !squelchEvent(event); - } - function squelchEvent(event) { - const squelched = isSquelchingEvents; - if (squelched) { - event.preventDefault(); - event.stopImmediatePropagation(); - } - squelchEventsForMicrotask(); - return squelched; - } - var isSquelchingEvents = false; - async function squelchEventsForMicrotask() { - isSquelchingEvents = true; - await null; - isSquelchingEvents = false; - } - - // node_modules/@material/web/button/internal/button.js - var buttonBaseClass = mixinDelegatesAria(mixinElementInternals(h3)); - var Button = class extends buttonBaseClass { - get name() { - return this.getAttribute("name") ?? ""; - } - set name(name) { - this.setAttribute("name", name); - } - /** - * The associated form element with which this element's value will submit. - */ - get form() { - return this[internals].form; - } - constructor() { - super(); - this.disabled = false; - this.softDisabled = false; - this.href = ""; - this.target = ""; - this.trailingIcon = false; - this.hasIcon = false; - this.type = "submit"; - this.value = ""; - if (!co) { - this.addEventListener("click", this.handleClick.bind(this)); - } - } - focus() { - this.buttonElement?.focus(); - } - blur() { - this.buttonElement?.blur(); - } - render() { - const isRippleDisabled = !this.href && (this.disabled || this.softDisabled); - const buttonOrLink = this.href ? this.renderLink() : this.renderButton(); - const buttonId = this.href ? "link" : "button"; - return ke` - ${this.renderElevationOrOutline?.()} -
- - - ${buttonOrLink} - `; - } - renderButton() { - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - return ke``; - } - renderLink() { - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - return ke`${this.renderContent()} - `; - } - renderContent() { - const icon = ke``; - return ke` - - ${this.trailingIcon ? D : icon} - - ${this.trailingIcon ? icon : D} - `; - } - handleClick(event) { - if (!this.href && this.softDisabled) { - event.stopImmediatePropagation(); - event.preventDefault(); - return; - } - if (!isActivationClick(event) || !this.buttonElement) { - return; - } - this.focus(); - dispatchActivationClick(this.buttonElement); - } - handleSlotChange() { - this.hasIcon = this.assignedIcons.length > 0; - } - }; - (() => { - setupFormSubmitter(Button); - })(); - Button.formAssociated = true; - Button.shadowRootOptions = { - mode: "open", - delegatesFocus: true - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], Button.prototype, "disabled", void 0); - __decorate([ - n4({ type: Boolean, attribute: "soft-disabled", reflect: true }) - ], Button.prototype, "softDisabled", void 0); - __decorate([ - n4() - ], Button.prototype, "href", void 0); - __decorate([ - n4() - ], Button.prototype, "target", void 0); - __decorate([ - n4({ type: Boolean, attribute: "trailing-icon", reflect: true }) - ], Button.prototype, "trailingIcon", void 0); - __decorate([ - n4({ type: Boolean, attribute: "has-icon", reflect: true }) - ], Button.prototype, "hasIcon", void 0); - __decorate([ - n4() - ], Button.prototype, "type", void 0); - __decorate([ - n4({ reflect: true }) - ], Button.prototype, "value", void 0); - __decorate([ - e4(".button") - ], Button.prototype, "buttonElement", void 0); - __decorate([ - o4({ slot: "icon", flatten: true }) - ], Button.prototype, "assignedIcons", void 0); - - // node_modules/@material/web/button/internal/filled-button.js - var FilledButton = class extends Button { - renderElevationOrOutline() { - return ke``; - } - }; - - // node_modules/@material/web/button/internal/filled-styles.js - var styles4 = i`:host{--_container-color: var(--md-filled-button-container-color, var(--md-sys-color-primary, #6750a4));--_container-elevation: var(--md-filled-button-container-elevation, 0);--_container-height: var(--md-filled-button-container-height, 40px);--_container-shadow-color: var(--md-filled-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-button-focus-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-container-elevation: var(--md-filled-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-button-hover-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-color: var(--md-filled-button-hover-state-layer-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-opacity: var(--md-filled-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-button-label-text-color, var(--md-sys-color-on-primary, #fff));--_label-text-font: var(--md-filled-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-button-pressed-label-text-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-color: var(--md-filled-button-pressed-state-layer-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-opacity: var(--md-filled-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-button-focus-icon-color, var(--md-sys-color-on-primary, #fff));--_hover-icon-color: var(--md-filled-button-hover-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-color: var(--md-filled-button-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-size: var(--md-filled-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-button-pressed-icon-color, var(--md-sys-color-on-primary, #fff));--_container-shape-start-start: var(--md-filled-button-container-shape-start-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-button-container-shape-start-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-button-container-shape-end-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-button-container-shape-end-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-button-leading-space, 24px);--_trailing-space: var(--md-filled-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-button-with-trailing-icon-trailing-space, 16px)} -`; - - // node_modules/@material/web/button/internal/shared-elevation-styles.js - var styles5 = i`md-elevation{transition-duration:280ms}:host(:is([disabled],[soft-disabled])) md-elevation{transition:none}md-elevation{--md-elevation-level: var(--_container-elevation);--md-elevation-shadow-color: var(--_container-shadow-color)}:host(:focus-within) md-elevation{--md-elevation-level: var(--_focus-container-elevation)}:host(:hover) md-elevation{--md-elevation-level: var(--_hover-container-elevation)}:host(:active) md-elevation{--md-elevation-level: var(--_pressed-container-elevation)}:host(:is([disabled],[soft-disabled])) md-elevation{--md-elevation-level: var(--_disabled-container-elevation)} -`; - - // node_modules/@material/web/button/internal/shared-styles.js - var styles6 = i`:host{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end);box-sizing:border-box;cursor:pointer;display:inline-flex;gap:8px;min-height:var(--_container-height);outline:none;padding-block:calc((var(--_container-height) - max(var(--_label-text-line-height),var(--_icon-size)))/2);padding-inline-start:var(--_leading-space);padding-inline-end:var(--_trailing-space);place-content:center;place-items:center;position:relative;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);text-overflow:ellipsis;text-wrap:nowrap;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);vertical-align:top;--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}:host(:is([disabled],[soft-disabled])){cursor:default;pointer-events:none}.button{border-radius:inherit;cursor:inherit;display:inline-flex;align-items:center;justify-content:center;border:none;outline:none;-webkit-appearance:none;vertical-align:middle;background:rgba(0,0,0,0);text-decoration:none;min-width:calc(64px - var(--_leading-space) - var(--_trailing-space));width:100%;z-index:0;height:100%;font:inherit;color:var(--_label-text-color);padding:0;gap:inherit;text-transform:inherit}.button::-moz-focus-inner{padding:0;border:0}:host(:hover) .button{color:var(--_hover-label-text-color)}:host(:focus-within) .button{color:var(--_focus-label-text-color)}:host(:active) .button{color:var(--_pressed-label-text-color)}.background{background-color:var(--_container-color);border-radius:inherit;inset:0;position:absolute}.label{overflow:hidden}:is(.button,.label,.label slot),.label ::slotted(*){text-overflow:inherit}:host(:is([disabled],[soft-disabled])) .label{color:var(--_disabled-label-text-color);opacity:var(--_disabled-label-text-opacity)}:host(:is([disabled],[soft-disabled])) .background{background-color:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}@media(forced-colors: active){.background{border:1px solid CanvasText}:host(:is([disabled],[soft-disabled])){--_disabled-icon-color: GrayText;--_disabled-icon-opacity: 1;--_disabled-container-opacity: 1;--_disabled-label-text-color: GrayText;--_disabled-label-text-opacity: 1}}:host([has-icon]:not([trailing-icon])){padding-inline-start:var(--_with-leading-icon-leading-space);padding-inline-end:var(--_with-leading-icon-trailing-space)}:host([has-icon][trailing-icon]){padding-inline-start:var(--_with-trailing-icon-leading-space);padding-inline-end:var(--_with-trailing-icon-trailing-space)}::slotted([slot=icon]){display:inline-flex;position:relative;writing-mode:horizontal-tb;fill:currentColor;flex-shrink:0;color:var(--_icon-color);font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size)}:host(:hover) ::slotted([slot=icon]){color:var(--_hover-icon-color)}:host(:focus-within) ::slotted([slot=icon]){color:var(--_focus-icon-color)}:host(:active) ::slotted([slot=icon]){color:var(--_pressed-icon-color)}:host(:is([disabled],[soft-disabled])) ::slotted([slot=icon]){color:var(--_disabled-icon-color);opacity:var(--_disabled-icon-opacity)}.touch{position:absolute;top:50%;height:48px;left:0;right:0;transform:translateY(-50%)}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_container-height))/2) 0}:host([touch-target=none]) .touch{display:none} -`; - - // node_modules/@material/web/button/filled-button.js - var MdFilledButton = class MdFilledButton2 extends FilledButton { - }; - MdFilledButton.styles = [ - styles6, - styles5, - styles4 - ]; - MdFilledButton = __decorate([ - t2("md-filled-button") - ], MdFilledButton); - - // node_modules/@material/web/button/internal/filled-tonal-button.js - var FilledTonalButton = class extends Button { - renderElevationOrOutline() { - return ke``; - } - }; - - // node_modules/@material/web/button/internal/filled-tonal-styles.js - var styles7 = i`:host{--_container-color: var(--md-filled-tonal-button-container-color, var(--md-sys-color-secondary-container, #e8def8));--_container-elevation: var(--md-filled-tonal-button-container-elevation, 0);--_container-height: var(--md-filled-tonal-button-container-height, 40px);--_container-shadow-color: var(--md-filled-tonal-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-tonal-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-tonal-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-tonal-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-tonal-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-tonal-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-tonal-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-tonal-button-focus-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-container-elevation: var(--md-filled-tonal-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-tonal-button-hover-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-color: var(--md-filled-tonal-button-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-opacity: var(--md-filled-tonal-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-tonal-button-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_label-text-font: var(--md-filled-tonal-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-tonal-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-tonal-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-tonal-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-tonal-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-tonal-button-pressed-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-color: var(--md-filled-tonal-button-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-opacity: var(--md-filled-tonal-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-tonal-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-tonal-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-tonal-button-focus-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-icon-color: var(--md-filled-tonal-button-hover-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-color: var(--md-filled-tonal-button-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-size: var(--md-filled-tonal-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-tonal-button-pressed-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_container-shape-start-start: var(--md-filled-tonal-button-container-shape-start-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-tonal-button-container-shape-start-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-tonal-button-container-shape-end-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-tonal-button-container-shape-end-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-tonal-button-leading-space, 24px);--_trailing-space: var(--md-filled-tonal-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-tonal-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-tonal-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-tonal-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-tonal-button-with-trailing-icon-trailing-space, 16px)} -`; - - // node_modules/@material/web/button/filled-tonal-button.js - var MdFilledTonalButton = class MdFilledTonalButton2 extends FilledTonalButton { - }; - MdFilledTonalButton.styles = [ - styles6, - styles5, - styles7 - ]; - MdFilledTonalButton = __decorate([ - t2("md-filled-tonal-button") - ], MdFilledTonalButton); - - // node_modules/@material/web/button/internal/text-button.js - var TextButton = class extends Button { - }; - - // node_modules/@material/web/button/internal/text-styles.js - var styles8 = i`:host{--_container-height: var(--md-text-button-container-height, 40px);--_disabled-label-text-color: var(--md-text-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-text-button-disabled-label-text-opacity, 0.38);--_focus-label-text-color: var(--md-text-button-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-text-button-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-text-button-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-text-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-text-button-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-text-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-text-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-text-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-text-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-text-button-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-text-button-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-text-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-text-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-text-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-text-button-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-icon-color: var(--md-text-button-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-color: var(--md-text-button-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-text-button-icon-size, 18px);--_pressed-icon-color: var(--md-text-button-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-text-button-container-shape-start-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-text-button-container-shape-start-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-text-button-container-shape-end-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-text-button-container-shape-end-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-text-button-leading-space, 12px);--_trailing-space: var(--md-text-button-trailing-space, 12px);--_with-leading-icon-leading-space: var(--md-text-button-with-leading-icon-leading-space, 12px);--_with-leading-icon-trailing-space: var(--md-text-button-with-leading-icon-trailing-space, 16px);--_with-trailing-icon-leading-space: var(--md-text-button-with-trailing-icon-leading-space, 16px);--_with-trailing-icon-trailing-space: var(--md-text-button-with-trailing-icon-trailing-space, 12px);--_container-color: none;--_disabled-container-color: none;--_disabled-container-opacity: 0} -`; - - // node_modules/@material/web/button/text-button.js - var MdTextButton = class MdTextButton2 extends TextButton { - }; - MdTextButton.styles = [styles6, styles8]; - MdTextButton = __decorate([ - t2("md-text-button") - ], MdTextButton); - - // node_modules/@material/web/divider/internal/divider.js - var Divider = class extends h3 { - constructor() { - super(...arguments); - this.inset = false; - this.insetStart = false; - this.insetEnd = false; - } - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], Divider.prototype, "inset", void 0); - __decorate([ - n4({ type: Boolean, reflect: true, attribute: "inset-start" }) - ], Divider.prototype, "insetStart", void 0); - __decorate([ - n4({ type: Boolean, reflect: true, attribute: "inset-end" }) - ], Divider.prototype, "insetEnd", void 0); - - // node_modules/@material/web/divider/internal/divider-styles.js - var styles9 = i`:host{box-sizing:border-box;color:var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));display:flex;height:var(--md-divider-thickness, 1px);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:"";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}} -`; - - // node_modules/@material/web/divider/divider.js - var MdDivider = class MdDivider2 extends Divider { - }; - MdDivider.styles = [styles9]; - MdDivider = __decorate([ - t2("md-divider") - ], MdDivider); - - // node_modules/@material/web/internal/events/redispatch-event.js - function redispatchEvent(element, event) { - if (event.bubbles && (!element.shadowRoot || event.composed)) { - event.stopPropagation(); - } - const copy = Reflect.construct(event.constructor, [event.type, event]); - const dispatched = element.dispatchEvent(copy); - if (!dispatched) { - event.preventDefault(); - } - return dispatched; - } - - // node_modules/@material/web/dialog/internal/animations.js - var DIALOG_DEFAULT_OPEN_ANIMATION = { - dialog: [ - [ - // Dialog slide down - [{ "transform": "translateY(-50px)" }, { "transform": "translateY(0)" }], - { duration: 500, easing: EASING.EMPHASIZED } - ] - ], - scrim: [ - [ - // Scrim fade in - [{ "opacity": 0 }, { "opacity": 0.32 }], - { duration: 500, easing: "linear" } - ] - ], - container: [ - [ - // Container fade in - [{ "opacity": 0 }, { "opacity": 1 }], - { duration: 50, easing: "linear", pseudoElement: "::before" } - ], - [ - // Container grow - // Note: current spec says to grow from 0dp->100% and shrink from - // 100%->35%. We change this to 35%->100% to simplify the animation that - // is supposed to clip content as it grows. From 0dp it's possible to see - // text/actions appear before the container has fully grown. - [{ "height": "35%" }, { "height": "100%" }], - { duration: 500, easing: EASING.EMPHASIZED, pseudoElement: "::before" } - ] - ], - headline: [ - [ - // Headline fade in - [{ "opacity": 0 }, { "opacity": 0, offset: 0.2 }, { "opacity": 1 }], - { duration: 250, easing: "linear", fill: "forwards" } - ] - ], - content: [ - [ - // Content fade in - [{ "opacity": 0 }, { "opacity": 0, offset: 0.2 }, { "opacity": 1 }], - { duration: 250, easing: "linear", fill: "forwards" } - ] - ], - actions: [ - [ - // Actions fade in - [{ "opacity": 0 }, { "opacity": 0, offset: 0.5 }, { "opacity": 1 }], - { duration: 300, easing: "linear", fill: "forwards" } - ] - ] - }; - var DIALOG_DEFAULT_CLOSE_ANIMATION = { - dialog: [ - [ - // Dialog slide up - [{ "transform": "translateY(0)" }, { "transform": "translateY(-50px)" }], - { duration: 150, easing: EASING.EMPHASIZED_ACCELERATE } - ] - ], - scrim: [ - [ - // Scrim fade out - [{ "opacity": 0.32 }, { "opacity": 0 }], - { duration: 150, easing: "linear" } - ] - ], - container: [ - [ - // Container shrink - [{ "height": "100%" }, { "height": "35%" }], - { - duration: 150, - easing: EASING.EMPHASIZED_ACCELERATE, - pseudoElement: "::before" - } - ], - [ - // Container fade out - [{ "opacity": "1" }, { "opacity": "0" }], - { delay: 100, duration: 50, easing: "linear", pseudoElement: "::before" } - ] - ], - headline: [ - [ - // Headline fade out - [{ "opacity": 1 }, { "opacity": 0 }], - { duration: 100, easing: "linear", fill: "forwards" } - ] - ], - content: [ - [ - // Content fade out - [{ "opacity": 1 }, { "opacity": 0 }], - { duration: 100, easing: "linear", fill: "forwards" } - ] - ], - actions: [ - [ - // Actions fade out - [{ "opacity": 1 }, { "opacity": 0 }], - { duration: 100, easing: "linear", fill: "forwards" } - ] - ] - }; - - // node_modules/@material/web/dialog/internal/dialog.js - var dialogBaseClass = mixinDelegatesAria(h3); - var Dialog = class extends dialogBaseClass { - // We do not use `delegatesFocus: true` due to a Chromium bug with - // selecting text. - // See https://bugs.chromium.org/p/chromium/issues/detail?id=950357 - /** - * Opens the dialog when set to `true` and closes it when set to `false`. - */ - get open() { - return this.isOpen; - } - set open(open) { - if (open === this.isOpen) { - return; - } - this.isOpen = open; - if (open) { - this.setAttribute("open", ""); - this.show(); - } else { - this.removeAttribute("open"); - this.close(); - } - } - constructor() { - super(); - this.quick = false; - this.returnValue = ""; - this.noFocusTrap = false; - this.getOpenAnimation = () => DIALOG_DEFAULT_OPEN_ANIMATION; - this.getCloseAnimation = () => DIALOG_DEFAULT_CLOSE_ANIMATION; - this.isOpen = false; - this.isOpening = false; - this.isConnectedPromise = this.getIsConnectedPromise(); - this.isAtScrollTop = false; - this.isAtScrollBottom = false; - this.nextClickIsFromContent = false; - this.hasHeadline = false; - this.hasActions = false; - this.hasIcon = false; - this.escapePressedWithoutCancel = false; - this.treewalker = co ? null : document.createTreeWalker(this, NodeFilter.SHOW_ELEMENT); - if (!co) { - this.addEventListener("submit", this.handleSubmit); - } - } - /** - * Opens the dialog and fires a cancelable `open` event. After a dialog's - * animation, an `opened` event is fired. - * - * Add an `autofocus` attribute to a child of the dialog that should - * receive focus after opening. - * - * @return A Promise that resolves after the animation is finished and the - * `opened` event was fired. - */ - async show() { - this.isOpening = true; - await this.isConnectedPromise; - await this.updateComplete; - const dialog = this.dialog; - if (dialog.open || !this.isOpening) { - this.isOpening = false; - return; - } - const preventOpen = !this.dispatchEvent(new Event("open", { cancelable: true })); - if (preventOpen) { - this.open = false; - this.isOpening = false; - return; - } - dialog.showModal(); - this.open = true; - if (this.scroller) { - this.scroller.scrollTop = 0; - } - this.querySelector("[autofocus]")?.focus(); - await this.animateDialog(this.getOpenAnimation()); - this.dispatchEvent(new Event("opened")); - this.isOpening = false; - } - /** - * Closes the dialog and fires a cancelable `close` event. After a dialog's - * animation, a `closed` event is fired. - * - * @param returnValue A return value usually indicating which button was used - * to close a dialog. If a dialog is canceled by clicking the scrim or - * pressing Escape, it will not change the return value after closing. - * @return A Promise that resolves after the animation is finished and the - * `closed` event was fired. - */ - async close(returnValue = this.returnValue) { - this.isOpening = false; - if (!this.isConnected) { - this.open = false; - return; - } - await this.updateComplete; - const dialog = this.dialog; - if (!dialog.open || this.isOpening) { - this.open = false; - return; - } - const prevReturnValue = this.returnValue; - this.returnValue = returnValue; - const preventClose = !this.dispatchEvent(new Event("close", { cancelable: true })); - if (preventClose) { - this.returnValue = prevReturnValue; - return; - } - await this.animateDialog(this.getCloseAnimation()); - dialog.close(returnValue); - this.open = false; - this.dispatchEvent(new Event("closed")); - } - connectedCallback() { - super.connectedCallback(); - this.isConnectedPromiseResolve(); - } - disconnectedCallback() { - super.disconnectedCallback(); - this.isConnectedPromise = this.getIsConnectedPromise(); - } - render() { - const scrollable = this.open && !(this.isAtScrollTop && this.isAtScrollBottom); - const classes = { - "has-headline": this.hasHeadline, - "has-actions": this.hasActions, - "has-icon": this.hasIcon, - "scrollable": scrollable, - "show-top-divider": scrollable && !this.isAtScrollTop, - "show-bottom-divider": scrollable && !this.isAtScrollBottom - }; - const showFocusTrap = this.open && !this.noFocusTrap; - const focusTrap = ke` - - `; - const { ariaLabel } = this; - return ke` -
- - ${showFocusTrap ? focusTrap : D} -
-
- -

- -

- -
-
-
-
- -
-
-
-
- - -
-
- ${showFocusTrap ? focusTrap : D} -
- `; - } - firstUpdated() { - this.intersectionObserver = new IntersectionObserver((entries) => { - for (const entry of entries) { - this.handleAnchorIntersection(entry); - } - }, { root: this.scroller }); - this.intersectionObserver.observe(this.topAnchor); - this.intersectionObserver.observe(this.bottomAnchor); - } - handleDialogClick() { - if (this.nextClickIsFromContent) { - this.nextClickIsFromContent = false; - return; - } - const preventDefault = !this.dispatchEvent(new Event("cancel", { cancelable: true })); - if (preventDefault) { - return; - } - this.close(); - } - handleContentClick() { - this.nextClickIsFromContent = true; - } - handleSubmit(event) { - const form = event.target; - const { submitter } = event; - if (form.method !== "dialog" || !submitter) { - return; - } - this.close(submitter.getAttribute("value") ?? this.returnValue); - } - handleCancel(event) { - if (event.target !== this.dialog) { - return; - } - this.escapePressedWithoutCancel = false; - const preventDefault = !redispatchEvent(this, event); - event.preventDefault(); - if (preventDefault) { - return; - } - this.close(); - } - handleClose() { - if (!this.escapePressedWithoutCancel) { - return; - } - this.escapePressedWithoutCancel = false; - this.dialog?.dispatchEvent(new Event("cancel", { cancelable: true })); - } - handleKeydown(event) { - if (event.key !== "Escape") { - return; - } - this.escapePressedWithoutCancel = true; - setTimeout(() => { - this.escapePressedWithoutCancel = false; - }); - } - async animateDialog(animation) { - this.cancelAnimations?.abort(); - this.cancelAnimations = new AbortController(); - if (this.quick) { - return; - } - const { dialog, scrim, container, headline, content, actions } = this; - if (!dialog || !scrim || !container || !headline || !content || !actions) { - return; - } - const { container: containerAnimate, dialog: dialogAnimate, scrim: scrimAnimate, headline: headlineAnimate, content: contentAnimate, actions: actionsAnimate } = animation; - const elementAndAnimation = [ - [dialog, dialogAnimate ?? []], - [scrim, scrimAnimate ?? []], - [container, containerAnimate ?? []], - [headline, headlineAnimate ?? []], - [content, contentAnimate ?? []], - [actions, actionsAnimate ?? []] - ]; - const animations = []; - for (const [element, animation2] of elementAndAnimation) { - for (const animateArgs of animation2) { - const animation3 = element.animate(...animateArgs); - this.cancelAnimations.signal.addEventListener("abort", () => { - animation3.cancel(); - }); - animations.push(animation3); - } - } - await Promise.all(animations.map((animation2) => animation2.finished.catch(() => { - }))); - } - handleHeadlineChange(event) { - const slot = event.target; - this.hasHeadline = slot.assignedElements().length > 0; - } - handleActionsChange(event) { - const slot = event.target; - this.hasActions = slot.assignedElements().length > 0; - } - handleIconChange(event) { - const slot = event.target; - this.hasIcon = slot.assignedElements().length > 0; - } - handleAnchorIntersection(entry) { - const { target, isIntersecting } = entry; - if (target === this.topAnchor) { - this.isAtScrollTop = isIntersecting; - } - if (target === this.bottomAnchor) { - this.isAtScrollBottom = isIntersecting; - } - } - getIsConnectedPromise() { - return new Promise((resolve) => { - this.isConnectedPromiseResolve = resolve; - }); - } - handleFocusTrapFocus(event) { - const [firstFocusableChild, lastFocusableChild] = this.getFirstAndLastFocusableChildren(); - if (!firstFocusableChild || !lastFocusableChild) { - this.dialog?.focus(); - return; - } - const isFirstFocusTrap = event.target === this.firstFocusTrap; - const isLastFocusTrap = !isFirstFocusTrap; - const focusCameFromFirstChild = event.relatedTarget === firstFocusableChild; - const focusCameFromLastChild = event.relatedTarget === lastFocusableChild; - const focusCameFromOutsideDialog = !focusCameFromFirstChild && !focusCameFromLastChild; - const shouldFocusFirstChild = isLastFocusTrap && focusCameFromLastChild || isFirstFocusTrap && focusCameFromOutsideDialog; - if (shouldFocusFirstChild) { - firstFocusableChild.focus(); - return; - } - const shouldFocusLastChild = isFirstFocusTrap && focusCameFromFirstChild || isLastFocusTrap && focusCameFromOutsideDialog; - if (shouldFocusLastChild) { - lastFocusableChild.focus(); - return; - } - } - getFirstAndLastFocusableChildren() { - if (!this.treewalker) { - return [null, null]; - } - let firstFocusableChild = null; - let lastFocusableChild = null; - this.treewalker.currentNode = this.treewalker.root; - while (this.treewalker.nextNode()) { - const nextChild = this.treewalker.currentNode; - if (!isFocusable(nextChild)) { - continue; - } - if (!firstFocusableChild) { - firstFocusableChild = nextChild; - } - lastFocusableChild = nextChild; - } - return [firstFocusableChild, lastFocusableChild]; - } - }; - __decorate([ - n4({ type: Boolean }) - ], Dialog.prototype, "open", null); - __decorate([ - n4({ type: Boolean }) - ], Dialog.prototype, "quick", void 0); - __decorate([ - n4({ attribute: false }) - ], Dialog.prototype, "returnValue", void 0); - __decorate([ - n4() - ], Dialog.prototype, "type", void 0); - __decorate([ - n4({ type: Boolean, attribute: "no-focus-trap" }) - ], Dialog.prototype, "noFocusTrap", void 0); - __decorate([ - e4("dialog") - ], Dialog.prototype, "dialog", void 0); - __decorate([ - e4(".scrim") - ], Dialog.prototype, "scrim", void 0); - __decorate([ - e4(".container") - ], Dialog.prototype, "container", void 0); - __decorate([ - e4(".headline") - ], Dialog.prototype, "headline", void 0); - __decorate([ - e4(".content") - ], Dialog.prototype, "content", void 0); - __decorate([ - e4(".actions") - ], Dialog.prototype, "actions", void 0); - __decorate([ - r4() - ], Dialog.prototype, "isAtScrollTop", void 0); - __decorate([ - r4() - ], Dialog.prototype, "isAtScrollBottom", void 0); - __decorate([ - e4(".scroller") - ], Dialog.prototype, "scroller", void 0); - __decorate([ - e4(".top.anchor") - ], Dialog.prototype, "topAnchor", void 0); - __decorate([ - e4(".bottom.anchor") - ], Dialog.prototype, "bottomAnchor", void 0); - __decorate([ - e4(".focus-trap") - ], Dialog.prototype, "firstFocusTrap", void 0); - __decorate([ - r4() - ], Dialog.prototype, "hasHeadline", void 0); - __decorate([ - r4() - ], Dialog.prototype, "hasActions", void 0); - __decorate([ - r4() - ], Dialog.prototype, "hasIcon", void 0); - function isFocusable(element) { - const knownFocusableElements = ":is(button,input,select,textarea,object,:is(a,area)[href],[tabindex],[contenteditable=true])"; - const notDisabled = ":not(:disabled,[disabled])"; - const notNegativeTabIndex = ':not([tabindex^="-"])'; - if (element.matches(knownFocusableElements + notDisabled + notNegativeTabIndex)) { - return true; - } - const isCustomElement = element.localName.includes("-"); - if (!isCustomElement) { - return false; - } - if (!element.matches(notDisabled)) { - return false; - } - return element.shadowRoot?.delegatesFocus ?? false; - } - - // node_modules/@material/web/dialog/internal/dialog-styles.js - var styles10 = i`:host{border-start-start-radius:var(--md-dialog-container-shape-start-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-start-end-radius:var(--md-dialog-container-shape-start-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-end-radius:var(--md-dialog-container-shape-end-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-start-radius:var(--md-dialog-container-shape-end-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));display:contents;margin:auto;max-height:min(560px,100% - 48px);max-width:min(560px,100% - 48px);min-height:140px;min-width:280px;position:fixed;height:fit-content;width:fit-content}dialog{background:rgba(0,0,0,0);border:none;border-radius:inherit;flex-direction:column;height:inherit;margin:inherit;max-height:inherit;max-width:inherit;min-height:inherit;min-width:inherit;outline:none;overflow:visible;padding:0;width:inherit}dialog[open]{display:flex}::backdrop{background:none}.scrim{background:var(--md-sys-color-scrim, #000);display:none;inset:0;opacity:32%;pointer-events:none;position:fixed;z-index:1}:host([open]) .scrim{display:flex}h2{all:unset;align-self:stretch}.headline{align-items:center;color:var(--md-dialog-headline-color, var(--md-sys-color-on-surface, #1d1b20));display:flex;flex-direction:column;font-family:var(--md-dialog-headline-font, var(--md-sys-typescale-headline-small-font, var(--md-ref-typeface-brand, Roboto)));font-size:var(--md-dialog-headline-size, var(--md-sys-typescale-headline-small-size, 1.5rem));line-height:var(--md-dialog-headline-line-height, var(--md-sys-typescale-headline-small-line-height, 2rem));font-weight:var(--md-dialog-headline-weight, var(--md-sys-typescale-headline-small-weight, var(--md-ref-typeface-weight-regular, 400)));position:relative}slot[name=headline]::slotted(*){align-items:center;align-self:stretch;box-sizing:border-box;display:flex;gap:8px;padding:24px 24px 0}.icon{display:flex}slot[name=icon]::slotted(*){color:var(--md-dialog-icon-color, var(--md-sys-color-secondary, #625b71));fill:currentColor;font-size:var(--md-dialog-icon-size, 24px);margin-top:24px;height:var(--md-dialog-icon-size, 24px);width:var(--md-dialog-icon-size, 24px)}.has-icon slot[name=headline]::slotted(*){justify-content:center;padding-top:16px}.scrollable slot[name=headline]::slotted(*){padding-bottom:16px}.scrollable.has-headline slot[name=content]::slotted(*){padding-top:8px}.container{border-radius:inherit;display:flex;flex-direction:column;flex-grow:1;overflow:hidden;position:relative;transform-origin:top}.container::before{background:var(--md-dialog-container-color, var(--md-sys-color-surface-container-high, #ece6f0));border-radius:inherit;content:"";inset:0;position:absolute}.scroller{display:flex;flex:1;flex-direction:column;overflow:hidden;z-index:1}.scrollable .scroller{overflow-y:scroll}.content{color:var(--md-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-dialog-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-dialog-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-dialog-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));flex:1;font-weight:var(--md-dialog-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)));height:min-content;position:relative}slot[name=content]::slotted(*){box-sizing:border-box;padding:24px}.anchor{position:absolute}.top.anchor{top:0}.bottom.anchor{bottom:0}.actions{position:relative}slot[name=actions]::slotted(*){box-sizing:border-box;display:flex;gap:8px;justify-content:flex-end;padding:16px 24px 24px}.has-actions slot[name=content]::slotted(*){padding-bottom:8px}md-divider{display:none;position:absolute}.has-headline.show-top-divider .headline md-divider,.has-actions.show-bottom-divider .actions md-divider{display:flex}.headline md-divider{bottom:0}.actions md-divider{top:0}@media(forced-colors: active){dialog{outline:2px solid WindowText}} -`; - - // node_modules/@material/web/dialog/dialog.js - var MdDialog = class MdDialog2 extends Dialog { - }; - MdDialog.styles = [styles10]; - MdDialog = __decorate([ - t2("md-dialog") - ], MdDialog); - - // node_modules/@material/web/icon/internal/icon.js - var Icon = class extends h3 { - render() { - return ke``; - } - connectedCallback() { - super.connectedCallback(); - const ariaHidden = this.getAttribute("aria-hidden"); - if (ariaHidden === "false") { - this.removeAttribute("aria-hidden"); - return; - } - this.setAttribute("aria-hidden", "true"); - } - }; - - // node_modules/@material/web/icon/internal/icon-styles.js - var styles11 = i`:host{font-size:var(--md-icon-size, 24px);width:var(--md-icon-size, 24px);height:var(--md-icon-size, 24px);color:inherit;font-variation-settings:inherit;font-weight:400;font-family:var(--md-icon-font, Material Symbols Outlined);display:inline-flex;font-style:normal;place-items:center;place-content:center;line-height:1;overflow:hidden;letter-spacing:normal;text-transform:none;user-select:none;white-space:nowrap;word-wrap:normal;flex-shrink:0;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale}::slotted(svg){fill:currentColor}::slotted(*){height:100%;width:100%} -`; - - // node_modules/@material/web/icon/icon.js - var MdIcon = class MdIcon2 extends Icon { - }; - MdIcon.styles = [styles11]; - MdIcon = __decorate([ - t2("md-icon") - ], MdIcon); - - // node_modules/lit-html/static.js - var $e = Symbol.for(""); - var xe = (t4) => { - if (t4?.r === $e) - return t4?._$litStatic$; - }; - var er = (t4, ...r5) => ({ _$litStatic$: r5.reduce((r6, e6, a2) => r6 + ((t5) => { - if (void 0 !== t5._$litStatic$) - return t5._$litStatic$; - throw Error(`Value passed to 'literal' function must be a 'literal' result: ${t5}. Use 'unsafeStatic' to pass non-literal values, but - take care to ensure page security.`); - })(e6) + t4[a2 + 1], t4[0]), r: $e }); - var Te = /* @__PURE__ */ new Map(); - var Ee = (t4) => (r5, ...e6) => { - const a2 = e6.length; - let o5, s2; - const i4 = [], l2 = []; - let n5, u2 = 0, c4 = false; - for (; u2 < a2; ) { - for (n5 = r5[u2]; u2 < a2 && void 0 !== (s2 = e6[u2], o5 = xe(s2)); ) - n5 += o5 + r5[++u2], c4 = true; - u2 !== a2 && l2.push(s2), i4.push(n5), u2++; - } - if (u2 === a2 && i4.push(r5[a2]), c4) { - const t5 = i4.join("$$lit$$"); - void 0 === (r5 = Te.get(t5)) && (i4.raw = i4, Te.set(t5, r5 = i4)), e6 = l2; - } - return t4(r5, ...e6); - }; - var ke2 = Ee(ke); - var Oe2 = Ee(Oe); - var Se2 = Ee(Se); - - // node_modules/@material/web/internal/controller/is-rtl.js - function isRtl(el, shouldCheck = true) { - return shouldCheck && getComputedStyle(el).getPropertyValue("direction").trim() === "rtl"; - } - - // node_modules/@material/web/iconbutton/internal/icon-button.js - var iconButtonBaseClass = mixinDelegatesAria(mixinElementInternals(h3)); - var IconButton = class extends iconButtonBaseClass { - get name() { - return this.getAttribute("name") ?? ""; - } - set name(name) { - this.setAttribute("name", name); - } - /** - * The associated form element with which this element's value will submit. - */ - get form() { - return this[internals].form; - } - /** - * The labels this element is associated with. - */ - get labels() { - return this[internals].labels; - } - constructor() { - super(); - this.disabled = false; - this.softDisabled = false; - this.flipIconInRtl = false; - this.href = ""; - this.target = ""; - this.ariaLabelSelected = ""; - this.toggle = false; - this.selected = false; - this.type = "submit"; - this.value = ""; - this.flipIcon = isRtl(this, this.flipIconInRtl); - if (!co) { - this.addEventListener("click", this.handleClick.bind(this)); - } - } - willUpdate() { - if (this.href) { - this.disabled = false; - this.softDisabled = false; - } - } - render() { - const tag = this.href ? er`div` : er`button`; - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - const hasToggledAriaLabel = ariaLabel && this.ariaLabelSelected; - const ariaPressedValue = !this.toggle ? D : this.selected; - let ariaLabelValue = D; - if (!this.href) { - ariaLabelValue = hasToggledAriaLabel && this.selected ? this.ariaLabelSelected : ariaLabel; - } - return ke2`<${tag} - class="icon-button ${Rt(this.getRenderClasses())}" - id="button" - aria-label="${ariaLabelValue || D}" - aria-haspopup="${!this.href && ariaHasPopup || D}" - aria-expanded="${!this.href && ariaExpanded || D}" - aria-pressed="${ariaPressedValue}" - aria-disabled=${!this.href && this.softDisabled || D} - ?disabled="${!this.href && this.disabled}" - @click="${this.handleClickOnChild}"> - ${this.renderFocusRing()} - ${this.renderRipple()} - ${!this.selected ? this.renderIcon() : D} - ${this.selected ? this.renderSelectedIcon() : D} - ${this.renderTouchTarget()} - ${this.href && this.renderLink()} - `; - } - renderLink() { - const { ariaLabel } = this; - return ke` - - `; - } - getRenderClasses() { - return { - "flip-icon": this.flipIcon, - "selected": this.toggle && this.selected - }; - } - renderIcon() { - return ke``; - } - renderSelectedIcon() { - return ke``; - } - renderTouchTarget() { - return ke``; - } - renderFocusRing() { - return ke``; - } - renderRipple() { - const isRippleDisabled = !this.href && (this.disabled || this.softDisabled); - return ke``; - } - connectedCallback() { - this.flipIcon = isRtl(this, this.flipIconInRtl); - super.connectedCallback(); - } - /** Handles a click on this element. */ - handleClick(event) { - if (!this.href && this.softDisabled) { - event.stopImmediatePropagation(); - event.preventDefault(); - return; - } - } - /** - * Handles a click on the child
or
`; - }); - return import_nanohtml6.default` -
- ${list} -
- `; - } - function blockSvg() { - return import_nanohtml6.default` - - - - - `; - } - - // v2/components/key-insights.jsx - function KeyInsights() { - const data = useData(); - return /* @__PURE__ */ y("div", { id: "key-insight" }, /* @__PURE__ */ y(DomNode, { key: data.count }, renderKeyInsight(data))); - } - function KeyInsightsMain({ title, children, icon = "chat" }) { - return /* @__PURE__ */ y("div", { className: "key-insight key-insight--main" }, /* @__PURE__ */ y("div", { className: `key-insight__icon hero-icon--${icon}` }), /* @__PURE__ */ y("h1", { className: "token-title-3-em" }, title), /* @__PURE__ */ y("div", { className: "token-title-3" }, /* @__PURE__ */ y("span", null, children))); - } - - // shared/js/ui/templates/protection-header.js - var import_nanohtml7 = __toESM(require_browser()); - - // shared/js/ui/components/text-link.jsx - function TextLink(props) { - const { onClick, rounded = false } = props; - const ref = _(null); - useRipple({ ref }); - let classNames = [`link-action`, `link-action--text`]; - if (rounded) - classNames.push(`link-action--rounded`); - return /* @__PURE__ */ y("a", { href: "javascript:void(0)", className: classNames.join(" "), draggable: false, ref, onClick }, props.children); - } - function PlainTextLink({ children, className, ...rest }) { - const classes = ["text-link-as-button"]; - if (className) - classes.push(className); - return /* @__PURE__ */ y("a", { href: "javascript:void(0)", className: classes.join(" "), draggable: false, ...rest }, children); - } - - // shared/js/ui/components/toggle.jsx - function ProtectionToggle(props) { - const [toggleState, toggle] = useToggleState(props.model, props.toggle); - const altText = ns.site("updatingProtectionList.title"); - return /* @__PURE__ */ y("div", { class: `site-info-toggle ${toggleState.active ? "is-active" : ""}` }, /* @__PURE__ */ y("p", { class: "site-info__protection" }, /* @__PURE__ */ y("span", { role: "textbox", dangerouslySetInnerHTML: { __html: toggleState.text } })), /* @__PURE__ */ y("div", { class: "site-info__toggle-container" }, toggleState.toggled && /* @__PURE__ */ y("img", { src: "../img/spinner.svg", className: "toggle-spinner", alt: altText }), !toggleState.toggled && /* @__PURE__ */ y(ToggleButton, { toggleState, onToggle: toggle }))); - } - function useToggleState(model, toggle) { - const [state, setState] = h2(() => { - const toggleState = { - text: ns.site("protectionsEnabled.title"), - active: true, - disabled: false, - label: "", - toggled: false, - sideEffects: false - }; - if (!model.protectionsEnabled) { - toggleState.text = ns.site("protectionsDisabled.title"); - toggleState.active = false; - } - if (model.isBroken) { - if (!isBrowser()) { - toggleState.active = false; - toggleState.disabled = true; - } - } - const labelEnabled = ns.site("enableProtectionsSwitch.title"); - const labelDisabled = ns.site("disableProtectionsSwitch.title"); - toggleState.label = toggleState.active ? labelDisabled : labelEnabled; - return toggleState; - }); - p2(() => { - if (!state.sideEffects) - return; - const isReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches === true; - const timeout = isReducedMotion ? 0 : 300; - const int = setTimeout(() => { - toggle(); - if (model.features.spinnerFollowingProtectionsToggle) { - setState((prev) => { - return { ...prev, toggled: true }; - }); - } - }, timeout); - return () => { - clearTimeout(int); - }; - }, [state.active, state.sideEffects]); - function toggleInternal() { - setState((prev) => { - return { ...prev, active: !prev.active, sideEffects: true }; - }); - } - return [state, toggleInternal]; - } - function ToggleButton(props) { - const { toggleState } = props; - const labelEnabled = ns.site("enableProtectionsSwitch.title"); - const labelDisabled = ns.site("disableProtectionsSwitch.title"); - const label = toggleState.active ? labelDisabled : labelEnabled; - return /* @__PURE__ */ y(DefaultToggleButton, { toggleState, label, onToggle: props.onToggle }); - } - function DefaultToggleButton(props) { - const { toggleState, label } = props; - return /* @__PURE__ */ y( - "button", - { - class: "toggle-button", - type: "button", - role: "switch", - "aria-checked": toggleState.active, - "aria-label": label, - disabled: toggleState.disabled, - onClick: props.onToggle - }, - /* @__PURE__ */ y("div", { class: "toggle-button__track" }), - /* @__PURE__ */ y("div", { class: "toggle-button__handle" }) - ); - } - - // shared/js/ui/templates/protection-header.js - var ProtectionContext = G( - /** @type {{state: UIState, setState: (st: UIState) => void; model: MigrationModel}} */ - {} - ); - function ProtectionHeader({ model, initialState, toggle, children, ...rest }) { - let initial; - if (initialState) { - initial = initialState; - } else { - if (model.isBroken || model.isAllowlisted) { - initial = "form-trigger"; - } else { - initial = "help-trigger"; - } - } - const [state, setState] = h2( - /** @type {UIState} */ - initial - ); - return /* @__PURE__ */ y("div", { ...rest }, /* @__PURE__ */ y("div", { class: "card-list--bordered" }, model.isBroken && /* @__PURE__ */ y(HeaderDisabled, { model, state, toggle }), !model.isBroken && /* @__PURE__ */ y(HeaderDefault, { model, state, toggle })), /* @__PURE__ */ y( - ProtectionContext.Provider, - { - value: { - state, - setState, - model - } - }, - children - )); - } - function HeaderDefault(props) { - const text = ns.site("websiteNotWorkingAdvice.title"); - const showHelp = props.state === "site-not-working" && !props.model.isAllowlisted; - return /* @__PURE__ */ y("div", { className: "protection-toggle" }, /* @__PURE__ */ y("div", { className: "protection-toggle__row" }, /* @__PURE__ */ y(ProtectionToggle, { model: props.model, toggle: props.toggle })), showHelp && /* @__PURE__ */ y("div", { className: "protection-toggle__row protection-toggle__row--alt" }, text)); - } - function HeaderDisabled(props) { - let text = i18n.t("site:protectionsDisabledRemote.title"); - if (props.model.isDenylisted) { - text = i18n.t("site:protectionsDisabledRemoteOverride.title"); - } - return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y("div", { className: "padding-x padding-y--reduced" }, /* @__PURE__ */ y(ProtectionToggle, { model: props.model, toggle: props.toggle })), /* @__PURE__ */ y("div", { className: "note note--nested" }, text)); - } - - // v2/components/protection-header.jsx - function ProtectionHeader2() { - const { push } = useNav(); - const data = useData(); - const onToggle = useToggle(); - const fetcher = useFetcher(); - const { breakageScreen } = useFeatures(); - const featureSettings2 = useFeatureSettings(); - return /* @__PURE__ */ y("div", { "data-testid": "protectionHeader" }, /* @__PURE__ */ y(ProtectionHeader, { model: data, toggle: onToggle }, /* @__PURE__ */ y("div", { className: "text--center" }, /* @__PURE__ */ y( - TextLink, - { - onClick: () => { - fetcher(new CheckBrokenSiteReportHandledMessage()).then(() => { - if (featureSettings2.webBreakageForm.state === "enabled") { - push(breakageScreen); - } - }).catch(console.error); - }, - rounded: true - }, - ns.site("websiteNotWorkingPrompt.title") - )))); - } - - // shared/js/ui/views/fire-dialog.js - var import_nanohtml8 = __toESM(require_browser()); - var import_raw3 = __toESM(require_raw_browser()); - function fireSummaryTemplate(selectedOption) { - const { descriptionStats } = selectedOption; - let template2 = "firebutton:summary"; - if (descriptionStats.clearHistory && descriptionStats.openTabs) { - template2 += "ClearTabsHistory"; - } else if (descriptionStats.clearHistory && !descriptionStats.openTabs) { - template2 += "ClearHistory"; - } else if (!descriptionStats.clearHistory && descriptionStats.openTabs) { - template2 += "ClearTabs"; - } else { - template2 += "ClearCookies"; - } - if (descriptionStats.site) { - template2 += "Site"; - } else if (descriptionStats.duration === "all") { - template2 += "All"; - } else { - template2 += "Duration"; - } - template2 += ".title"; - return import_nanohtml8.default`
-

- ${(0, import_raw3.default)( - i18n.t(template2, { - durationDesc: i18n.t("firebutton:historyDuration.title", { duration: descriptionStats.duration }), - ...descriptionStats - }) - )} -

- ${descriptionStats.site && descriptionStats.clearHistory ? import_nanohtml8.default`

${i18n.t("firebutton:historyAndDownloadsNotAffected.title")}

` : null} - ${descriptionStats.openTabs && descriptionStats.pinnedTabs ? import_nanohtml8.default`

- ${(0, import_raw3.default)(i18n.t("firebutton:summaryPinnedIgnored.title", { tabs: descriptionStats.pinnedTabs }))} -

` : null} -
`; - } - - // v2/components/fire-dialog.jsx - function FireProvider({ onCancel }) { - const [fireOptions, setFireOptions] = h2( - /** @type {null | FireOption[]} */ - null - ); - const fetcher = useFetcher(); - p2(() => { - const msg = new FetchBurnOptions(); - fetcher(msg).then((resp) => { - setFireOptions(resp.options); - }).catch(console.error); - }, [fetcher]); - function onUpdate(index) { - if (!fireOptions) - return; - const selectedOption = index; - const opts = fireOptions[selectedOption]; - fetcher(new SetBurnDefaultOption(opts.name)).catch(console.error); - } - function onBurn(index) { - if (!fireOptions) - return; - const selectedOption = index; - const opts = fireOptions[selectedOption].options; - fetcher(new BurnMessage( - /** @type {any} */ - opts - )).then(() => { - onCancel(); - }); - } - if (fireOptions === null) - return null; - return /* @__PURE__ */ y(FireDialog, { fireOptions, onUpdate, onCancel, onBurn }); - } - function FireDialog({ fireOptions, onUpdate, onCancel, onBurn }) { - if (!fireOptions) { - return /* @__PURE__ */ y("dialog", { id: "fire-button-container" }); - } - let selectedOptionIndex = fireOptions.findIndex(({ selected }) => selected); - if (selectedOptionIndex < 0) { - selectedOptionIndex = 0; - } - const [value, setValue] = h2(selectedOptionIndex); - const selectedOption = fireOptions[value]; - const selectOptions = fireOptions.map(({ name }, index) => /* @__PURE__ */ y("option", { value: index }, i18n.t(`firebutton:option${name}.title`))); - const summary = fireSummaryTemplate(selectedOption); - function onChange(e3) { - setValue(Number(e3.target.value)); - onUpdate(Number(e3.target.value)); - } - return /* @__PURE__ */ y("dialog", { id: "fire-button-container", open: true }, /* @__PURE__ */ y("div", { id: "fire-button-content" }, /* @__PURE__ */ y("span", { id: "fire-button-header" }, /* @__PURE__ */ y("img", { src: "../img/fire-button-header.svg" }), /* @__PURE__ */ y("h3", null, selectedOption.descriptionStats.openTabs > 0 ? i18n.t("firebutton:fireDialogHeader.title") : i18n.t("firebutton:fireDialogHeaderNoTabs.title"))), /* @__PURE__ */ y("select", { id: "fire-button-opts", onChange, value }, selectOptions), /* @__PURE__ */ y(DomNode, null, summary), /* @__PURE__ */ y("div", { id: "fire-button-row" }, /* @__PURE__ */ y("button", { id: "fire-button-cancel", onClick: onCancel }, i18n.t("firebutton:cancel.title")), /* @__PURE__ */ y("button", { id: "fire-button-burn", onClick: () => onBurn(value) }, i18n.t("firebutton:clearData.title"))))); - } - - // v2/components/search-bar.jsx - function SearchBar() { - const data = useData(); - const fetcher = useFetcher(); - const showFireButton = data.fireButton?.enabled === true; - const [focussed, setFocussed] = h2(false); - const [fireDialogOpen, setFireDialogOpen] = h2(false); - function openSettings() { - const msg = new OpenOptionsMessage(); - fetcher(msg).catch(console.error); - } - function openFire() { - setFireDialogOpen(true); - } - function doSearch(e3) { - e3.preventDefault(); - const values = Object.fromEntries(new FormData(e3.target)); - if (!values.q || !(typeof values.q === "string")) { - return console.warn("missing value"); - } - const msg = new SearchMessage({ term: values.q }); - fetcher(msg).catch(console.error); - } - const fireButton = showFireButton ? /* @__PURE__ */ y("button", { type: "button", class: "fire-button", onClick: openFire }, /* @__PURE__ */ y(FireIcon, null)) : null; - if (!data.tab.search) - return null; - return /* @__PURE__ */ y("div", { className: "search token-search-input" }, /* @__PURE__ */ y("form", { className: "search-form", name: "x", "data-test-id": "search-form", "data-focussed": focussed, onSubmit: doSearch }, /* @__PURE__ */ y( - "input", - { - type: "text", - autoComplete: "off", - autoFocus: true, - placeholder: ns.site("searchPlaceholder.title"), - name: "q", - className: "search-form__input", - defaultValue: "", - onInput: (e3) => setFocussed(e3.target.value.length > 0), - onBlur: () => setFocussed(false), - onFocus: (e3) => setFocussed(e3.target.value.length > 0) - } - ), /* @__PURE__ */ y("button", { className: "search-form__go", type: "submit", "aria-label": ns.site("searchGoButton.title") }, /* @__PURE__ */ y(LoupeIcon, null))), fireButton, fireDialogOpen ? /* @__PURE__ */ y(FireProvider, { onCancel: () => setFireDialogOpen(false) }) : null, /* @__PURE__ */ y("button", { type: "button", className: "cog-button", "aria-label": ns.site("optionsButton.title"), onClick: openSettings }, /* @__PURE__ */ y(CogIcon, null))); - } - function LoupeIcon() { - return /* @__PURE__ */ y("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y("rect", { class: "loupe-handle", x: "11.5", y: "12.9142", width: "2", height: "6", rx: "1", transform: "rotate(-45 11.5 12.9142)" }), /* @__PURE__ */ y( - "path", - { - class: "loupe-glass", - d: "M12.6976 5.27292C14.7478 7.32317 14.7478 10.6473 12.6976 12.6975C10.6473 14.7478 7.32322 14.7478 5.27297 12.6975C3.22272 10.6473 3.22272 7.32317 5.27297 5.27292C7.32322 3.22267 10.6473 3.22267 12.6976 5.27292Z", - "stroke-width": "1.5" - } - )); - } - function CogIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y( - "path", - { - class: "settings-cog", - "fill-rule": "evenodd", - "clip-rule": "evenodd", - d: "M3.43351 13.1462C3.06364 14.0391 3.48767 15.0628 4.3806 15.4327L5.30448 15.8154C6.19741 16.1853 7.2211 15.7612 7.59096 14.8683L7.84778 14.2483C7.89842 14.2495 7.94918 14.2501 8.00007 14.2501C8.05068 14.2501 8.10118 14.2495 8.15154 14.2483L8.40831 14.8682C8.77818 15.7611 9.80187 16.1852 10.6948 15.8153L11.6187 15.4326C12.5116 15.0628 12.9356 14.0391 12.5658 13.1461L12.3093 12.527C12.3828 12.457 12.4546 12.3853 12.5247 12.3118L13.1437 12.5682C14.0366 12.9381 15.0603 12.514 15.4302 11.6211L15.8129 10.6972C16.1827 9.8043 15.7587 8.7806 14.8658 8.41074L14.2482 8.15493C14.2494 8.10345 14.2501 8.05185 14.2501 8.00011C14.2501 7.94964 14.2495 7.89928 14.2483 7.84905L14.8659 7.59324C15.7588 7.22337 16.1828 6.19968 15.8129 5.30675L15.4303 4.38287C15.0604 3.48994 14.0367 3.06592 13.1438 3.43578L12.5273 3.69115C12.4568 3.61712 12.3845 3.54482 12.3105 3.47432L12.5658 2.85787C12.9357 1.96494 12.5117 0.94124 11.6188 0.571378L10.6949 0.188694C9.80195 -0.181168 8.77825 0.242858 8.40839 1.13579L8.15316 1.75196C8.10226 1.75073 8.05122 1.75011 8.00007 1.75011C7.94864 1.75011 7.89734 1.75074 7.84616 1.75198L7.59089 1.13569C7.22102 0.242766 6.19733 -0.181263 5.3044 0.1886L4.38052 0.571284C3.4876 0.941146 3.06357 1.96484 3.43343 2.85777L3.68905 3.47488C3.61513 3.54532 3.54293 3.61755 3.47254 3.69151L2.85533 3.43585C1.9624 3.06599 0.938705 3.49002 0.568843 4.38295L0.186159 5.30683C-0.183704 6.19975 0.240324 7.22345 1.13325 7.59331L1.75185 7.84955C1.75067 7.89961 1.75007 7.9498 1.75007 8.00011C1.75007 8.05168 1.7507 8.10312 1.75194 8.15443L1.13335 8.41066C0.240417 8.78052 -0.18361 9.80422 0.186252 10.6971L0.568936 11.621C0.938798 12.514 1.96249 12.938 2.85542 12.5681L3.47512 12.3114C3.54507 12.3848 3.6168 12.4565 3.69022 12.5265L3.43351 13.1462ZM1.61161 6.43846C1.35648 6.33279 1.23533 6.0403 1.34101 5.78518L1.72369 4.8613C1.82937 4.60618 2.12185 4.48503 2.37697 4.5907L3.47809 5.0468C3.69752 5.13769 3.94855 5.05988 4.09713 4.87459C4.32641 4.58865 4.58647 4.32845 4.87227 4.099C5.05738 3.95039 5.13507 3.69948 5.04422 3.48016L4.58828 2.37941C4.4826 2.12429 4.60375 1.83181 4.85888 1.72613L5.78276 1.34345C6.03788 1.23777 6.33036 1.35893 6.43604 1.61405L6.89159 2.71385C6.98246 2.93322 7.21488 3.05571 7.45092 3.02993C7.63126 3.01022 7.81448 3.00011 8.00007 3.00011C8.18541 3.00011 8.3684 3.0102 8.54851 3.02985C8.78452 3.0556 9.01691 2.93311 9.10776 2.71377L9.56324 1.61414C9.66891 1.35902 9.9614 1.23787 10.2165 1.34354L11.1404 1.72623C11.3955 1.8319 11.5167 2.12439 11.411 2.37951L10.9553 3.47967C10.8644 3.69901 10.9422 3.94995 11.1273 4.09856C11.4132 4.32802 11.6734 4.58826 11.9027 4.87425C12.0513 5.05952 12.3023 5.13731 12.5217 5.04642L13.6221 4.59063C13.8773 4.48495 14.1697 4.6061 14.2754 4.86122L14.6581 5.7851C14.7638 6.04023 14.6426 6.33271 14.3875 6.43839L13.2866 6.89438C13.0674 6.98521 12.9449 7.21748 12.9705 7.45343C12.99 7.63298 13.0001 7.81537 13.0001 8.00011C13.0001 8.18597 12.9899 8.36945 12.9702 8.55005C12.9443 8.78611 13.0668 9.01859 13.2862 9.10947L14.3874 9.56559C14.6425 9.67126 14.7637 9.96375 14.658 10.2189L14.2753 11.1427C14.1696 11.3979 13.8772 11.519 13.622 11.4133L12.5195 10.9566C12.3002 10.8658 12.0493 10.9435 11.9007 11.1285C11.6715 11.4139 11.4117 11.6736 11.1262 11.9026C10.941 12.0511 10.8632 12.3021 10.9541 12.5215L11.4109 13.6245C11.5166 13.8796 11.3954 14.1721 11.1403 14.2778L10.2164 14.6604C9.96132 14.7661 9.66884 14.645 9.56316 14.3898L9.1062 13.2866C9.01536 13.0673 8.78307 12.9449 8.54711 12.9705C8.36745 12.9901 8.18493 13.0001 8.00007 13.0001C7.81497 13.0001 7.63221 12.9901 7.45233 12.9705C7.21634 12.9447 6.984 13.0672 6.89316 13.2865L6.43611 14.3899C6.33044 14.6451 6.03796 14.7662 5.78283 14.6605L4.85895 14.2779C4.60383 14.1722 4.48268 13.8797 4.58836 13.6246L5.04545 12.521C5.13632 12.3017 5.05857 12.0507 4.87337 11.9021C4.58799 11.6731 4.32826 11.4135 4.09918 11.1282C3.95057 10.9431 3.69967 10.8654 3.48037 10.9563L2.37707 11.4133C2.12194 11.5189 1.82946 11.3978 1.72379 11.1427L1.3411 10.2188C1.23543 9.96367 1.35658 9.67119 1.6117 9.56551L2.71385 9.10898C2.93323 9.01811 3.05572 8.78566 3.02992 8.54962C3.01019 8.36916 3.00007 8.18582 3.00007 8.00011C3.00007 7.81552 3.01007 7.63327 3.02957 7.45386C3.0552 7.21793 2.93271 6.98568 2.71345 6.89486L1.61161 6.43846ZM6.12508 8.00008C6.12508 6.96455 6.96455 6.12508 8.00008 6.12508C9.03562 6.12508 9.87508 6.96455 9.87508 8.00008C9.87508 9.03562 9.03562 9.87508 8.00008 9.87508C6.96455 9.87508 6.12508 9.03562 6.12508 8.00008ZM8.00008 4.87508C6.27419 4.87508 4.87508 6.27419 4.87508 8.00008C4.87508 9.72597 6.27419 11.1251 8.00008 11.1251C9.72597 11.1251 11.1251 9.72597 11.1251 8.00008C11.1251 6.27419 9.72597 4.87508 8.00008 4.87508Z", - "fill-opacity": "0.8" - } - )); - } - function FireIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y( - "path", - { - class: "fire-icon", - "fill-rule": "evenodd", - "clip-rule": "evenodd", - d: "M6.51018 15.53C5.52187 15.1832 4.62831 14.6102 3.90082 13.8566C3.17333 13.1031 2.63205 12.1899 2.32018 11.19C2.00674 10.2021 1.95815 9.14927 2.17926 8.1367C2.40038 7.12413 2.88345 6.18736 3.58018 5.42005C3.55105 5.89155 3.6297 6.36349 3.81018 6.80005C4.02356 7.25295 4.32236 7.6604 4.69018 8.00005C4.69018 8.00005 4.12018 6.49005 5.50018 4.00005C6.05384 3.11404 6.78312 2.35083 7.64306 1.75747C8.50299 1.16412 9.47535 0.7532 10.5002 0.550049C9.98701 1.37608 9.80819 2.36673 10.0002 3.32005C10.3002 4.32005 10.7902 4.86005 11.3402 6.32005C11.6533 7.02128 11.8102 7.78217 11.8002 8.55005C11.8926 8.00549 12.0787 7.48106 12.3502 7.00005C12.8054 6.23481 13.5124 5.65154 14.3502 5.35005C13.9624 6.24354 13.8043 7.21983 13.8902 8.19005C14.1302 9.57207 14.0026 10.9929 13.5202 12.31C13.1428 13.1433 12.5799 13.8792 11.8745 14.4616C11.1691 15.0439 10.3398 15.4573 9.45018 15.67C10.0364 15.44 10.5354 15.0313 10.8765 14.5018C11.2175 13.9723 11.3832 13.349 11.3502 12.72C11.252 11.9769 10.8985 11.2911 10.3502 10.78C10.0002 12.67 9.00018 12.89 9.00018 12.89C9.38752 12.0753 9.62788 11.1985 9.71018 10.3C9.76455 9.73167 9.71025 9.15813 9.55018 8.61005C9.35806 7.62829 8.80504 6.75416 8.00018 6.16005C8.05821 6.68407 8.0102 7.21441 7.85902 7.7195C7.70784 8.22458 7.45657 8.69408 7.12018 9.10005C6.31018 10.36 4.94018 11.29 5.00018 13.17C5.02637 13.6604 5.17925 14.1356 5.44391 14.5492C5.70856 14.9628 6.07594 15.3008 6.51018 15.53Z", - "fill-opacity": "0.84" - } - )); - } - - // v2/components/email.jsx - init_lib(); - var formatAddress = (address) => address + "@duck.com"; - var EmailContext = G({ - /** @type {EmailState} */ - state: { - state: "unknown", - alias: null - }, - /** @type {() => void} */ - copyAlias: () => { - throw new Error("todo: implement refresh"); - } - }); - function EmailProvider({ children }) { - const data = useData(); - const fetcher = useFetcher(); - const hasAlias = typeof data.emailProtectionUserData?.nextAlias === "string"; - const initialState = { - state: hasAlias ? "idle" : "unknown", - alias: hasAlias ? data.emailProtectionUserData?.nextAlias : null - }; - const [state, dispatch] = s2((state2, action) => { - switch (state2.state) { - case "added": { - switch (action.type) { - case "update": { - return { - ...state2, - alias: action.alias - }; - } - case "reset": { - return { - ...state2, - state: ( - /** @type {const} */ - "idle" - ) - }; - } - default: - return state2; - } - } - case "idle": - case "unknown": - switch (action.type) { - case "copy": { - return { - ...state2, - state: ( - /** @type {const} */ - "added" - ) - }; - } - } - break; - } - return state2; - }, initialState); - function copyAlias() { - dispatch({ type: "copy" }); - if (!state.alias) { - return console.warn("missing state.alias"); - } - navigator.clipboard?.writeText(formatAddress(state.alias)); - const msg = new RefreshEmailAliasMessage(); - fetcher(msg).then((resp) => { - console.log("--", resp); - const response = z3.object({ - privateAddress: z3.string().optional() - }); - const parsed = response.safeParse(resp); - if (!parsed.success) { - console.warn("response did not contain a valid private address", resp); - dispatch({ - type: "update", - alias: null - }); - } else { - if (!parsed.data.privateAddress) { - return console.warn("missing `privateAddress`"); - } - dispatch({ - type: "update", - alias: parsed.data.privateAddress - }); - } - }).catch((e3) => console.error("error refreshing", e3)).finally(() => { - setTimeout(() => { - dispatch({ type: "reset" }); - }, 2e3); - }); - } - if (state.state === "unknown") - return null; - return /* @__PURE__ */ y(EmailContext.Provider, { value: { state, copyAlias } }, children); - } - function EmailBar() { - const { state, copyAlias } = q2(EmailContext); - const text = state.state === "idle" ? i18n.t("site:createNewDuckAddress.title") : i18n.t("site:createNewDuckAddressCopied.title"); - const icon = state.state === "idle" ? /* @__PURE__ */ y(WandIcon, null) : /* @__PURE__ */ y(CheckMarkIcon, null); - return /* @__PURE__ */ y("div", { id: "email-alias-container" }, /* @__PURE__ */ y("div", { className: "js-email-alias email-alias token-body-em" }, /* @__PURE__ */ y( - "button", - { - className: "email-alias__button", - type: "button", - "data-state": state.state, - disabled: state.state === "added", - onClick: copyAlias - }, - icon, - /* @__PURE__ */ y("span", { className: "email-alias__text" }, text) - ))); - } - function WandIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ y("path", { d: "M10.4998 0.75C10.4998 0.335786 10.164 0 9.74976 0C9.33554 0 8.99976 0.335786 8.99976 0.75V3.25C8.99976 3.66421 9.33554 4 9.74976 4C10.164 4 10.4998 3.66421 10.4998 3.25V0.75Z" }), /* @__PURE__ */ y("path", { d: "M10.4998 9.75C10.4998 9.33579 10.164 9 9.74976 9C9.33554 9 8.99976 9.33579 8.99976 9.75V12.25C8.99976 12.6642 9.33554 13 9.74976 13C10.164 13 10.4998 12.6642 10.4998 12.25V9.75Z" }), /* @__PURE__ */ y("path", { d: "M15.9998 6.25C15.9998 6.66421 15.664 7 15.2498 7H12.7498C12.3355 7 11.9998 6.66421 11.9998 6.25C11.9998 5.83579 12.3355 5.5 12.7498 5.5H15.2498C15.664 5.5 15.9998 5.83579 15.9998 6.25Z" }), /* @__PURE__ */ y("path", { d: "M6.24976 7C6.66397 7 6.99976 6.66421 6.99976 6.25C6.99976 5.83579 6.66397 5.5 6.24976 5.5H3.74976C3.33554 5.5 2.99976 5.83579 2.99976 6.25C2.99976 6.66421 3.33554 7 3.74976 7H6.24976Z" }), /* @__PURE__ */ y("path", { d: "M14.2801 10.7803C13.9872 11.0732 13.5123 11.0732 13.2194 10.7803L11.4694 9.03033C11.1765 8.73744 11.1765 8.26256 11.4694 7.96967C11.7623 7.67678 12.2372 7.67678 12.5301 7.96967L14.2801 9.71967C14.573 10.0126 14.573 10.4874 14.2801 10.7803Z" }), /* @__PURE__ */ y("path", { d: "M6.71942 4.28033C7.01231 4.57322 7.48719 4.57322 7.78008 4.28033C8.07297 3.98744 8.07297 3.51256 7.78008 3.21967L6.03008 1.46967C5.73719 1.17678 5.26231 1.17678 4.96942 1.46967C4.67653 1.76256 4.67653 2.23744 4.96942 2.53033L6.71942 4.28033Z" }), /* @__PURE__ */ y("path", { d: "M11.4694 4.53032C11.1765 4.23743 11.1765 3.76256 11.4694 3.46966L13.2194 1.71966C13.5123 1.42677 13.9872 1.42677 14.2801 1.71966C14.573 2.01256 14.573 2.48743 14.2801 2.78032L12.5301 4.53032C12.2372 4.82322 11.7623 4.82322 11.4694 4.53032Z" }), /* @__PURE__ */ y("path", { d: "M2.28296 12.658L9.24784 5.69307C9.54074 5.40018 10.0156 5.40018 10.3085 5.69307V5.69307C10.6014 5.98597 10.6014 6.46084 10.3085 6.75373L3.34362 13.7186L2.28296 12.658Z" }), /* @__PURE__ */ y("path", { d: "M0.243221 15.7588C-0.0496725 15.466 -0.0496726 14.9911 0.243221 14.6982L1.75195 13.1895L2.81261 14.2501L1.30388 15.7588C1.01099 16.0517 0.536114 16.0517 0.243221 15.7588V15.7588Z" })); - } - function CheckMarkIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ y("path", { d: "M11.809 6.2501C12.0851 5.94141 12.0588 5.46727 11.7501 5.19108C11.4414 4.91488 10.9673 4.94122 10.6911 5.24991L7.0255 9.34675L5.33049 7.27508C5.06819 6.9545 4.59568 6.90724 4.27509 7.16954C3.95451 7.43183 3.90726 7.90435 4.16955 8.22494L6.41955 10.9749C6.55833 11.1446 6.76436 11.245 6.98346 11.2498C7.20256 11.2547 7.41282 11.1634 7.55895 11.0001L11.809 6.2501Z" }), /* @__PURE__ */ y( - "path", - { - "fill-rule": "evenodd", - "clip-rule": "evenodd", - d: "M8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0ZM1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8C14.5 11.5899 11.5899 14.5 8 14.5C4.41015 14.5 1.5 11.5899 1.5 8Z" - } - )); - } - - // shared/js/ui/templates/site.js - var import_nanohtml9 = __toESM(require_browser()); - function localizePermissions(permissions) { - if (!Array.isArray(permissions) || permissions.length === 0) { - return []; - } - const updatedPermissions = JSON.parse(JSON.stringify(permissions)); - return updatedPermissions.map((perm) => { - const permKey = `permissions:${perm.key}.title`; - if (i18n.exists(permKey)) { - perm.title = i18n.t(permKey); - } - perm.options = perm.options.map((option) => { - const optionKey = `permissions:${option.id}.title`; - if (i18n.exists(optionKey)) { - option.title = i18n.t(optionKey); - } - return option; - }); - return perm; - }); - } - - // v2/components/page-outer.jsx - function PageOuter({ children }) { - return /* @__PURE__ */ y("div", { class: "page-outer" }, children); - } - - // v2/components/permissions.jsx - function Permissions() { - const data = useData(); - if (!data.permissions || data.permissions.length === 0) { - return null; - } - const localizedPerms = localizePermissions(data.permissions); - const fetcher = useFetcher(); - function update(id, value) { - console.log(id, value); - fetcher(new UpdatePermissionMessage({ id, value })).catch((e3) => console.error(e3)); - } - return /* @__PURE__ */ y(PageOuter, null, /* @__PURE__ */ y("div", { className: "site-info__li--manage-permissions" }, localizedPerms.map(({ key: permissionId, title, permission, options }) => { - return /* @__PURE__ */ y("div", { className: "site-info__page-permission" }, /* @__PURE__ */ y("label", null, /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("div", { className: "site-info__page-permission__icon", "data-icon": permissionId }), title), /* @__PURE__ */ y("select", { name: permissionId, onChange: (e3) => update( - permissionId, - /** @type {any} */ - e3.target.value - ) }, options.map(({ id, title: title2 }) => /* @__PURE__ */ y("option", { value: id, selected: permission === id }, title2))))); - }))); - } - - // v2/screens/cta-screen.jsx - function CtaScreen() { - const data = useData(); - const ctas = { - spread: { - title: i18n.t("ctascreens:spreadTitle.title"), - text: i18n.t("ctascreens:spreadText.title"), - icon: heartArrowSvg, - action: /* @__PURE__ */ y("a", { href: "https://duckduckgo.com/spread", target: "_blank", class: "cta__button" }, i18n.t("ctascreens:spreadButton.title")) - }, - email: { - title: i18n.t("ctascreens:emailTitle.title"), - text: i18n.t("ctascreens:emailText.title"), - icon: emailSvg, - action: /* @__PURE__ */ y("a", { href: "https://duckduckgo.com/email", target: "_blank", class: "cta__button" }, i18n.t("ctascreens:spreadButton.title")) - } - }; - const keys = Object.keys(ctas); - const ctaKey = data.emailProtectionUserData?.nextAlias ? "spread" : keys[Math.floor(Math.random() * keys.length)]; - const cta = ctas[ctaKey]; - return /* @__PURE__ */ y("div", { className: "cta-screen page-inner" }, /* @__PURE__ */ y("p", { className: "note token-title-3 text--center" }, i18n.t("ctascreens:protectionsUnavailableNote.title")), /* @__PURE__ */ y("div", { className: "cta text--center" }, /* @__PURE__ */ y("div", { className: "cta__icon", dangerouslySetInnerHTML: { __html: cta.icon() } }), /* @__PURE__ */ y("h1", { className: "cta__title" }, cta.title), /* @__PURE__ */ y("h2", { className: "cta__text" }, cta.text), /* @__PURE__ */ y("div", { className: "cta__action" }, cta.action))); - } - function heartArrowSvg() { - return ` - - - - - - - - - - - - - - - - -`; - } - function emailSvg() { - return ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`; - } - - // v2/screens/primary-screen.jsx - function PrimaryScreen() { - const status = usePrimaryStatus(); - return /* @__PURE__ */ y("div", { class: "site-info page" }, /* @__PURE__ */ y("div", { className: "page-inner" }, /* @__PURE__ */ y(SearchBar, null), /* @__PURE__ */ y(PrimaryScreenTopNav, null), status === "error" && /* @__PURE__ */ y(ErrorInner, null), status === "cta" && /* @__PURE__ */ y(CtaScreenInner, null), status === "ready" && /* @__PURE__ */ y(PrimaryScreenInner, null), /* @__PURE__ */ y(Footer, null), /* @__PURE__ */ y(Permissions, null))); - } - function Footer() { - return /* @__PURE__ */ y("footer", { className: "footer" }, /* @__PURE__ */ y("div", { className: "padding-x" }, isBrowser() && /* @__PURE__ */ y(EmailProvider, null, /* @__PURE__ */ y(EmailBar, null)))); - } - function PrimaryScreenInner() { - return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y("header", { class: "header" }, /* @__PURE__ */ y(ProtectionHeader2, null)), /* @__PURE__ */ y("div", { class: "header-spacer" }), /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(KeyInsights, null)), /* @__PURE__ */ y("div", { class: "padding-x" }, /* @__PURE__ */ y(MainNav, null))); - } - function PrimaryScreenTopNav() { - const onClose = useClose(); - if (isAndroid()) - return /* @__PURE__ */ y(TopNav, { back: /* @__PURE__ */ y(Back, { onClick: onClose }) }); - if (isIOS()) - return /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Done, { onClick: onClose }) }); - return null; - } - function CtaScreenInner() { - return /* @__PURE__ */ y("div", { class: "padding-x" }, /* @__PURE__ */ y(CtaScreen, null)); - } - function ErrorInner() { - const errorText = i18n.t("site:errorMessage.title"); - return /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y("div", { className: "cta-screen" }, /* @__PURE__ */ y("p", { className: "note token-title-3 text--center" }, errorText))); - } - - // v2/breakage-categories.js - var defaultCategories = () => { - return { - blocked: ns.report("blocked.title"), - layout: ns.report("layout.title"), - "empty-spaces": ns.report("emptySpaces.title"), - paywall: ns.report("paywall.title"), - videos: ns.report("videos.title"), - comments: ns.report("comments.title"), - login: ns.report("login.title"), - shopping: ns.report("shopping.title"), - other: ns.report("other.title") - }; - }; - function createBreakageFeaturesFrom(platformFeatures) { - return { - /** - * @param {Record} [additional] - * @return {[key: string, description: string][]} - */ - categoryList(additional = {}) { - const items = { - ...defaultCategories(), - ...additional - }; - const list = Object.entries(items); - if (platformFeatures.randomisedCategories) { - return shuffle(list); - } - return list; - } - }; - } - function shuffle(arr2) { - let len = arr2.length; - let temp; - let index; - while (len > 0) { - index = Math.floor(Math.random() * len); - len--; - temp = arr2[len]; - arr2[len] = arr2[index]; - arr2[index] = temp; - } - return arr2; - } - - // v2/components/custom-element-loader.jsx - function CustomElementLoader(props) { - const [state, dispatch] = s2(reducer, { status: "idle" }); - p2(() => { - if (state.status === "idle") { - if (window.__ddg_did_load && window.__ddg_did_load.includes(props.element)) { - dispatch({ kind: "skip-loading" }); - } else { - dispatch({ kind: "load-script", element: props.element }); - } - return; - } - if (state.status === "script-ready") { - dispatch({ kind: "load-element" }); - customElements.whenDefined(props.element).then(() => { - if (!window.__ddg_did_load) - window.__ddg_did_load = []; - window.__ddg_did_load.push(props.element); - dispatch({ kind: "element-loaded" }); - }); - } - }, [state.status, props.src, props.element]); - if (state.status === "element-ready") { - return props.children; - } - if (state.status === "script-pending") { - return /* @__PURE__ */ y("script", { src: props.src, onLoad: () => dispatch({ kind: "script-loaded" }) }); - } - return ( - /** @type {any} */ - null - ); - } - function reducer(state, event) { - console.log("incoming", event, "current", state); - switch (state.status) { - case "idle": { - switch (event.kind) { - case "load-script": { - return { ...state, status: ( - /** @type {const} */ - "script-pending" - ) }; - } - case "skip-loading": { - return { ...state, status: ( - /** @type {const} */ - "element-ready" - ) }; - } - } - break; - } - case "script-pending": { - switch (event.kind) { - case "script-loaded": { - return { ...state, status: ( - /** @type {const} */ - "script-ready" - ) }; - } - } - break; - } - case "script-ready": { - switch (event.kind) { - case "load-element": { - return { ...state, status: ( - /** @type {const} */ - "element-pending" - ) }; - } - } - break; - } - case "element-pending": { - switch (event.kind) { - case "element-loaded": { - return { ...state, status: ( - /** @type {const} */ - "element-ready" - ) }; - } - } - } - } - return state; - } - - // v2/components/android-breakage-modal-wrapper.jsx - var DDG_DIALOG_NAME = "ddg-android-breakage-dialog"; - var DDG_DIALOG_PATH = "../public/js/android-breakage-dialog.js"; - function FormSelectElementWithDialog() { - const platformFeatures = useFeatures(); - const randomised = F(() => { - const f3 = createBreakageFeaturesFrom(platformFeatures); - return f3.categoryList(); - }, [platformFeatures]); - const selectRef = _(null); - function onClick(e3) { - e3.preventDefault(); - e3.stopImmediatePropagation(); - const elem = document.querySelector(DDG_DIALOG_NAME); - if (!elem) - return console.warn("could not find custom element", "ddg-android-breakage-dialog"); - if (!selectRef.current) - return console.warn("could not find select ref"); - elem.show(selectRef.current.value); - } - return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y(CustomElementLoader, { src: DDG_DIALOG_PATH, element: DDG_DIALOG_NAME }, /* @__PURE__ */ y( - AndroidBreakageDialogWrapper, - { - items: randomised, - onSelect: (value) => { - if (!selectRef.current) - return; - selectRef.current.value = value; - } - } - )), /* @__PURE__ */ y("div", { className: "form__select breakage-form__input--dropdown", onClick, "data-testid": "select-click-capture" }, /* @__PURE__ */ y("select", { name: "category", ref: selectRef }, /* @__PURE__ */ y("option", { value: "", selected: true, disabled: true }, ns.report("pickYourIssueFromTheList.title")), randomised.map(([key, value]) => { - return /* @__PURE__ */ y("option", { value: key }, value); - })))); - } - function AndroidBreakageDialogWrapper({ items, onSelect }) { - const ref = _(null); - p2(() => { - const controller = new AbortController(); - ref.current?.addEventListener( - "did-select", - (e3) => { - const selection = ( - /** @type {{value: string}} */ - e3.detail - ); - const matched = items.find(([name]) => name === selection.value); - if (!matched) - throw new Error("value did not match a variant"); - const [value] = matched; - onSelect(value); - }, - { signal: controller.signal } - ); - return () => { - return controller.abort(); - }; - }, []); - return /* @__PURE__ */ y( - "ddg-android-breakage-dialog", - { - items, - ref, - title: ns.report("pickYourIssueFromTheList.title"), - cancelText: ns.site("navigationCancel.title"), - okText: ns.site("okDialogAction.title") - } - ); - } - - // v2/screens/breakage-form-screen.jsx - function BreakageFormScreen({ includeToggle }) { - const data = useData(); - const onToggle = useToggle(); - const onClose = useClose(); - const nav = useNav(); - const canPop = nav.canPop(); - const sendReport = useSendReport(); - const platformFeatures = useFeatures(); - const [state, setState] = h2( - /** @type {"idle" | "sent"} */ - "idle" - ); - const icon = largeHeroIcon({ - status: "breakage-form" - }); - let headerText = includeToggle ? ns.report("selectTheOptionDesc.title") : ns.report("selectTheOptionDescV2.title"); - function submit(e3) { - e3.preventDefault(); - const values = Object.fromEntries(new FormData(e3.target)); - sendReport({ - category: String(values.category || ""), - description: String(values.description || "") - }); - setState("sent"); - } - let topNav2 = platformSwitch({ - android: () => /* @__PURE__ */ y(SecondaryTopNav, null, /* @__PURE__ */ y(Title, null, ns.site("websiteNotWorkingCta.title"))), - default: () => /* @__PURE__ */ y(SecondaryTopNav, null) - }); - if (!canPop) { - topNav2 = platformSwitch({ - ios: () => /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Done, { onClick: onClose }) }), - android: () => /* @__PURE__ */ y(TopNav, { back: /* @__PURE__ */ y(Back, { onClick: onClose }) }, /* @__PURE__ */ y(Title, null, ns.site("websiteNotWorkingCta.title"))), - default: () => /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Close, { onClick: onClose }) }) - }); - } - return /* @__PURE__ */ y("div", { className: "breakage-form page-inner" }, topNav2, /* @__PURE__ */ y("div", { className: "breakage-form__inner", "data-state": state }, includeToggle && /* @__PURE__ */ y("div", { class: "header header--breakage" }, /* @__PURE__ */ y( - ProtectionHeader, - { - model: data, - initialState: "site-not-working", - toggle: onToggle, - "data-testid": "breakage-form-protection-header" - } - )), /* @__PURE__ */ y("div", { className: "key-insight key-insight--breakage padding-x-double" }, /* @__PURE__ */ y(DomNode, null, icon), /* @__PURE__ */ y("div", { className: "breakage-form__advise" }, /* @__PURE__ */ y("p", { className: "token-title-3" }, headerText)), /* @__PURE__ */ y("div", { className: "thanks" }, /* @__PURE__ */ y("p", { className: "thanks__primary" }, ns.report("thankYou.title")), /* @__PURE__ */ y("p", { className: "thanks__secondary" }, ns.report("yourReportWillHelpDesc.title")))), /* @__PURE__ */ y("div", { className: "breakage-form__content padding-x-double" }, /* @__PURE__ */ y( - FormElement, - { - onSubmit: submit, - before: platformFeatures.breakageFormCategorySelect === "material-web-dialog" ? /* @__PURE__ */ y(FormSelectElementWithDialog, null) : /* @__PURE__ */ y(DefaultSelectElement, null) - } - )), /* @__PURE__ */ y("div", { className: "breakage-form__footer padding-x-double token-breakage-form-body" }, ns.report("reportsAreAnonymousDesc.title")))); - } - function DefaultSelectElement() { - const platformFeatures = useFeatures(); - const randomised = F(() => { - const f3 = createBreakageFeaturesFrom(platformFeatures); - return f3.categoryList(); - }, [platformFeatures]); - return /* @__PURE__ */ y("div", { className: "form__select breakage-form__input--dropdown" }, /* @__PURE__ */ y("select", { name: "category" }, /* @__PURE__ */ y("option", { value: "", selected: true, disabled: true }, ns.report("pickYourIssueFromTheList.title")), randomised.map(([key, value]) => { - return /* @__PURE__ */ y("option", { value: key }, value); - }))); - } - function FormElement({ onSubmit, before, after, placeholder }) { - let bullet = "\n \u2022 "; - placeholder = placeholder || ns.report("tellUsMoreDesc.title", { bullet }); - return /* @__PURE__ */ y("form", { className: "breakage-form__element", onSubmit }, /* @__PURE__ */ y("div", { className: "form__group" }, before, /* @__PURE__ */ y("textarea", { className: "form__textarea", placeholder, maxLength: 2500, name: "description" }), after), /* @__PURE__ */ y("button", { className: "form__submit token-label-em", type: "submit" }, ns.report("sendReport.title"))); - } - - // shared/js/ui/templates/page-trackers.js - var import_nanohtml11 = __toESM(require_browser()); - - // shared/js/ui/templates/shared/platform-limitations.js - var import_nanohtml10 = __toESM(require_browser()); - function platformLimitations() { - return import_nanohtml10.default`

${ns.site("trackerLimitationsNote.title")}

`; - } - - // shared/js/ui/templates/page-trackers.js - function trackerListWrapper(name, heading, companiesList, bordered) { - return import_nanohtml11.default` -
    - ${heading ? import_nanohtml11.default`
  1. ${heading}
  2. ` : import_nanohtml11.default``} ${companiesList} -
- `; - } - function renderCompany(company) { - if (company.displayName && company.displayName === "unknown") { - company.displayName = `(${i18n.t("site:trackerNetworkUnknown.title")})`; - } - const slug = company.normalizedName; - const title = company.name || company.displayName; - const titleClasses = [ - "site-info__tracker__icon", - "site-info__tracker__icon--company", - slug[0].toUpperCase(), - "color-" + getColorId(slug), - slug - ]; - const listLabel = i18n.t("site:trackerDomainsForCompany.title", { - companyName: company.displayName - }); - return import_nanohtml11.default`
  • -

    - - ${company.displayName} -

    -
      - ${Object.keys(company.urls).map((urlHostname) => { - const url = company.urls[urlHostname]; - const matched = displayCategories[url.category]; - return import_nanohtml11.default`
    1. -

      ${urlHostname}

      - ${matched ? import_nanohtml11.default`
      ${i18n.t(matched)}
      ` : ""} -
    2. `; - })} -
    -
  • `; - } - function renderSections(sections) { - const output2 = sections.filter((section) => section.companies.length > 0).map((section) => { - const companiesList = section.companies.map((company) => renderCompany(company)); - const sectionHeading = section.heading(); - return trackerListWrapper(section.name, sectionHeading, companiesList, section.bordered); - }); - return output2; - } - function sectionsFromSiteTrackers(site2) { - const { blocked } = site2.tab.requestDetails; - const sections = renderSections([ - { - name: "blocked", - heading: () => null, - companies: blocked.sortedByPrevalence(), - bordered: true - } - ]); - return sections; - } - - // v2/screens/trackers-screen.jsx - function TrackersScreen() { - const data = useData(); - const ref = useRippleChildren(data.count); - return /* @__PURE__ */ y("div", { className: "site-info card page-inner", "data-page": "trackers" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double", ref }, /* @__PURE__ */ y(DomNode, { key: data.count }, heroFromTabTrackers(data.tab.requestDetails, data.protectionsEnabled))), /* @__PURE__ */ y("div", { className: "padding-x-double", "aria-label": "List of Tracker Companies" }, sectionsFromSiteTrackers(data).map((el, index) => { - return /* @__PURE__ */ y(DomNode, { key: String(data.count) + String(index) }, el); - })), data.tab.platformLimitations ? /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, platformLimitations())) : /* @__PURE__ */ y("div", null)); - } - - // shared/js/ui/templates/page-non-trackers.js - var import_nanohtml12 = __toESM(require_browser()); - function sectionsFromSiteNonTracker(site2) { - const requestDetails = site2.tab.requestDetails; - const onlyAllowedNonTrackers = requestDetails.matches(site2.protectionsEnabled, [ - states.protectionsOn_allowedNonTrackers, - states.protectionsOff_allowedNonTrackers, - states.protectionsOn_blocked_allowedNonTrackers - ]); - if (!site2.protectionsEnabled) { - return renderSections([ - { - name: "protectionsDisabled", - heading: () => ns.site("sectionHeadingProtectionsDisabled.title"), - companies: requestDetails.all.sortedByPrevalence(), - bordered: false - } - ]); - } - return renderSections([ - { - name: "adAttribution", - heading: () => import_nanohtml12.default` -
    -

    ${ns.site("sectionHeadingAdAttribution.title", { domain: site2.tab.domain })}

    - ${adAttributionLink()} -
    - `, - companies: requestDetails.allowed.adClickAttribution.sortedByPrevalence() - }, - { - name: "ignored (rule exceptions)", - heading: () => ns.site("sectionHeadingIgnore.title"), - companies: requestDetails.allowed.ruleException.sortedByPrevalence() - }, - { - name: "firstParty", - heading: () => ns.site("sectionHeadingFirstParty.title", { domain: site2.tab.domain }), - companies: requestDetails.allowed.ownedByFirstParty.sortedByPrevalence() - }, - { - name: "thirdParty", - heading: () => { - if (onlyAllowedNonTrackers) { - return null; - } - return ns.site("sectionHeadingThirdParty.title"); - }, - companies: requestDetails.allowed.otherThirdPartyRequest.sortedByPrevalence(), - bordered: onlyAllowedNonTrackers - } - ]); - } - - // v2/screens/non-trackers-screen.jsx - function NonTrackersScreen() { - const data = useData(); - const ref = useRippleChildren(data.count); - return /* @__PURE__ */ y("div", { className: "site-info card page-inner", "data-page": "non-trackers" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double", ref }, /* @__PURE__ */ y(DomNode, { key: data.count }, heroFromTabNonTrackers(data.tab.requestDetails, data.protectionsEnabled))), /* @__PURE__ */ y("div", { className: "padding-x-double", "aria-label": "List of Tracker Companies" }, sectionsFromSiteNonTracker(data).map((el, index) => { - return /* @__PURE__ */ y(DomNode, { key: String(data.count) + String(index) }, el); - })), data.tab.platformLimitations && /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, platformLimitations()))); - } - - // v2/screens/consent-managed-screen.jsx - function ConsentManagedScreen({ cosmetic }) { - const data = useData(); - const fetcher = useFetcher(); - const summary = cosmetic ? ns.site("cookiesHiddenSummary.title") : ns.site("cookiesMinimizedSummary.title"); - const icon = largeHeroIcon({ - status: cosmetic ? "cookies-hidden" : "cookies-managed" - }); - const hero = heroTemplate({ - icon, - summary, - suffix: "none" - }); - function disable() { - const msg = new OpenSettingsMessages({ - target: "cpm" - }); - fetcher(msg).catch(console.error); - } - return /* @__PURE__ */ y("div", { className: "card page-inner", "data-page": "cookie-prompt" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, hero)), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y("div", { className: "padding-y border--top--inner text--center" }, /* @__PURE__ */ y(DomNode, { key: data.count }, disableInSettingsLink(disable))))); - } - - // shared/js/ui/components/toggle-report/toggle-report-provider.jsx - init_schema_parsers(); - var ToggleReportContext = G({ - value: ( - /** @type {import('../../../../../schema/__generated__/schema.types').ToggleReportScreen} */ - {} - ), - /** @type {() => void} */ - send: () => { - throw new Error("todo implement send"); - }, - /** @type {() => void} */ - reject: () => { - throw new Error("todo implement reject"); - }, - /** @type {() => void} */ - didShowWhatIsSent: () => { - throw new Error("todo implement didShowWhatIsSent"); - }, - /** @type {() => void} */ - didClickSuccessScreen: () => { - throw new Error("todo implement didClickSuccessScreen"); - } - }); - function ToggleReportProvider({ children, model, screen }) { - const initial = { status: "pending" }; - const [state, dispatch] = s2((state2, action) => action, initial); - p2(() => { - const msg = new FetchToggleReportOptions(); - model.fetch(msg)?.then((data) => { - const parsed = toggleReportScreenSchema.safeParse(data); - if (parsed.success) { - dispatch({ status: "ready", value: data }); - } else { - console.group("ToggleReportProvider"); - console.error("the response for FetchToggleReportOptions did not match the schema"); - console.error("response:", data); - console.error("error:", parsed.error.toString()); - console.groupEnd(); - dispatch({ status: "error", error: parsed.error.toString() }); - } - }).catch((e3) => { - dispatch({ status: "error", error: e3.toString() }); - }); - }, [model]); - function send() { - useConnectionCount.pause(); - model.fetch(new SendToggleBreakageReport()); - } - function reject() { - model.fetch(new RejectToggleBreakageReport()); - } - function didShowWhatIsSent() { - model.fetch(new SeeWhatIsSent()); - } - function didClickSuccessScreen() { - model.fetch(new CloseMessage({ eventOrigin: { screen } })); - } - if (state.status === "ready") { - return /* @__PURE__ */ y( - ToggleReportContext.Provider, - { - value: { - value: state.value, - send, - reject, - didShowWhatIsSent, - didClickSuccessScreen - } - }, - children - ); - } - if (state.status === "error") - return /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("p", null, "Something went wrong"), /* @__PURE__ */ y("pre", null, /* @__PURE__ */ y("code", null, state.error))); - return null; - } - - // shared/js/ui/components/toggle-report/use-toggle-report-state.js - function useToggleReportState() { - const { send, reject, didShowWhatIsSent } = q2(ToggleReportContext); - return s2( - (state, action) => { - switch (action) { - case "toggle-ios": { - didShowWhatIsSent(); - return { - ...state, - value: ( - /** @type {const} */ - "animating" - ) - }; - } - case "animation-complete": { - return { - ...state, - value: ( - /** @type {const} */ - "showing" - ) - }; - } - case "toggle": { - const next = state.value === "hiding" ? ( - /** @type {const} */ - "showing" - ) : ( - /** @type {const} */ - "hiding" - ); - if (next === "showing") { - didShowWhatIsSent(); - } - return { - ...state, - value: next - }; - } - case "send": { - send(); - return { - ...state, - value: ( - /** @type {const} */ - "sent" - ) - }; - } - case "reject": { - reject(); - return state; - } - } - return state; - }, - { value: ( - /** @type {'hiding' | 'showing' | 'sent' | 'rejected' | 'animating'} */ - "hiding" - ) } - ); - } - - // shared/js/ui/components/toggle-report.jsx - var import_classnames2 = __toESM(require_classnames()); - - // shared/js/ui/components/button.jsx - function Button({ children, btnSize, variant = "desktop-vibrancy", ...rest }) { - return /* @__PURE__ */ y("button", { type: "button", className: "button token-body", ...rest, "data-variant": variant, "data-size": btnSize }, children); - } - function ButtonBar({ children, layout = "horizontal", ...rest }) { - return /* @__PURE__ */ y("div", { className: "button-bar", "data-layout": layout, ...rest }, children); - } - - // shared/js/ui/components/stack.jsx - var import_classnames = __toESM(require_classnames()); - function Stack({ children, gap, className, ...rest }) { - return /* @__PURE__ */ y("div", { ...rest, className: (0, import_classnames.default)(["stack", className]), style: { gap } }, children); - } - function Scrollable({ children, ...rest }) { - return /* @__PURE__ */ y("div", { className: "scrollable fade-in", ...rest }, children); - } - - // shared/js/ui/components/toggle-report/use-ios-animation.js - function useIosAnimation(state, dispatch) { - p2(() => { - if (platform.name !== "ios" && platform.name !== "android") - return; - if (state.value === "animating") { - const child = ( - /** @type {HTMLDivElement | null} */ - document.querySelector('[data-toggle-report="child"]') - ); - if (!child) - return; - child.addEventListener("transitionend", () => { - dispatch("animation-complete"); - }); - child.style.transform = "translateY(0)"; - } - }, [state.value]); - p2(() => { - if (platform.name !== "ios" && platform.name !== "android") - return; - const child = ( - /** @type {HTMLDivElement | null} */ - document.querySelector('[data-toggle-report="child"]') - ); - const parent = ( - /** @type {HTMLDivElement | null} */ - document.querySelector('[data-toggle-report="parent"]') - ); - if (!child || !parent) - return; - const rs = new ResizeObserver((r3) => { - for (const resizeObserverEntry of r3) { - if (resizeObserverEntry.contentRect.height === 0) - continue; - const childSize = child.clientHeight; - const parentHeight = resizeObserverEntry.contentRect.height - 56; - const offset2 = (parentHeight - childSize) / 2; - child.style.transform = "translateY(" + offset2 + "px)"; - child.dataset.ready = "true"; - setTimeout(() => { - child.style.transition = "all .3s"; - }, 0); - } - }); - rs.observe(parent); - return () => { - rs.disconnect(); - }; - }, []); - } - - // shared/data/text.js - function namedString(item) { - switch (item.id) { - case "openerContext": - return ns.toggleReport("dynamic_openerContext.title"); - case "userRefreshCount": - return ns.toggleReport("dynamic_userRefreshCount.title"); - case "jsPerformance": - return ns.toggleReport("dynamic_jsPerformance.title"); - case "wvVersion": - return ns.toggleReport("dynamic_wvVersion.title"); - case "requests": - return ns.toggleReport("dynamic_requests.title"); - case "features": - return ns.toggleReport("dynamic_features.title"); - case "appVersion": - return ns.toggleReport("dynamic_appVersion.title"); - case "atb": - return ns.toggleReport("dynamic_atb.title"); - case "errorDescriptions": - return ns.toggleReport("dynamic_errorDescriptions.title"); - case "extensionVersion": - return ns.toggleReport("dynamic_extensionVersion.title"); - case "httpErrorCodes": - return ns.toggleReport("dynamic_httpErrorCodes.title"); - case "lastSentDay": - return ns.toggleReport("dynamic_lastSentDay.title"); - case "device": - return ns.toggleReport("dynamic_device.title"); - case "os": - return ns.toggleReport("dynamic_os.title"); - case "reportFlow": - return ns.toggleReport("dynamic_reportFlow.title"); - case "siteUrl": - return ns.toggleReport("dynamic_siteUrl.title"); - case "listVersions": - return ns.toggleReport("dynamic_listVersions.title"); - case "didOpenReportInfo": - return ns.toggleReport("dynamic_didOpenReportInfo.title"); - case "toggleReportCounter": - return ns.toggleReport("dynamic_toggleReportCounter.title"); - case "locale": - return ns.toggleReport("dynamic_locale.title"); - case "description": - return ns.toggleReport("dynamic_description.title"); - } - } - - // shared/js/ui/components/toggle-report/toggle-report-data-list.jsx - function ToggleReportDataList({ rows }) { - return /* @__PURE__ */ y(Stack, { gap: "4px", className: "data-list__content" }, /* @__PURE__ */ y("p", { className: "data-list__heading" }, ns.toggleReport("reportsNoInfoSent.title")), /* @__PURE__ */ y("ul", { className: "data-list" }, rows.map((item) => { - const string = namedString(item); - const additional = item.id === "siteUrl" ? "[" + item.additional?.url + "]" : null; - return /* @__PURE__ */ y("li", { className: "data-list__item" }, /* @__PURE__ */ y("span", { dangerouslySetInnerHTML: { __html: `` } }), string, additional && /* @__PURE__ */ y("strong", { className: "block" }, additional)); - }))); - } - - // shared/js/ui/components/toggle-report/toggle-report-sent.jsx - function ToggleReportSent({ onClick }) { - return /* @__PURE__ */ y("div", { onClick }, /* @__PURE__ */ y(ToggleReportIcon, { variant: "sent" }), /* @__PURE__ */ y(Stack, { gap: "8px" }, /* @__PURE__ */ y("h1", { className: "token-title-2-em text--center" }, ns.report("thankYou.title")), /* @__PURE__ */ y("h2", { className: "token-title-3 text--center text--balance" }, ns.toggleReport("yourReportWillHelpToggleReport.title")))); - } - - // shared/js/ui/components/toggle-report/toggle-report-wrapper.jsx - function ToggleReportWrapper({ children, state }) { - switch (platform.name) { - case "android": - return /* @__PURE__ */ y("div", { className: "padding-x-xl padding-y-third" }, children); - case "ios": - return /* @__PURE__ */ y("div", { className: "padding-x-xl vertically-centered", "data-state": state, "data-toggle-report": "child" }, children); - case "windows": - case "browser": - case "macos": - return /* @__PURE__ */ y("div", { className: "padding-x-double" }, children, state === "sent" ? /* @__PURE__ */ y("div", { style: "height: 40px" }) : /* @__PURE__ */ y("div", { style: "height: 32px" })); - default: - return null; - } - } - - // shared/js/ui/components/toggle-report/toggle-report-title.jsx - function ToggleReportTitle({ children }) { - switch (platform.name) { - case "android": - return /* @__PURE__ */ y("h1", { className: "token-headline-2 text--center" }, children); - case "ios": - return /* @__PURE__ */ y("h1", { className: "token-ios-title-3 text--center" }, children); - case "windows": - return /* @__PURE__ */ y("h1", { className: "token-title-3-em text--center" }, children); - case "browser": - case "macos": - return /* @__PURE__ */ y("h1", { className: "token-title-2-em text--center" }, children); - default: - return null; - } - } - - // shared/js/ui/components/toggle-report.jsx - function ToggleReportIcon({ variant = "standard" }) { - const classes = (0, import_classnames2.default)({ - "hero-icon--toggle-report": variant === "standard", - "hero-icon--toggle-report-sent": variant === "sent", - "large-icon-container": platform.name === "browser" || platform.name === "windows", - "medium-icon-container": platform.name === "macos" || platform.name === "ios" || platform.name === "android" - }); - return /* @__PURE__ */ y("div", { className: classes }); - } - function ToggleReport() { - const mobile = platform.name === "android" || platform.name === "ios"; - const innerGap = mobile ? "24px" : "16px"; - const desktop = platform.name === "macos" || platform.name === "windows"; - const extension = platform.name === "browser"; - const { value, didClickSuccessScreen } = q2(ToggleReportContext); - const [state, dispatch] = useToggleReportState(); - useIosAnimation(state, dispatch); - if (state.value === "sent" && (desktop || extension)) { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(ToggleReportSent, { onClick: didClickSuccessScreen })); - } - if (desktop || extension) { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y(ToggleReportIcon, null), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")), /* @__PURE__ */ y(DesktopRevealText, { state, toggle: () => dispatch("toggle") }))), state.value === "showing" && /* @__PURE__ */ y(Scrollable, null, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") })))); - } - if (mobile) { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y(ToggleReportIcon, null), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")))), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") }), state.value !== "showing" && /* @__PURE__ */ y(RevealText, { toggle: () => dispatch(platform.name === "ios" ? "toggle-ios" : "toggle") })), state.value === "showing" && /* @__PURE__ */ y("div", { className: "ios-separator" }, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })))); - } - return /* @__PURE__ */ y("p", null, "unsupported platform: ", platform.name); - } - function SetAutoHeight() { - p2(() => { - const inner = ( - /** @type {HTMLElement} */ - document.querySelector('[data-screen="toggleReport"] .page-inner') - ); - if (inner) { - inner.style.height = "auto"; - const height = getContentHeight(); - document.body.style.setProperty("--height", `${height}px`); - const unsub = setupMutationObserverForExtensions((height2) => { - document.body.style.setProperty("--height", `${height2}px`); - }); - return () => { - unsub(); - }; - } else { - console.warn("Could not select the required element"); - } - }, []); - return null; - } - function getButtonStyles() { - switch (platform.name) { - case "ios": - case "android": - return { variant: "ios-secondary", size: "big", layout: "vertical" }; - case "windows": - return { variant: "desktop-standard", size: "desktop-large", layout: "horizontal" }; - default: - return { variant: "desktop-vibrancy", size: "desktop-large", layout: "horizontal" }; - } - } - function ToggleReportButtons({ send, reject }) { - const { variant, size, layout } = getButtonStyles(); - return /* @__PURE__ */ y(ButtonBar, { layout }, /* @__PURE__ */ y(Button, { variant, btnSize: size, onClick: reject }, ns.toggleReport("dontSendReport.title")), /* @__PURE__ */ y(Button, { variant, btnSize: size, onClick: send }, ns.report("sendReport.title"))); - } - function RevealText({ toggle }) { - return /* @__PURE__ */ y("p", { className: "text--center token-title-3" }, /* @__PURE__ */ y(PlainTextLink, { onClick: toggle, className: "token-bold" }, ns.toggleReport("siteNotWorkingInfoReveal.title"))); - } - function DesktopRevealText({ state, toggle }) { - if (state.value === "showing") - return null; - return /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("p", { className: "text--center token-title-3" }, /* @__PURE__ */ y(PlainTextLink, { onClick: toggle }, ns.toggleReport("siteNotWorkingInfoReveal.title")))); - } - - // v2/screens/toggle-report-screen.jsx - function ToggleReportScreen() { - const fetcher = useFetcher(); - const features = useFeatures(); - const { count } = useConnectionCount(); - const connectionId = `connection-${count}`; - p2(() => { - document.body.dataset.screen = "toggleReport"; - return () => { - document.body.dataset.screen = ""; - }; - }, []); - return /* @__PURE__ */ y(ToggleReportProvider, { key: connectionId, model: { fetch: fetcher }, screen: features.initialScreen }, /* @__PURE__ */ y(ToggleReportWrapper2, null, /* @__PURE__ */ y(ToggleReport, null))); - } - function ToggleReportWrapper2({ children }) { - const features = useFeatures(); - const onClose = useClose(); - const [_24, dispatch] = useToggleReportState(); - p2(() => { - document.body.dataset.screen = "toggleReport"; - return () => { - document.body.dataset.screen = ""; - }; - }, []); - const done = platformSwitch({ - ios: () => /* @__PURE__ */ y(Done, { onClick: onClose }), - macos: () => /* @__PURE__ */ y(Close, { onClick: onClose }), - default: () => null - }); - const back = platformSwitch({ - android: () => /* @__PURE__ */ y(Back, { onClick: () => dispatch("reject") }), - default: () => null - }); - return /* @__PURE__ */ y("div", { "data-toggle-report": "parent", class: "toggle-report page-inner", "data-opener": features.opener }, features.opener === "menu" ? /* @__PURE__ */ y(TopNav, { back, done }) : /* @__PURE__ */ y(TopNav, { back }), /* @__PURE__ */ y("div", { "data-testid": "toggle-report" }, children)); - } - - // v2/components/nav.jsx - function Nav({ children }) { - return /* @__PURE__ */ y("ul", { className: "default-list main-nav token-body-em" }, children); - } - function NavItem({ children, label, onClick }) { - return /* @__PURE__ */ y("li", { className: "main-nav__row" }, /* @__PURE__ */ y( - "a", - { - href: "javascript:void(0)", - role: "button", - draggable: false, - "aria-label": typeof children === "string" ? children : label, - className: "main-nav__item main-nav__item--link link-action link-action--dark", - onClick - }, - /* @__PURE__ */ y("span", { className: "main-nav__text" }, children), - /* @__PURE__ */ y("span", { className: "main-nav__chev" }) - )); - } - - // v2/screens/choice-problem.jsx - function CategoryTypeSelection() { - const description = ns.report("selectTheCategoryType.title"); - const { push } = useNav(); - const send = useTelemetry(); - const { tab } = useData(); - const showNativeFeedback2 = useShowNativeFeedback(); - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-problem" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: tab.domain }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y(Nav, null, /* @__PURE__ */ y( - NavItem, - { - onClick: () => { - send({ name: "categoryTypeSelected", value: "notWorking" }); - push("categorySelection"); - } - }, - ns.report("categoryType1.title") - ), /* @__PURE__ */ y( - NavItem, - { - onClick: () => { - send({ name: "categoryTypeSelected", value: "dislike" }); - push("choiceBreakageForm", { category: "dislike" }); - } - }, - ns.report("categoryType2.title") - ), /* @__PURE__ */ y( - NavItem, - { - onClick: () => { - send({ name: "categoryTypeSelected", value: "general" }); - showNativeFeedback2(); - } - }, - ns.report("categoryType3.title") - )))); - } - function CategorySelection() { - const description = ns.report("selectTheCategory.title"); - const { push } = useNav(); - const send = useTelemetry(); - const { protectionsEnabled, tab } = useData(); - const text = tab.domain; - const platformFeatures = useFeatures(); - const showToggle = protectionsEnabled && (platformFeatures.breakageScreen === "categoryTypeSelection" || platformFeatures.initialScreen === "categoryTypeSelection"); - const randomised = F(() => { - const f3 = createBreakageFeaturesFrom(platformFeatures); - return f3.categoryList({ - login: ns.report("loginV2.title") - }); - }, [platformFeatures]); - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: text }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y(Nav, null, randomised.map(([value, title]) => { - return /* @__PURE__ */ y( - NavItem, - { - key: value, - onClick: () => { - send({ name: "categorySelected", value: ( - /** @type {any} */ - value - ) }); - if (showToggle) { - push("choiceToggle", { category: value }); - } else { - push("choiceBreakageForm", { category: value }); - } - } - }, - title - ); - })))); - } - function ChoiceToggleScreen() { - const description = ns.report("tryTurningProtectionsOff.title"); - const { push } = useNav(); - const data = useData(); - const text = data.tab.domain; - const onToggle = useToggle(); - const send = useTelemetry(); - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: text, icon: "switch-shield" }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y("div", { class: "card-list--bordered" }, /* @__PURE__ */ y("div", { className: "protection-toggle" }, /* @__PURE__ */ y("div", { className: "protection-toggle__row" }, /* @__PURE__ */ y(ProtectionToggle, { model: data, toggle: onToggle })))), /* @__PURE__ */ y("div", { class: "text--center" }, /* @__PURE__ */ y( - TextLink, - { - onClick: () => { - push("choiceBreakageForm"); - send({ name: "toggleSkipped" }); - } - }, - ns.report("skipThisStep.title") - )))); - } - var validCategories = () => { - return { - ...defaultCategories(), - dislike: ns.report("dislike.title") - }; - }; - function ChoiceBreakageForm() { - const { tab } = useData(); - const sendReport = useSendReport(); - const nav = useNav(); - const showAlert = useShowAlert(); - const categories = validCategories(); - let category = nav.params.get("category"); - if (!category || !Object.hasOwnProperty.call(categories, category)) { - category = "other"; - } - const description = categories[category]; - const placeholder = category === "other" ? ns.report("otherRequired.title") : ns.report("otherOptional.title"); - function submit(e3) { - e3.preventDefault(); - const values = Object.fromEntries(new FormData(e3.target)); - const desc = String(values.description).trim(); - if (category === "other" && desc.length === 0) { - showAlert(); - } else { - sendReport({ - category, - description: desc - }); - } - } - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-third" }, /* @__PURE__ */ y(KeyInsightsMain, { title: tab.domain }, description)), /* @__PURE__ */ y("div", { className: "padding-x-third" }, /* @__PURE__ */ y( - FormElement, - { - placeholder, - after: /* @__PURE__ */ y("ul", { class: "padding-x" }, /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened.title")), /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened2.title")), /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened3.title"))), - onSubmit: submit - } - ))); - } - function NavWrapper() { - return /* @__PURE__ */ y(SecondaryTopNavAlt, null, /* @__PURE__ */ y(Title, null, ns.report("reportTitle.title"))); - } - - // v2/navigation.jsx - init_schema_parsers(); - var availableScreens = { - primaryScreen: { kind: "root", component: () => /* @__PURE__ */ y(PrimaryScreen, null) }, - // screens that would load immediately - breakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(BreakageFormScreen, { includeToggle: true }) }, - promptBreakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(BreakageFormScreen, { includeToggle: false }) }, - toggleReport: { kind: "subview", component: () => /* @__PURE__ */ y(ToggleReportScreen, null) }, - // - categoryTypeSelection: { kind: "subview", component: () => /* @__PURE__ */ y(CategoryTypeSelection, null) }, - categorySelection: { kind: "subview", component: () => /* @__PURE__ */ y(CategorySelection, null) }, - choiceToggle: { kind: "subview", component: () => /* @__PURE__ */ y(ChoiceToggleScreen, null) }, - choiceBreakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(ChoiceBreakageForm, null) }, - connection: { kind: "subview", component: () => /* @__PURE__ */ y(ConnectionScreen, null) }, - trackers: { kind: "subview", component: () => /* @__PURE__ */ y(TrackersScreen, null) }, - nonTrackers: { kind: "subview", component: () => /* @__PURE__ */ y(NonTrackersScreen, null) }, - consentManaged: { kind: "subview", component: () => /* @__PURE__ */ y(ConsentManagedScreen, { cosmetic: false }) }, - cookieHidden: { kind: "subview", component: () => /* @__PURE__ */ y(ConsentManagedScreen, { cosmetic: true }) } - }; - var entries = ( - /** @type {[ScreenName, { kind: 'subview' | 'root', component: () => any}][]} */ - Object.entries(availableScreens) - ); - var NavContext = G({ - /** @type {(name: ScreenName, params?: Record) => void} */ - push() { - throw new Error("not implemented"); - }, - /** @type {() => void} */ - pop() { - throw new Error("not implemented"); - }, - params: new URLSearchParams(""), - /** @type {() => boolean} */ - canPop: () => false, - /** @type {(screen: import('../schema/__generated__/schema.types').EventOrigin['screen']) => boolean} */ - canPopFrom: (screen) => false, - /** @type {() => ScreenName} */ - screen: () => { - throw new Error("screen() not implemented"); - } - }); - var ScreenContext = G({ - /** @type {import('../schema/__generated__/schema.types').EventOrigin['screen']} */ - screen: ( - /** @type {const} */ - "primaryScreen" - ) - }); - function useNav() { - return q2(NavContext); - } - function useCanPop() { - const { screen } = q2(ScreenContext); - const { canPopFrom } = useNav(); - return canPopFrom(screen); - } - function isScreenName(input) { - return screenKindSchema.safeParse(input).success; - } - function navReducer(state, event) { - if (!window.__ddg_integration_test) { - console.log("\u{1F4E9}", event, state); - } - switch (state.state) { - case "transitioning": { - switch (event.type) { - case "end": { - return { - ...state, - commit: [], - state: ( - /** @type {const} */ - "settled" - ) - }; - } - } - return state; - } - case "initial": - case "settled": { - switch (event.type) { - case "goto": { - if (!event.opts.animate) { - return { - ...state, - stack: event.stack, - state: ( - /** @type {const} */ - "settled" - ) - }; - } - return { - ...state, - stack: event.stack, - state: ( - /** @type {const} */ - "transitioning" - ) - }; - } - case "push": { - if (!event.opts.animate) { - return { - ...state, - stack: state.stack.concat(event.name), - state: ( - /** @type {const} */ - "settled" - ), - via: "push" - }; - } - return { - ...state, - stack: state.stack.concat(event.name), - state: ( - /** @type {const} */ - "transitioning" - ), - via: "push" - }; - } - case "pop": { - if (state.stack.length < 2) { - if (!window.__ddg_integration_test) { - console.warn("ignoring a `pop` event", window.location.search); - } - return state; - } - if (!event.opts.animate) { - const next = state.stack.slice(0, -1); - return { - ...state, - commit: next, - stack: next, - state: ( - /** @type {const} */ - "settled" - ), - via: "pop" - }; - } - return { - ...state, - commit: state.stack, - stack: state.stack.slice(0, -1), - state: ( - /** @type {const} */ - "transitioning" - ), - via: "pop" - }; - } - default: { - console.warn("ignoring", event, "state", state); - return state; - } - } - } - default: - throw new Error("unreachable"); - } - } - function Navigation(props) { - const [state, dispatch] = s2(navReducer, { - stack: props.stack, - state: "initial", - commit: [], - via: void 0 - }); - const parentRef = _(null); - p2(() => { - const curr = parentRef.current; - if (!curr) - return; - const handler = (e3) => { - if (e3.target !== parentRef.current) - return; - dispatch({ type: "end" }); - }; - curr.addEventListener("transitionend", handler); - return () => { - curr.removeEventListener("transitionend", handler); - }; - }, [state.state]); - p2(() => { - function popstateHandler() { - const currentUrlParams = new URLSearchParams(location.search); - const currentURLStack = currentUrlParams.getAll("stack"); - const navigationIntentionIsForwards = currentURLStack.length > state.stack.length; - if (navigationIntentionIsForwards) { - const lastEntry = currentURLStack[currentURLStack.length - 1]; - if (isScreenName(lastEntry)) { - dispatch({ type: "push", name: lastEntry, opts: { animate: props.animate && isAndroid() } }); - } - } else { - dispatch({ type: "pop", opts: { animate: props.animate && isAndroid() } }); - } - } - window.addEventListener("popstate", popstateHandler); - return () => { - window.removeEventListener("popstate", popstateHandler); - }; - }, [state.state, state.stack, state.via, props.animate]); - const canPop = T2(() => { - if (state.state === "transitioning") { - return state.commit.length > 1 || state.stack.length > 1; - } - return state.stack.length > 1; - }, [state.state, state.stack, state.commit]); - const canPopFrom = T2( - (screen2) => { - if (state.stack[0] === screen2) - return false; - return canPop(); - }, - [state.state, state.stack, state.commit] - ); - const screen = T2(() => { - const v3 = ( - /** @type {ScreenName} */ - state.stack[state.stack.length - 1] - ); - return v3; - }, [state.state, state.stack, state.commit]); - const api = { - /** - * @param {ScreenName} name - * @param {Record} params - */ - push: (name, params = {}) => { - const url = new URL(window.location.href); - for (let [key, value] of Object.entries(params)) { - url.searchParams.set(key, value); - } - url.searchParams.delete("stack"); - for (let string of state.stack) { - url.searchParams.append("stack", string); - } - url.searchParams.append("stack", name); - window.history.pushState({}, "", url); - dispatch({ type: "push", name, opts: { animate: props.animate } }); - }, - pop: () => { - window.history.go(-1); - dispatch({ type: "pop", opts: { animate: props.animate } }); - }, - canPop, - canPopFrom, - screen, - get params() { - return new URLSearchParams(location.search); - } - }; - return /* @__PURE__ */ y(NavContext.Provider, { value: api }, /* @__PURE__ */ y( - "div", - { - id: "popup-container", - ref: parentRef, - className: (0, import_classnames3.default)({ - "sliding-subview-v2": true, - "sliding-subview-v2--root": true, - "sliding-subview-v2--animating": state.state === "transitioning" - }), - style: { - transform: `translateX(` + -((state.stack.length - 1) * 100) + "%)" - } - }, - entries.map(([screenName, item]) => { - const inStack = state.stack.includes(screenName); - const commiting = state.commit.includes(screenName); - const current = state.stack[state.stack.length - 1] === screenName; - if (!inStack && !commiting) - return null; - if (item.kind === "root") { - return /* @__PURE__ */ y(ScreenContext.Provider, { value: { screen: screenName } }, /* @__PURE__ */ y("section", { className: "app-height", key: screenName, "data-testid": `subview-${screenName}` }, item.component())); - } - const translateValue = state.stack.includes(screenName) ? state.stack.indexOf(screenName) : state.commit.includes(screenName) ? state.commit.indexOf(screenName) : 0; - const cssProp = `translateX(${translateValue * 100}%)`; - return /* @__PURE__ */ y(ScreenContext.Provider, { value: { screen: screenName } }, /* @__PURE__ */ y( - "section", - { - "data-current": String(current), - className: "sliding-subview-v2", - key: screenName, - style: { transform: cssProp } - }, - item.component() - )); - }) - )); - } - - // v2/settings.jsx - var SettingsContext = G({ - /** @type {boolean} */ - reducedMotion: false - }); - function SettingsProvider({ children }) { - const [reducedMotion, setReducedMotion] = h2(window.matchMedia("(prefers-reduced-motion: reduce)").matches); - p2(() => { - const mediaQueryList = window.matchMedia("(prefers-reduced-motion: reduce)"); - const listener = (event) => setReducedMotion(event.matches); - mediaQueryList.addEventListener("change", listener); - return () => { - mediaQueryList.removeEventListener("change", listener); - }; - }, []); - return /* @__PURE__ */ y(SettingsContext.Provider, { value: { reducedMotion } }, children); - } - function useGlobalSettings() { - return q2(SettingsContext); - } - - // v2/app.jsx - function App() { - const { reducedMotion } = useGlobalSettings(); - const data = useFeatures(); - const stack = initialStack(data); - return /* @__PURE__ */ y(Navigation, { stack, animate: !reducedMotion, params: new URLSearchParams(window.location.search) }); - } - function initialStack(features) { - if (features.initialScreen === "breakageForm") { - return ["breakageForm"]; - } - if (features.initialScreen === "promptBreakageForm") { - return ["promptBreakageForm"]; - } - if (features.initialScreen === "toggleReport") { - return ["toggleReport"]; - } - if (features.initialScreen === "choiceBreakageForm") { - return ["choiceBreakageForm"]; - } - if (features.initialScreen === "categoryTypeSelection") { - return ["categoryTypeSelection"]; - } - if (features.initialScreen === "categorySelection") { - return ["categorySelection"]; - } - return ["primaryScreen"]; - } - - // v2/index.jsx - window.onunhandledrejection = (event) => { - console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`); - }; - async function init2() { - const app = document.querySelector("#app"); - if (!app) - throw new Error("unreachable"); - B( - /* @__PURE__ */ y(SettingsProvider, null, /* @__PURE__ */ y(DataProvider, null, /* @__PURE__ */ y(App, null))), - app - ); - } - init2().catch((e3) => { - console.error("start up error", e3); - }); -})(); -/*! Bundled license information: - -classnames/index.js: - (*! - Copyright (c) 2018 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames - *) - -@material/base/foundation.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/base/component.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/dom/events.js: - (** - * @license - * Copyright 2019 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/dom/ponyfill.js: - (** - * @license - * Copyright 2018 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/ripple/constants.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/ripple/foundation.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/ripple/component.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) -*/ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js deleted file mode 100644 index 341914af7d7b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * https://bugs.chromium.org/p/v8/issues/detail?id=10682 - */ -function hasIntlGetCanonicalLocalesBug() { - try { - return new Intl.Locale('und-x-private').toString() === 'x-private'; - } catch (e) { - return true; - } -} -function shouldPolyfill() { - return !('Locale' in Intl) || hasIntlGetCanonicalLocalesBug(); -} -/** - * Load the Intl.Locale polyfill if needed - */ -if (shouldPolyfill()) { - const script = document.createElement('script'); - script.src = '../public/js/polyfills.js'; - document.head.appendChild(script); -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js deleted file mode 100644 index 363804777119..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js +++ /dev/null @@ -1,6801 +0,0 @@ -"use strict"; -(() => { - var __create = Object.create; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __getProtoOf = Object.getPrototypeOf; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __esm = (fn, res) => function __init() { - return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; - }; - var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; - }; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod - )); - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - - // node_modules/tslib/tslib.es6.js - var tslib_es6_exports = {}; - __export(tslib_es6_exports, { - __assign: () => __assign, - __asyncDelegator: () => __asyncDelegator, - __asyncGenerator: () => __asyncGenerator, - __asyncValues: () => __asyncValues, - __await: () => __await, - __awaiter: () => __awaiter, - __classPrivateFieldGet: () => __classPrivateFieldGet, - __classPrivateFieldIn: () => __classPrivateFieldIn, - __classPrivateFieldSet: () => __classPrivateFieldSet, - __createBinding: () => __createBinding, - __decorate: () => __decorate, - __exportStar: () => __exportStar, - __extends: () => __extends, - __generator: () => __generator, - __importDefault: () => __importDefault, - __importStar: () => __importStar, - __makeTemplateObject: () => __makeTemplateObject, - __metadata: () => __metadata, - __param: () => __param, - __read: () => __read, - __rest: () => __rest, - __spread: () => __spread, - __spreadArray: () => __spreadArray, - __spreadArrays: () => __spreadArrays, - __values: () => __values - }); - function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { - this.constructor = d; - } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - } - function __rest(s, e) { - var t = {}; - for (var p in s) - if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; - } - function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") - r = Reflect.decorate(decorators, target, key, desc); - else - for (var i = decorators.length - 1; i >= 0; i--) - if (d = decorators[i]) - r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - } - function __param(paramIndex, decorator) { - return function(target, key) { - decorator(target, key, paramIndex); - }; - } - function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") - return Reflect.metadata(metadataKey, metadataValue); - } - function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); - }); - } - return new (P || (P = Promise))(function(resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - } - function rejected(value) { - try { - step(generator["throw"](value)); - } catch (e) { - reject(e); - } - } - function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); - } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - } - function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { - if (t[0] & 1) - throw t[1]; - return t[1]; - }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { - return this; - }), g; - function verb(n) { - return function(v) { - return step([n, v]); - }; - } - function step(op) { - if (f) - throw new TypeError("Generator is already executing."); - while (_) - try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) - return t; - if (y = 0, t) - op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: - case 1: - t = op; - break; - case 4: - _.label++; - return { value: op[1], done: false }; - case 5: - _.label++; - y = op[1]; - op = [0]; - continue; - case 7: - op = _.ops.pop(); - _.trys.pop(); - continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { - _ = 0; - continue; - } - if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { - _.label = op[1]; - break; - } - if (op[0] === 6 && _.label < t[1]) { - _.label = t[1]; - t = op; - break; - } - if (t && _.label < t[2]) { - _.label = t[2]; - _.ops.push(op); - break; - } - if (t[2]) - _.ops.pop(); - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } catch (e) { - op = [6, e]; - y = 0; - } finally { - f = t = 0; - } - if (op[0] & 5) - throw op[1]; - return { value: op[0] ? op[1] : void 0, done: true }; - } - } - function __exportStar(m, o) { - for (var p in m) - if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) - __createBinding(o, m, p); - } - function __values(o) { - var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; - if (m) - return m.call(o); - if (o && typeof o.length === "number") - return { - next: function() { - if (o && i >= o.length) - o = void 0; - return { value: o && o[i++], done: !o }; - } - }; - throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); - } - function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) - return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) - ar.push(r.value); - } catch (error) { - e = { error }; - } finally { - try { - if (r && !r.done && (m = i["return"])) - m.call(i); - } finally { - if (e) - throw e.error; - } - } - return ar; - } - function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; - } - function __spreadArrays() { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) - s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; - } - function __spreadArray(to, from, pack) { - if (pack || arguments.length === 2) - for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) - ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); - } - function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); - } - function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) - throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { - return this; - }, i; - function verb(n) { - if (g[n]) - i[n] = function(v) { - return new Promise(function(a, b) { - q.push([n, v, a, b]) > 1 || resume(n, v); - }); - }; - } - function resume(n, v) { - try { - step(g[n](v)); - } catch (e) { - settle(q[0][3], e); - } - } - function step(r) { - r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); - } - function fulfill(value) { - resume("next", value); - } - function reject(value) { - resume("throw", value); - } - function settle(f, v) { - if (f(v), q.shift(), q.length) - resume(q[0][0], q[0][1]); - } - } - function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function(e) { - throw e; - }), verb("return"), i[Symbol.iterator] = function() { - return this; - }, i; - function verb(n, f) { - i[n] = o[n] ? function(v) { - return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; - } : f; - } - } - function __asyncValues(o) { - if (!Symbol.asyncIterator) - throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { - return this; - }, i); - function verb(n) { - i[n] = o[n] && function(v) { - return new Promise(function(resolve, reject) { - v = o[n](v), settle(resolve, reject, v.done, v.value); - }); - }; - } - function settle(resolve, reject, d, v) { - Promise.resolve(v).then(function(v2) { - resolve({ value: v2, done: d }); - }, reject); - } - } - function __makeTemplateObject(cooked, raw) { - if (Object.defineProperty) { - Object.defineProperty(cooked, "raw", { value: raw }); - } else { - cooked.raw = raw; - } - return cooked; - } - function __importStar(mod) { - if (mod && mod.__esModule) - return mod; - var result = {}; - if (mod != null) { - for (var k in mod) - if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) - __createBinding(result, mod, k); - } - __setModuleDefault(result, mod); - return result; - } - function __importDefault(mod) { - return mod && mod.__esModule ? mod : { default: mod }; - } - function __classPrivateFieldGet(receiver, state, kind, f) { - if (kind === "a" && !f) - throw new TypeError("Private accessor was defined without a getter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) - throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); - } - function __classPrivateFieldSet(receiver, state, value, kind, f) { - if (kind === "m") - throw new TypeError("Private method is not writable"); - if (kind === "a" && !f) - throw new TypeError("Private accessor was defined without a setter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) - throw new TypeError("Cannot write private member to an object whose class did not declare it"); - return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; - } - function __classPrivateFieldIn(state, receiver) { - if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") - throw new TypeError("Cannot use 'in' operator on non-object"); - return typeof state === "function" ? receiver === state : state.has(receiver); - } - var extendStatics, __assign, __createBinding, __setModuleDefault; - var init_tslib_es6 = __esm({ - "node_modules/tslib/tslib.es6.js"() { - extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { - d2.__proto__ = b2; - } || function(d2, b2) { - for (var p in b2) - if (Object.prototype.hasOwnProperty.call(b2, p)) - d2[p] = b2[p]; - }; - return extendStatics(d, b); - }; - __assign = function() { - __assign = Object.assign || function __assign2(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) - if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); - }; - __createBinding = Object.create ? function(o, m, k, k2) { - if (k2 === void 0) - k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { - return m[k]; - } }; - } - Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { - if (k2 === void 0) - k2 = k; - o[k2] = m[k]; - }; - __setModuleDefault = Object.create ? function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); - } : function(o, v) { - o["default"] = v; - }; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeLocaleList.js - var require_CanonicalizeLocaleList = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeLocaleList.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CanonicalizeLocaleList = void 0; - function CanonicalizeLocaleList(locales) { - return Intl.getCanonicalLocales(locales); - } - exports.CanonicalizeLocaleList = CanonicalizeLocaleList; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeTimeZoneName.js - var require_CanonicalizeTimeZoneName = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeTimeZoneName.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CanonicalizeTimeZoneName = void 0; - function CanonicalizeTimeZoneName(tz, _a) { - var tzData = _a.tzData, uppercaseLinks = _a.uppercaseLinks; - var uppercasedTz = tz.toUpperCase(); - var uppercasedZones = Object.keys(tzData).reduce(function(all, z) { - all[z.toUpperCase()] = z; - return all; - }, {}); - var ianaTimeZone = uppercaseLinks[uppercasedTz] || uppercasedZones[uppercasedTz]; - if (ianaTimeZone === "Etc/UTC" || ianaTimeZone === "Etc/GMT") { - return "UTC"; - } - return ianaTimeZone; - } - exports.CanonicalizeTimeZoneName = CanonicalizeTimeZoneName; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/262.js - var require__ = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/262.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.msFromTime = exports.OrdinaryHasInstance = exports.SecFromTime = exports.MinFromTime = exports.HourFromTime = exports.DateFromTime = exports.MonthFromTime = exports.InLeapYear = exports.DayWithinYear = exports.DaysInYear = exports.YearFromTime = exports.TimeFromYear = exports.DayFromYear = exports.WeekDay = exports.Day = exports.Type = exports.HasOwnProperty = exports.ArrayCreate = exports.SameValue = exports.ToObject = exports.TimeClip = exports.ToNumber = exports.ToString = void 0; - function ToString(o) { - if (typeof o === "symbol") { - throw TypeError("Cannot convert a Symbol value to a string"); - } - return String(o); - } - exports.ToString = ToString; - function ToNumber(val) { - if (val === void 0) { - return NaN; - } - if (val === null) { - return 0; - } - if (typeof val === "boolean") { - return val ? 1 : 0; - } - if (typeof val === "number") { - return val; - } - if (typeof val === "symbol" || typeof val === "bigint") { - throw new TypeError("Cannot convert symbol/bigint to number"); - } - return Number(val); - } - exports.ToNumber = ToNumber; - function ToInteger(n) { - var number = ToNumber(n); - if (isNaN(number) || SameValue(number, -0)) { - return 0; - } - if (isFinite(number)) { - return number; - } - var integer = Math.floor(Math.abs(number)); - if (number < 0) { - integer = -integer; - } - if (SameValue(integer, -0)) { - return 0; - } - return integer; - } - function TimeClip(time) { - if (!isFinite(time)) { - return NaN; - } - if (Math.abs(time) > 8.64 * 1e15) { - return NaN; - } - return ToInteger(time); - } - exports.TimeClip = TimeClip; - function ToObject(arg) { - if (arg == null) { - throw new TypeError("undefined/null cannot be converted to object"); - } - return Object(arg); - } - exports.ToObject = ToObject; - function SameValue(x, y) { - if (Object.is) { - return Object.is(x, y); - } - if (x === y) { - return x !== 0 || 1 / x === 1 / y; - } - return x !== x && y !== y; - } - exports.SameValue = SameValue; - function ArrayCreate(len) { - return new Array(len); - } - exports.ArrayCreate = ArrayCreate; - function HasOwnProperty(o, prop) { - return Object.prototype.hasOwnProperty.call(o, prop); - } - exports.HasOwnProperty = HasOwnProperty; - function Type(x) { - if (x === null) { - return "Null"; - } - if (typeof x === "undefined") { - return "Undefined"; - } - if (typeof x === "function" || typeof x === "object") { - return "Object"; - } - if (typeof x === "number") { - return "Number"; - } - if (typeof x === "boolean") { - return "Boolean"; - } - if (typeof x === "string") { - return "String"; - } - if (typeof x === "symbol") { - return "Symbol"; - } - if (typeof x === "bigint") { - return "BigInt"; - } - } - exports.Type = Type; - var MS_PER_DAY = 864e5; - function mod(x, y) { - return x - Math.floor(x / y) * y; - } - function Day(t) { - return Math.floor(t / MS_PER_DAY); - } - exports.Day = Day; - function WeekDay(t) { - return mod(Day(t) + 4, 7); - } - exports.WeekDay = WeekDay; - function DayFromYear(y) { - return Date.UTC(y, 0) / MS_PER_DAY; - } - exports.DayFromYear = DayFromYear; - function TimeFromYear(y) { - return Date.UTC(y, 0); - } - exports.TimeFromYear = TimeFromYear; - function YearFromTime(t) { - return new Date(t).getUTCFullYear(); - } - exports.YearFromTime = YearFromTime; - function DaysInYear(y) { - if (y % 4 !== 0) { - return 365; - } - if (y % 100 !== 0) { - return 366; - } - if (y % 400 !== 0) { - return 365; - } - return 366; - } - exports.DaysInYear = DaysInYear; - function DayWithinYear(t) { - return Day(t) - DayFromYear(YearFromTime(t)); - } - exports.DayWithinYear = DayWithinYear; - function InLeapYear(t) { - return DaysInYear(YearFromTime(t)) === 365 ? 0 : 1; - } - exports.InLeapYear = InLeapYear; - function MonthFromTime(t) { - var dwy = DayWithinYear(t); - var leap = InLeapYear(t); - if (dwy >= 0 && dwy < 31) { - return 0; - } - if (dwy < 59 + leap) { - return 1; - } - if (dwy < 90 + leap) { - return 2; - } - if (dwy < 120 + leap) { - return 3; - } - if (dwy < 151 + leap) { - return 4; - } - if (dwy < 181 + leap) { - return 5; - } - if (dwy < 212 + leap) { - return 6; - } - if (dwy < 243 + leap) { - return 7; - } - if (dwy < 273 + leap) { - return 8; - } - if (dwy < 304 + leap) { - return 9; - } - if (dwy < 334 + leap) { - return 10; - } - if (dwy < 365 + leap) { - return 11; - } - throw new Error("Invalid time"); - } - exports.MonthFromTime = MonthFromTime; - function DateFromTime(t) { - var dwy = DayWithinYear(t); - var mft = MonthFromTime(t); - var leap = InLeapYear(t); - if (mft === 0) { - return dwy + 1; - } - if (mft === 1) { - return dwy - 30; - } - if (mft === 2) { - return dwy - 58 - leap; - } - if (mft === 3) { - return dwy - 89 - leap; - } - if (mft === 4) { - return dwy - 119 - leap; - } - if (mft === 5) { - return dwy - 150 - leap; - } - if (mft === 6) { - return dwy - 180 - leap; - } - if (mft === 7) { - return dwy - 211 - leap; - } - if (mft === 8) { - return dwy - 242 - leap; - } - if (mft === 9) { - return dwy - 272 - leap; - } - if (mft === 10) { - return dwy - 303 - leap; - } - if (mft === 11) { - return dwy - 333 - leap; - } - throw new Error("Invalid time"); - } - exports.DateFromTime = DateFromTime; - var HOURS_PER_DAY = 24; - var MINUTES_PER_HOUR = 60; - var SECONDS_PER_MINUTE = 60; - var MS_PER_SECOND = 1e3; - var MS_PER_MINUTE = MS_PER_SECOND * SECONDS_PER_MINUTE; - var MS_PER_HOUR = MS_PER_MINUTE * MINUTES_PER_HOUR; - function HourFromTime(t) { - return mod(Math.floor(t / MS_PER_HOUR), HOURS_PER_DAY); - } - exports.HourFromTime = HourFromTime; - function MinFromTime(t) { - return mod(Math.floor(t / MS_PER_MINUTE), MINUTES_PER_HOUR); - } - exports.MinFromTime = MinFromTime; - function SecFromTime(t) { - return mod(Math.floor(t / MS_PER_SECOND), SECONDS_PER_MINUTE); - } - exports.SecFromTime = SecFromTime; - function IsCallable(fn) { - return typeof fn === "function"; - } - function OrdinaryHasInstance(C, O, internalSlots) { - if (!IsCallable(C)) { - return false; - } - if (internalSlots === null || internalSlots === void 0 ? void 0 : internalSlots.boundTargetFunction) { - var BC = internalSlots === null || internalSlots === void 0 ? void 0 : internalSlots.boundTargetFunction; - return O instanceof BC; - } - if (typeof O !== "object") { - return false; - } - var P = C.prototype; - if (typeof P !== "object") { - throw new TypeError("OrdinaryHasInstance called on an object with an invalid prototype property."); - } - return Object.prototype.isPrototypeOf.call(P, O); - } - exports.OrdinaryHasInstance = OrdinaryHasInstance; - function msFromTime(t) { - return mod(t, MS_PER_SECOND); - } - exports.msFromTime = msFromTime; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CoerceOptionsToObject.js - var require_CoerceOptionsToObject = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CoerceOptionsToObject.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CoerceOptionsToObject = void 0; - var _262_1 = require__(); - function CoerceOptionsToObject(options) { - if (typeof options === "undefined") { - return /* @__PURE__ */ Object.create(null); - } - return (0, _262_1.ToObject)(options); - } - exports.CoerceOptionsToObject = CoerceOptionsToObject; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/DefaultNumberOption.js - var require_DefaultNumberOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/DefaultNumberOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.DefaultNumberOption = void 0; - function DefaultNumberOption(val, min, max, fallback) { - if (val !== void 0) { - val = Number(val); - if (isNaN(val) || val < min || val > max) { - throw new RangeError("".concat(val, " is outside of range [").concat(min, ", ").concat(max, "]")); - } - return Math.floor(val); - } - return fallback; - } - exports.DefaultNumberOption = DefaultNumberOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetNumberOption.js - var require_GetNumberOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetNumberOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetNumberOption = void 0; - var DefaultNumberOption_1 = require_DefaultNumberOption(); - function GetNumberOption(options, property, minimum, maximum, fallback) { - var val = options[property]; - return (0, DefaultNumberOption_1.DefaultNumberOption)(val, minimum, maximum, fallback); - } - exports.GetNumberOption = GetNumberOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOption.js - var require_GetOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetOption = void 0; - var _262_1 = require__(); - function GetOption(opts, prop, type, values, fallback) { - if (typeof opts !== "object") { - throw new TypeError("Options must be an object"); - } - var value = opts[prop]; - if (value !== void 0) { - if (type !== "boolean" && type !== "string") { - throw new TypeError("invalid type"); - } - if (type === "boolean") { - value = Boolean(value); - } - if (type === "string") { - value = (0, _262_1.ToString)(value); - } - if (values !== void 0 && !values.filter(function(val) { - return val == value; - }).length) { - throw new RangeError("".concat(value, " is not within ").concat(values.join(", "))); - } - return value; - } - return fallback; - } - exports.GetOption = GetOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOptionsObject.js - var require_GetOptionsObject = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOptionsObject.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetOptionsObject = void 0; - function GetOptionsObject(options) { - if (typeof options === "undefined") { - return /* @__PURE__ */ Object.create(null); - } - if (typeof options === "object") { - return options; - } - throw new TypeError("Options must be an object"); - } - exports.GetOptionsObject = GetOptionsObject; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetStringOrBooleanOption.js - var require_GetStringOrBooleanOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetStringOrBooleanOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetStringOrBooleanOption = void 0; - var _262_1 = require__(); - function GetStringOrBooleanOption(opts, prop, values, trueValue, falsyValue, fallback) { - var value = opts[prop]; - if (value === void 0) { - return fallback; - } - if (value === true) { - return trueValue; - } - var valueBoolean = Boolean(value); - if (valueBoolean === false) { - return falsyValue; - } - value = (0, _262_1.ToString)(value); - if (value === "true" || value === "false") { - return fallback; - } - if ((values || []).indexOf(value) === -1) { - throw new RangeError("Invalid value ".concat(value)); - } - return value; - } - exports.GetStringOrBooleanOption = GetStringOrBooleanOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsSanctionedSimpleUnitIdentifier.js - var require_IsSanctionedSimpleUnitIdentifier = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsSanctionedSimpleUnitIdentifier.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsSanctionedSimpleUnitIdentifier = exports.SIMPLE_UNITS = exports.removeUnitNamespace = exports.SANCTIONED_UNITS = void 0; - exports.SANCTIONED_UNITS = [ - "angle-degree", - "area-acre", - "area-hectare", - "concentr-percent", - "digital-bit", - "digital-byte", - "digital-gigabit", - "digital-gigabyte", - "digital-kilobit", - "digital-kilobyte", - "digital-megabit", - "digital-megabyte", - "digital-petabyte", - "digital-terabit", - "digital-terabyte", - "duration-day", - "duration-hour", - "duration-millisecond", - "duration-minute", - "duration-month", - "duration-second", - "duration-week", - "duration-year", - "length-centimeter", - "length-foot", - "length-inch", - "length-kilometer", - "length-meter", - "length-mile-scandinavian", - "length-mile", - "length-millimeter", - "length-yard", - "mass-gram", - "mass-kilogram", - "mass-ounce", - "mass-pound", - "mass-stone", - "temperature-celsius", - "temperature-fahrenheit", - "volume-fluid-ounce", - "volume-gallon", - "volume-liter", - "volume-milliliter" - ]; - function removeUnitNamespace(unit) { - return unit.slice(unit.indexOf("-") + 1); - } - exports.removeUnitNamespace = removeUnitNamespace; - exports.SIMPLE_UNITS = exports.SANCTIONED_UNITS.map(removeUnitNamespace); - function IsSanctionedSimpleUnitIdentifier(unitIdentifier) { - return exports.SIMPLE_UNITS.indexOf(unitIdentifier) > -1; - } - exports.IsSanctionedSimpleUnitIdentifier = IsSanctionedSimpleUnitIdentifier; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsValidTimeZoneName.js - var require_IsValidTimeZoneName = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsValidTimeZoneName.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsValidTimeZoneName = void 0; - function IsValidTimeZoneName(tz, _a) { - var tzData = _a.tzData, uppercaseLinks = _a.uppercaseLinks; - var uppercasedTz = tz.toUpperCase(); - var zoneNames = /* @__PURE__ */ new Set(); - var linkNames = /* @__PURE__ */ new Set(); - Object.keys(tzData).map(function(z) { - return z.toUpperCase(); - }).forEach(function(z) { - return zoneNames.add(z); - }); - Object.keys(uppercaseLinks).forEach(function(linkName) { - linkNames.add(linkName.toUpperCase()); - zoneNames.add(uppercaseLinks[linkName].toUpperCase()); - }); - return zoneNames.has(uppercasedTz) || linkNames.has(uppercasedTz); - } - exports.IsValidTimeZoneName = IsValidTimeZoneName; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedCurrencyCode.js - var require_IsWellFormedCurrencyCode = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedCurrencyCode.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsWellFormedCurrencyCode = void 0; - function toUpperCase(str) { - return str.replace(/([a-z])/g, function(_, c) { - return c.toUpperCase(); - }); - } - var NOT_A_Z_REGEX = /[^A-Z]/; - function IsWellFormedCurrencyCode(currency) { - currency = toUpperCase(currency); - if (currency.length !== 3) { - return false; - } - if (NOT_A_Z_REGEX.test(currency)) { - return false; - } - return true; - } - exports.IsWellFormedCurrencyCode = IsWellFormedCurrencyCode; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedUnitIdentifier.js - var require_IsWellFormedUnitIdentifier = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedUnitIdentifier.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsWellFormedUnitIdentifier = void 0; - var IsSanctionedSimpleUnitIdentifier_1 = require_IsSanctionedSimpleUnitIdentifier(); - function toLowerCase(str) { - return str.replace(/([A-Z])/g, function(_, c) { - return c.toLowerCase(); - }); - } - function IsWellFormedUnitIdentifier(unit) { - unit = toLowerCase(unit); - if ((0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(unit)) { - return true; - } - var units = unit.split("-per-"); - if (units.length !== 2) { - return false; - } - var numerator = units[0], denominator = units[1]; - if (!(0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(numerator) || !(0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(denominator)) { - return false; - } - return true; - } - exports.IsWellFormedUnitIdentifier = IsWellFormedUnitIdentifier; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ApplyUnsignedRoundingMode.js - var require_ApplyUnsignedRoundingMode = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ApplyUnsignedRoundingMode.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ApplyUnsignedRoundingMode = void 0; - function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) { - if (x === r1) - return r1; - if (unsignedRoundingMode === void 0) { - throw new Error("unsignedRoundingMode is mandatory"); - } - if (unsignedRoundingMode === "zero") { - return r1; - } - if (unsignedRoundingMode === "infinity") { - return r2; - } - var d1 = x - r1; - var d2 = r2 - x; - if (d1 < d2) { - return r1; - } - if (d2 < d1) { - return r2; - } - if (d1 !== d2) { - throw new Error("Unexpected error"); - } - if (unsignedRoundingMode === "half-zero") { - return r1; - } - if (unsignedRoundingMode === "half-infinity") { - return r2; - } - if (unsignedRoundingMode !== "half-even") { - throw new Error("Unexpected value for unsignedRoundingMode: ".concat(unsignedRoundingMode)); - } - var cardinality = r1 / (r2 - r1) % 2; - if (cardinality === 0) { - return r1; - } - return r2; - } - exports.ApplyUnsignedRoundingMode = ApplyUnsignedRoundingMode; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CollapseNumberRange.js - var require_CollapseNumberRange = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CollapseNumberRange.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CollapseNumberRange = void 0; - function CollapseNumberRange(result) { - return result; - } - exports.CollapseNumberRange = CollapseNumberRange; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/utils.js - var require_utils = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = exports.defineProperty = exports.isLiteralPart = exports.getMultiInternalSlots = exports.getInternalSlot = exports.setMultiInternalSlots = exports.setInternalSlot = exports.repeat = exports.getMagnitude = void 0; - function getMagnitude(x) { - return Math.floor(Math.log(x) * Math.LOG10E); - } - exports.getMagnitude = getMagnitude; - function repeat(s, times) { - if (typeof s.repeat === "function") { - return s.repeat(times); - } - var arr = new Array(times); - for (var i = 0; i < arr.length; i++) { - arr[i] = s; - } - return arr.join(""); - } - exports.repeat = repeat; - function setInternalSlot(map, pl, field, value) { - if (!map.get(pl)) { - map.set(pl, /* @__PURE__ */ Object.create(null)); - } - var slots = map.get(pl); - slots[field] = value; - } - exports.setInternalSlot = setInternalSlot; - function setMultiInternalSlots(map, pl, props) { - for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) { - var k = _a[_i]; - setInternalSlot(map, pl, k, props[k]); - } - } - exports.setMultiInternalSlots = setMultiInternalSlots; - function getInternalSlot(map, pl, field) { - return getMultiInternalSlots(map, pl, field)[field]; - } - exports.getInternalSlot = getInternalSlot; - function getMultiInternalSlots(map, pl) { - var fields = []; - for (var _i = 2; _i < arguments.length; _i++) { - fields[_i - 2] = arguments[_i]; - } - var slots = map.get(pl); - if (!slots) { - throw new TypeError("".concat(pl, " InternalSlot has not been initialized")); - } - return fields.reduce(function(all, f) { - all[f] = slots[f]; - return all; - }, /* @__PURE__ */ Object.create(null)); - } - exports.getMultiInternalSlots = getMultiInternalSlots; - function isLiteralPart(patternPart) { - return patternPart.type === "literal"; - } - exports.isLiteralPart = isLiteralPart; - function defineProperty(target, name, _a) { - var value = _a.value; - Object.defineProperty(target, name, { - configurable: true, - enumerable: false, - writable: true, - value - }); - } - exports.defineProperty = defineProperty; - exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; - function invariant(condition, message, Err) { - if (Err === void 0) { - Err = Error; - } - if (!condition) { - throw new Err(message); - } - } - exports.invariant = invariant; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponentForMagnitude.js - var require_ComputeExponentForMagnitude = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponentForMagnitude.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ComputeExponentForMagnitude = void 0; - function ComputeExponentForMagnitude(numberFormat, magnitude, _a) { - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - var notation = internalSlots.notation, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem; - switch (notation) { - case "standard": - return 0; - case "scientific": - return magnitude; - case "engineering": - return Math.floor(magnitude / 3) * 3; - default: { - var compactDisplay = internalSlots.compactDisplay, style = internalSlots.style, currencyDisplay = internalSlots.currencyDisplay; - var thresholdMap = void 0; - if (style === "currency" && currencyDisplay !== "name") { - var currency = dataLocaleData.numbers.currency[numberingSystem] || dataLocaleData.numbers.currency[dataLocaleData.numbers.nu[0]]; - thresholdMap = currency.short; - } else { - var decimal = dataLocaleData.numbers.decimal[numberingSystem] || dataLocaleData.numbers.decimal[dataLocaleData.numbers.nu[0]]; - thresholdMap = compactDisplay === "long" ? decimal.long : decimal.short; - } - if (!thresholdMap) { - return 0; - } - var num = String(Math.pow(10, magnitude)); - var thresholds = Object.keys(thresholdMap); - if (num < thresholds[0]) { - return 0; - } - if (num > thresholds[thresholds.length - 1]) { - return thresholds[thresholds.length - 1].length - 1; - } - var i = thresholds.indexOf(num); - if (i === -1) { - return 0; - } - var magnitudeKey = thresholds[i]; - var compactPattern = thresholdMap[magnitudeKey].other; - if (compactPattern === "0") { - return 0; - } - return magnitudeKey.length - thresholdMap[magnitudeKey].other.match(/0+/)[0].length; - } - } - } - exports.ComputeExponentForMagnitude = ComputeExponentForMagnitude; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawPrecision.js - var require_ToRawPrecision = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawPrecision.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ToRawPrecision = void 0; - var utils_1 = require_utils(); - function ToRawPrecision(x, minPrecision, maxPrecision) { - var p = maxPrecision; - var m; - var e; - var xFinal; - if (x === 0) { - m = (0, utils_1.repeat)("0", p); - e = 0; - xFinal = 0; - } else { - var xToString = x.toString(); - var xToStringExponentIndex = xToString.indexOf("e"); - var _a = xToString.split("e"), xToStringMantissa = _a[0], xToStringExponent = _a[1]; - var xToStringMantissaWithoutDecimalPoint = xToStringMantissa.replace(".", ""); - if (xToStringExponentIndex >= 0 && xToStringMantissaWithoutDecimalPoint.length <= p) { - e = +xToStringExponent; - m = xToStringMantissaWithoutDecimalPoint + (0, utils_1.repeat)("0", p - xToStringMantissaWithoutDecimalPoint.length); - xFinal = x; - } else { - e = (0, utils_1.getMagnitude)(x); - var decimalPlaceOffset = e - p + 1; - var n = Math.round(adjustDecimalPlace(x, decimalPlaceOffset)); - if (adjustDecimalPlace(n, p - 1) >= 10) { - e = e + 1; - n = Math.floor(n / 10); - } - m = n.toString(); - xFinal = adjustDecimalPlace(n, p - 1 - e); - } - } - var int; - if (e >= p - 1) { - m = m + (0, utils_1.repeat)("0", e - p + 1); - int = e + 1; - } else if (e >= 0) { - m = "".concat(m.slice(0, e + 1), ".").concat(m.slice(e + 1)); - int = e + 1; - } else { - m = "0.".concat((0, utils_1.repeat)("0", -e - 1)).concat(m); - int = 1; - } - if (m.indexOf(".") >= 0 && maxPrecision > minPrecision) { - var cut = maxPrecision - minPrecision; - while (cut > 0 && m[m.length - 1] === "0") { - m = m.slice(0, -1); - cut--; - } - if (m[m.length - 1] === ".") { - m = m.slice(0, -1); - } - } - return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; - function adjustDecimalPlace(x2, magnitude) { - return magnitude < 0 ? x2 * Math.pow(10, -magnitude) : x2 / Math.pow(10, magnitude); - } - } - exports.ToRawPrecision = ToRawPrecision; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawFixed.js - var require_ToRawFixed = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawFixed.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ToRawFixed = void 0; - var utils_1 = require_utils(); - function ToRawFixed(x, minFraction, maxFraction) { - var f = maxFraction; - var n = Math.round(x * Math.pow(10, f)); - var xFinal = n / Math.pow(10, f); - var m; - if (n < 1e21) { - m = n.toString(); - } else { - m = n.toString(); - var _a = m.split("e"), mantissa = _a[0], exponent = _a[1]; - m = mantissa.replace(".", ""); - m = m + (0, utils_1.repeat)("0", Math.max(+exponent - m.length + 1, 0)); - } - var int; - if (f !== 0) { - var k = m.length; - if (k <= f) { - var z = (0, utils_1.repeat)("0", f + 1 - k); - m = z + m; - k = f + 1; - } - var a = m.slice(0, k - f); - var b = m.slice(k - f); - m = "".concat(a, ".").concat(b); - int = a.length; - } else { - int = m.length; - } - var cut = maxFraction - minFraction; - while (cut > 0 && m[m.length - 1] === "0") { - m = m.slice(0, -1); - cut--; - } - if (m[m.length - 1] === ".") { - m = m.slice(0, -1); - } - return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; - } - exports.ToRawFixed = ToRawFixed; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToString.js - var require_FormatNumericToString = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToString.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.FormatNumericToString = void 0; - var _262_1 = require__(); - var ToRawPrecision_1 = require_ToRawPrecision(); - var utils_1 = require_utils(); - var ToRawFixed_1 = require_ToRawFixed(); - function FormatNumericToString(intlObject, x) { - var isNegative = x < 0 || (0, _262_1.SameValue)(x, -0); - if (isNegative) { - x = -x; - } - var result; - var rourndingType = intlObject.roundingType; - switch (rourndingType) { - case "significantDigits": - result = (0, ToRawPrecision_1.ToRawPrecision)(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits); - break; - case "fractionDigits": - result = (0, ToRawFixed_1.ToRawFixed)(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits); - break; - default: - result = (0, ToRawPrecision_1.ToRawPrecision)(x, 1, 2); - if (result.integerDigitsCount > 1) { - result = (0, ToRawFixed_1.ToRawFixed)(x, 0, 0); - } - break; - } - x = result.roundedNumber; - var string = result.formattedString; - var int = result.integerDigitsCount; - var minInteger = intlObject.minimumIntegerDigits; - if (int < minInteger) { - var forwardZeros = (0, utils_1.repeat)("0", minInteger - int); - string = forwardZeros + string; - } - if (isNegative) { - x = -x; - } - return { roundedNumber: x, formattedString: string }; - } - exports.FormatNumericToString = FormatNumericToString; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponent.js - var require_ComputeExponent = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponent.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ComputeExponent = void 0; - var utils_1 = require_utils(); - var ComputeExponentForMagnitude_1 = require_ComputeExponentForMagnitude(); - var FormatNumericToString_1 = require_FormatNumericToString(); - function ComputeExponent(numberFormat, x, _a) { - var getInternalSlots = _a.getInternalSlots; - if (x === 0) { - return [0, 0]; - } - if (x < 0) { - x = -x; - } - var magnitude = (0, utils_1.getMagnitude)(x); - var exponent = (0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(numberFormat, magnitude, { - getInternalSlots - }); - x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent); - var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(getInternalSlots(numberFormat), x); - if (formatNumberResult.roundedNumber === 0) { - return [exponent, magnitude]; - } - var newMagnitude = (0, utils_1.getMagnitude)(formatNumberResult.roundedNumber); - if (newMagnitude === magnitude - exponent) { - return [exponent, magnitude]; - } - return [ - (0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(numberFormat, magnitude + 1, { - getInternalSlots - }), - magnitude + 1 - ]; - } - exports.ComputeExponent = ComputeExponent; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CurrencyDigits.js - var require_CurrencyDigits = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CurrencyDigits.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CurrencyDigits = void 0; - var _262_1 = require__(); - function CurrencyDigits(c, _a) { - var currencyDigitsData = _a.currencyDigitsData; - return (0, _262_1.HasOwnProperty)(currencyDigitsData, c) ? currencyDigitsData[c] : 2; - } - exports.CurrencyDigits = CurrencyDigits; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatApproximately.js - var require_FormatApproximately = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatApproximately.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.FormatApproximately = void 0; - function FormatApproximately(numberFormat, result, _a) { - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]; - var approximatelySign = symbols.approximatelySign; - result.push({ type: "approximatelySign", value: approximatelySign }); - return result; - } - exports.FormatApproximately = FormatApproximately; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/digit-mapping.generated.js - var require_digit_mapping_generated = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/digit-mapping.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.digitMapping = void 0; - exports.digitMapping = { "adlm": ["\u{1E950}", "\u{1E951}", "\u{1E952}", "\u{1E953}", "\u{1E954}", "\u{1E955}", "\u{1E956}", "\u{1E957}", "\u{1E958}", "\u{1E959}"], "ahom": ["\u{11730}", "\u{11731}", "\u{11732}", "\u{11733}", "\u{11734}", "\u{11735}", "\u{11736}", "\u{11737}", "\u{11738}", "\u{11739}"], "arab": ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"], "arabext": ["\u06F0", "\u06F1", "\u06F2", "\u06F3", "\u06F4", "\u06F5", "\u06F6", "\u06F7", "\u06F8", "\u06F9"], "bali": ["\u1B50", "\u1B51", "\u1B52", "\u1B53", "\u1B54", "\u1B55", "\u1B56", "\u1B57", "\u1B58", "\u1B59"], "beng": ["\u09E6", "\u09E7", "\u09E8", "\u09E9", "\u09EA", "\u09EB", "\u09EC", "\u09ED", "\u09EE", "\u09EF"], "bhks": ["\u{11C50}", "\u{11C51}", "\u{11C52}", "\u{11C53}", "\u{11C54}", "\u{11C55}", "\u{11C56}", "\u{11C57}", "\u{11C58}", "\u{11C59}"], "brah": ["\u{11066}", "\u{11067}", "\u{11068}", "\u{11069}", "\u{1106A}", "\u{1106B}", "\u{1106C}", "\u{1106D}", "\u{1106E}", "\u{1106F}"], "cakm": ["\u{11136}", "\u{11137}", "\u{11138}", "\u{11139}", "\u{1113A}", "\u{1113B}", "\u{1113C}", "\u{1113D}", "\u{1113E}", "\u{1113F}"], "cham": ["\uAA50", "\uAA51", "\uAA52", "\uAA53", "\uAA54", "\uAA55", "\uAA56", "\uAA57", "\uAA58", "\uAA59"], "deva": ["\u0966", "\u0967", "\u0968", "\u0969", "\u096A", "\u096B", "\u096C", "\u096D", "\u096E", "\u096F"], "diak": ["\u{11950}", "\u{11951}", "\u{11952}", "\u{11953}", "\u{11954}", "\u{11955}", "\u{11956}", "\u{11957}", "\u{11958}", "\u{11959}"], "fullwide": ["\uFF10", "\uFF11", "\uFF12", "\uFF13", "\uFF14", "\uFF15", "\uFF16", "\uFF17", "\uFF18", "\uFF19"], "gong": ["\u{11DA0}", "\u{11DA1}", "\u{11DA2}", "\u{11DA3}", "\u{11DA4}", "\u{11DA5}", "\u{11DA6}", "\u{11DA7}", "\u{11DA8}", "\u{11DA9}"], "gonm": ["\u{11D50}", "\u{11D51}", "\u{11D52}", "\u{11D53}", "\u{11D54}", "\u{11D55}", "\u{11D56}", "\u{11D57}", "\u{11D58}", "\u{11D59}"], "gujr": ["\u0AE6", "\u0AE7", "\u0AE8", "\u0AE9", "\u0AEA", "\u0AEB", "\u0AEC", "\u0AED", "\u0AEE", "\u0AEF"], "guru": ["\u0A66", "\u0A67", "\u0A68", "\u0A69", "\u0A6A", "\u0A6B", "\u0A6C", "\u0A6D", "\u0A6E", "\u0A6F"], "hanidec": ["\u3007", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"], "hmng": ["\u{16B50}", "\u{16B51}", "\u{16B52}", "\u{16B53}", "\u{16B54}", "\u{16B55}", "\u{16B56}", "\u{16B57}", "\u{16B58}", "\u{16B59}"], "hmnp": ["\u{1E140}", "\u{1E141}", "\u{1E142}", "\u{1E143}", "\u{1E144}", "\u{1E145}", "\u{1E146}", "\u{1E147}", "\u{1E148}", "\u{1E149}"], "java": ["\uA9D0", "\uA9D1", "\uA9D2", "\uA9D3", "\uA9D4", "\uA9D5", "\uA9D6", "\uA9D7", "\uA9D8", "\uA9D9"], "kali": ["\uA900", "\uA901", "\uA902", "\uA903", "\uA904", "\uA905", "\uA906", "\uA907", "\uA908", "\uA909"], "khmr": ["\u17E0", "\u17E1", "\u17E2", "\u17E3", "\u17E4", "\u17E5", "\u17E6", "\u17E7", "\u17E8", "\u17E9"], "knda": ["\u0CE6", "\u0CE7", "\u0CE8", "\u0CE9", "\u0CEA", "\u0CEB", "\u0CEC", "\u0CED", "\u0CEE", "\u0CEF"], "lana": ["\u1A80", "\u1A81", "\u1A82", "\u1A83", "\u1A84", "\u1A85", "\u1A86", "\u1A87", "\u1A88", "\u1A89"], "lanatham": ["\u1A90", "\u1A91", "\u1A92", "\u1A93", "\u1A94", "\u1A95", "\u1A96", "\u1A97", "\u1A98", "\u1A99"], "laoo": ["\u0ED0", "\u0ED1", "\u0ED2", "\u0ED3", "\u0ED4", "\u0ED5", "\u0ED6", "\u0ED7", "\u0ED8", "\u0ED9"], "lepc": ["\u1A90", "\u1A91", "\u1A92", "\u1A93", "\u1A94", "\u1A95", "\u1A96", "\u1A97", "\u1A98", "\u1A99"], "limb": ["\u1946", "\u1947", "\u1948", "\u1949", "\u194A", "\u194B", "\u194C", "\u194D", "\u194E", "\u194F"], "mathbold": ["\u{1D7CE}", "\u{1D7CF}", "\u{1D7D0}", "\u{1D7D1}", "\u{1D7D2}", "\u{1D7D3}", "\u{1D7D4}", "\u{1D7D5}", "\u{1D7D6}", "\u{1D7D7}"], "mathdbl": ["\u{1D7D8}", "\u{1D7D9}", "\u{1D7DA}", "\u{1D7DB}", "\u{1D7DC}", "\u{1D7DD}", "\u{1D7DE}", "\u{1D7DF}", "\u{1D7E0}", "\u{1D7E1}"], "mathmono": ["\u{1D7F6}", "\u{1D7F7}", "\u{1D7F8}", "\u{1D7F9}", "\u{1D7FA}", "\u{1D7FB}", "\u{1D7FC}", "\u{1D7FD}", "\u{1D7FE}", "\u{1D7FF}"], "mathsanb": ["\u{1D7EC}", "\u{1D7ED}", "\u{1D7EE}", "\u{1D7EF}", "\u{1D7F0}", "\u{1D7F1}", "\u{1D7F2}", "\u{1D7F3}", "\u{1D7F4}", "\u{1D7F5}"], "mathsans": ["\u{1D7E2}", "\u{1D7E3}", "\u{1D7E4}", "\u{1D7E5}", "\u{1D7E6}", "\u{1D7E7}", "\u{1D7E8}", "\u{1D7E9}", "\u{1D7EA}", "\u{1D7EB}"], "mlym": ["\u0D66", "\u0D67", "\u0D68", "\u0D69", "\u0D6A", "\u0D6B", "\u0D6C", "\u0D6D", "\u0D6E", "\u0D6F"], "modi": ["\u{11650}", "\u{11651}", "\u{11652}", "\u{11653}", "\u{11654}", "\u{11655}", "\u{11656}", "\u{11657}", "\u{11658}", "\u{11659}"], "mong": ["\u1810", "\u1811", "\u1812", "\u1813", "\u1814", "\u1815", "\u1816", "\u1817", "\u1818", "\u1819"], "mroo": ["\u{16A60}", "\u{16A61}", "\u{16A62}", "\u{16A63}", "\u{16A64}", "\u{16A65}", "\u{16A66}", "\u{16A67}", "\u{16A68}", "\u{16A69}"], "mtei": ["\uABF0", "\uABF1", "\uABF2", "\uABF3", "\uABF4", "\uABF5", "\uABF6", "\uABF7", "\uABF8", "\uABF9"], "mymr": ["\u1040", "\u1041", "\u1042", "\u1043", "\u1044", "\u1045", "\u1046", "\u1047", "\u1048", "\u1049"], "mymrshan": ["\u1090", "\u1091", "\u1092", "\u1093", "\u1094", "\u1095", "\u1096", "\u1097", "\u1098", "\u1099"], "mymrtlng": ["\uA9F0", "\uA9F1", "\uA9F2", "\uA9F3", "\uA9F4", "\uA9F5", "\uA9F6", "\uA9F7", "\uA9F8", "\uA9F9"], "newa": ["\u{11450}", "\u{11451}", "\u{11452}", "\u{11453}", "\u{11454}", "\u{11455}", "\u{11456}", "\u{11457}", "\u{11458}", "\u{11459}"], "nkoo": ["\u07C0", "\u07C1", "\u07C2", "\u07C3", "\u07C4", "\u07C5", "\u07C6", "\u07C7", "\u07C8", "\u07C9"], "olck": ["\u1C50", "\u1C51", "\u1C52", "\u1C53", "\u1C54", "\u1C55", "\u1C56", "\u1C57", "\u1C58", "\u1C59"], "orya": ["\u0B66", "\u0B67", "\u0B68", "\u0B69", "\u0B6A", "\u0B6B", "\u0B6C", "\u0B6D", "\u0B6E", "\u0B6F"], "osma": ["\u{104A0}", "\u{104A1}", "\u{104A2}", "\u{104A3}", "\u{104A4}", "\u{104A5}", "\u{104A6}", "\u{104A7}", "\u{104A8}", "\u{104A9}"], "rohg": ["\u{10D30}", "\u{10D31}", "\u{10D32}", "\u{10D33}", "\u{10D34}", "\u{10D35}", "\u{10D36}", "\u{10D37}", "\u{10D38}", "\u{10D39}"], "saur": ["\uA8D0", "\uA8D1", "\uA8D2", "\uA8D3", "\uA8D4", "\uA8D5", "\uA8D6", "\uA8D7", "\uA8D8", "\uA8D9"], "segment": ["\u{1FBF0}", "\u{1FBF1}", "\u{1FBF2}", "\u{1FBF3}", "\u{1FBF4}", "\u{1FBF5}", "\u{1FBF6}", "\u{1FBF7}", "\u{1FBF8}", "\u{1FBF9}"], "shrd": ["\u{111D0}", "\u{111D1}", "\u{111D2}", "\u{111D3}", "\u{111D4}", "\u{111D5}", "\u{111D6}", "\u{111D7}", "\u{111D8}", "\u{111D9}"], "sind": ["\u{112F0}", "\u{112F1}", "\u{112F2}", "\u{112F3}", "\u{112F4}", "\u{112F5}", "\u{112F6}", "\u{112F7}", "\u{112F8}", "\u{112F9}"], "sinh": ["\u0DE6", "\u0DE7", "\u0DE8", "\u0DE9", "\u0DEA", "\u0DEB", "\u0DEC", "\u0DED", "\u0DEE", "\u0DEF"], "sora": ["\u{110F0}", "\u{110F1}", "\u{110F2}", "\u{110F3}", "\u{110F4}", "\u{110F5}", "\u{110F6}", "\u{110F7}", "\u{110F8}", "\u{110F9}"], "sund": ["\u1BB0", "\u1BB1", "\u1BB2", "\u1BB3", "\u1BB4", "\u1BB5", "\u1BB6", "\u1BB7", "\u1BB8", "\u1BB9"], "takr": ["\u{116C0}", "\u{116C1}", "\u{116C2}", "\u{116C3}", "\u{116C4}", "\u{116C5}", "\u{116C6}", "\u{116C7}", "\u{116C8}", "\u{116C9}"], "talu": ["\u19D0", "\u19D1", "\u19D2", "\u19D3", "\u19D4", "\u19D5", "\u19D6", "\u19D7", "\u19D8", "\u19D9"], "tamldec": ["\u0BE6", "\u0BE7", "\u0BE8", "\u0BE9", "\u0BEA", "\u0BEB", "\u0BEC", "\u0BED", "\u0BEE", "\u0BEF"], "telu": ["\u0C66", "\u0C67", "\u0C68", "\u0C69", "\u0C6A", "\u0C6B", "\u0C6C", "\u0C6D", "\u0C6E", "\u0C6F"], "thai": ["\u0E50", "\u0E51", "\u0E52", "\u0E53", "\u0E54", "\u0E55", "\u0E56", "\u0E57", "\u0E58", "\u0E59"], "tibt": ["\u0F20", "\u0F21", "\u0F22", "\u0F23", "\u0F24", "\u0F25", "\u0F26", "\u0F27", "\u0F28", "\u0F29"], "tirh": ["\u{114D0}", "\u{114D1}", "\u{114D2}", "\u{114D3}", "\u{114D4}", "\u{114D5}", "\u{114D6}", "\u{114D7}", "\u{114D8}", "\u{114D9}"], "vaii": ["\u1620", "\u1621", "\u1622", "\u1623", "\u1624", "\u1625", "\u1626", "\u1627", "\u1628", "\u1629"], "wara": ["\u{118E0}", "\u{118E1}", "\u{118E2}", "\u{118E3}", "\u{118E4}", "\u{118E5}", "\u{118E6}", "\u{118E7}", "\u{118E8}", "\u{118E9}"], "wcho": ["\u{1E2F0}", "\u{1E2F1}", "\u{1E2F2}", "\u{1E2F3}", "\u{1E2F4}", "\u{1E2F5}", "\u{1E2F6}", "\u{1E2F7}", "\u{1E2F8}", "\u{1E2F9}"] }; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/regex.generated.js - var require_regex_generated = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/regex.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.S_UNICODE_REGEX = void 0; - exports.S_UNICODE_REGEX = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20BF\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC1\uFDFC\uFDFD\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEE0-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDD78\uDD7A-\uDDCB\uDDCD-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6\uDF00-\uDF92\uDF94-\uDFCA]/; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/format_to_parts.js - var require_format_to_parts = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/format_to_parts.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var ToRawFixed_1 = require_ToRawFixed(); - var digit_mapping_generated_1 = require_digit_mapping_generated(); - var regex_generated_1 = require_regex_generated(); - var CARET_S_UNICODE_REGEX = new RegExp("^".concat(regex_generated_1.S_UNICODE_REGEX.source)); - var S_DOLLAR_UNICODE_REGEX = new RegExp("".concat(regex_generated_1.S_UNICODE_REGEX.source, "$")); - var CLDR_NUMBER_PATTERN = /[#0](?:[\.,][#0]+)*/g; - function formatToParts(numberResult, data, pl, options) { - var sign = numberResult.sign, exponent = numberResult.exponent, magnitude = numberResult.magnitude; - var notation = options.notation, style = options.style, numberingSystem = options.numberingSystem; - var defaultNumberingSystem = data.numbers.nu[0]; - var compactNumberPattern = null; - if (notation === "compact" && magnitude) { - compactNumberPattern = getCompactDisplayPattern(numberResult, pl, data, style, options.compactDisplay, options.currencyDisplay, numberingSystem); - } - var nonNameCurrencyPart; - if (style === "currency" && options.currencyDisplay !== "name") { - var byCurrencyDisplay = data.currencies[options.currency]; - if (byCurrencyDisplay) { - switch (options.currencyDisplay) { - case "code": - nonNameCurrencyPart = options.currency; - break; - case "symbol": - nonNameCurrencyPart = byCurrencyDisplay.symbol; - break; - default: - nonNameCurrencyPart = byCurrencyDisplay.narrow; - break; - } - } else { - nonNameCurrencyPart = options.currency; - } - } - var numberPattern; - if (!compactNumberPattern) { - if (style === "decimal" || style === "unit" || style === "currency" && options.currencyDisplay === "name") { - var decimalData = data.numbers.decimal[numberingSystem] || data.numbers.decimal[defaultNumberingSystem]; - numberPattern = getPatternForSign(decimalData.standard, sign); - } else if (style === "currency") { - var currencyData = data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]; - numberPattern = getPatternForSign(currencyData[options.currencySign], sign); - } else { - var percentPattern = data.numbers.percent[numberingSystem] || data.numbers.percent[defaultNumberingSystem]; - numberPattern = getPatternForSign(percentPattern, sign); - } - } else { - numberPattern = compactNumberPattern; - } - var decimalNumberPattern = CLDR_NUMBER_PATTERN.exec(numberPattern)[0]; - numberPattern = numberPattern.replace(CLDR_NUMBER_PATTERN, "{0}").replace(/'(.)'/g, "$1"); - if (style === "currency" && options.currencyDisplay !== "name") { - var currencyData = data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]; - var afterCurrency = currencyData.currencySpacing.afterInsertBetween; - if (afterCurrency && !S_DOLLAR_UNICODE_REGEX.test(nonNameCurrencyPart)) { - numberPattern = numberPattern.replace("\xA4{0}", "\xA4".concat(afterCurrency, "{0}")); - } - var beforeCurrency = currencyData.currencySpacing.beforeInsertBetween; - if (beforeCurrency && !CARET_S_UNICODE_REGEX.test(nonNameCurrencyPart)) { - numberPattern = numberPattern.replace("{0}\xA4", "{0}".concat(beforeCurrency, "\xA4")); - } - } - var numberPatternParts = numberPattern.split(/({c:[^}]+}|\{0\}|[¤%\-\+])/g); - var numberParts = []; - var symbols = data.numbers.symbols[numberingSystem] || data.numbers.symbols[defaultNumberingSystem]; - for (var _i = 0, numberPatternParts_1 = numberPatternParts; _i < numberPatternParts_1.length; _i++) { - var part = numberPatternParts_1[_i]; - if (!part) { - continue; - } - switch (part) { - case "{0}": { - numberParts.push.apply(numberParts, paritionNumberIntoParts( - symbols, - numberResult, - notation, - exponent, - numberingSystem, - // If compact number pattern exists, do not insert group separators. - !compactNumberPattern && Boolean(options.useGrouping), - decimalNumberPattern - )); - break; - } - case "-": - numberParts.push({ type: "minusSign", value: symbols.minusSign }); - break; - case "+": - numberParts.push({ type: "plusSign", value: symbols.plusSign }); - break; - case "%": - numberParts.push({ type: "percentSign", value: symbols.percentSign }); - break; - case "\xA4": - numberParts.push({ type: "currency", value: nonNameCurrencyPart }); - break; - default: - if (/^\{c:/.test(part)) { - numberParts.push({ - type: "compact", - value: part.substring(3, part.length - 1) - }); - } else { - numberParts.push({ type: "literal", value: part }); - } - break; - } - } - switch (style) { - case "currency": { - if (options.currencyDisplay === "name") { - var unitPattern = (data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]).unitPattern; - var unitName = void 0; - var currencyNameData = data.currencies[options.currency]; - if (currencyNameData) { - unitName = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), currencyNameData.displayName); - } else { - unitName = options.currency; - } - var unitPatternParts = unitPattern.split(/(\{[01]\})/g); - var result = []; - for (var _a = 0, unitPatternParts_1 = unitPatternParts; _a < unitPatternParts_1.length; _a++) { - var part = unitPatternParts_1[_a]; - switch (part) { - case "{0}": - result.push.apply(result, numberParts); - break; - case "{1}": - result.push({ type: "currency", value: unitName }); - break; - default: - if (part) { - result.push({ type: "literal", value: part }); - } - break; - } - } - return result; - } else { - return numberParts; - } - } - case "unit": { - var unit = options.unit, unitDisplay = options.unitDisplay; - var unitData = data.units.simple[unit]; - var unitPattern = void 0; - if (unitData) { - unitPattern = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), data.units.simple[unit][unitDisplay]); - } else { - var _b = unit.split("-per-"), numeratorUnit = _b[0], denominatorUnit = _b[1]; - unitData = data.units.simple[numeratorUnit]; - var numeratorUnitPattern = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), data.units.simple[numeratorUnit][unitDisplay]); - var perUnitPattern = data.units.simple[denominatorUnit].perUnit[unitDisplay]; - if (perUnitPattern) { - unitPattern = perUnitPattern.replace("{0}", numeratorUnitPattern); - } else { - var perPattern = data.units.compound.per[unitDisplay]; - var denominatorPattern = selectPlural(pl, 1, data.units.simple[denominatorUnit][unitDisplay]); - unitPattern = unitPattern = perPattern.replace("{0}", numeratorUnitPattern).replace("{1}", denominatorPattern.replace("{0}", "")); - } - } - var result = []; - for (var _c = 0, _d = unitPattern.split(/(\s*\{0\}\s*)/); _c < _d.length; _c++) { - var part = _d[_c]; - var interpolateMatch = /^(\s*)\{0\}(\s*)$/.exec(part); - if (interpolateMatch) { - if (interpolateMatch[1]) { - result.push({ type: "literal", value: interpolateMatch[1] }); - } - result.push.apply(result, numberParts); - if (interpolateMatch[2]) { - result.push({ type: "literal", value: interpolateMatch[2] }); - } - } else if (part) { - result.push({ type: "unit", value: part }); - } - } - return result; - } - default: - return numberParts; - } - } - exports.default = formatToParts; - function paritionNumberIntoParts(symbols, numberResult, notation, exponent, numberingSystem, useGrouping, decimalNumberPattern) { - var result = []; - var n = numberResult.formattedString, x = numberResult.roundedNumber; - if (isNaN(x)) { - return [{ type: "nan", value: n }]; - } else if (!isFinite(x)) { - return [{ type: "infinity", value: n }]; - } - var digitReplacementTable = digit_mapping_generated_1.digitMapping[numberingSystem]; - if (digitReplacementTable) { - n = n.replace(/\d/g, function(digit) { - return digitReplacementTable[+digit] || digit; - }); - } - var decimalSepIndex = n.indexOf("."); - var integer; - var fraction; - if (decimalSepIndex > 0) { - integer = n.slice(0, decimalSepIndex); - fraction = n.slice(decimalSepIndex + 1); - } else { - integer = n; - } - if (useGrouping && (notation !== "compact" || x >= 1e4)) { - var groupSepSymbol = symbols.group; - var groups = []; - var integerNumberPattern = decimalNumberPattern.split(".")[0]; - var patternGroups = integerNumberPattern.split(","); - var primaryGroupingSize = 3; - var secondaryGroupingSize = 3; - if (patternGroups.length > 1) { - primaryGroupingSize = patternGroups[patternGroups.length - 1].length; - } - if (patternGroups.length > 2) { - secondaryGroupingSize = patternGroups[patternGroups.length - 2].length; - } - var i = integer.length - primaryGroupingSize; - if (i > 0) { - groups.push(integer.slice(i, i + primaryGroupingSize)); - for (i -= secondaryGroupingSize; i > 0; i -= secondaryGroupingSize) { - groups.push(integer.slice(i, i + secondaryGroupingSize)); - } - groups.push(integer.slice(0, i + secondaryGroupingSize)); - } else { - groups.push(integer); - } - while (groups.length > 0) { - var integerGroup = groups.pop(); - result.push({ type: "integer", value: integerGroup }); - if (groups.length > 0) { - result.push({ type: "group", value: groupSepSymbol }); - } - } - } else { - result.push({ type: "integer", value: integer }); - } - if (fraction !== void 0) { - result.push({ type: "decimal", value: symbols.decimal }, { type: "fraction", value: fraction }); - } - if ((notation === "scientific" || notation === "engineering") && isFinite(x)) { - result.push({ type: "exponentSeparator", value: symbols.exponential }); - if (exponent < 0) { - result.push({ type: "exponentMinusSign", value: symbols.minusSign }); - exponent = -exponent; - } - var exponentResult = (0, ToRawFixed_1.ToRawFixed)(exponent, 0, 0); - result.push({ - type: "exponentInteger", - value: exponentResult.formattedString - }); - } - return result; - } - function getPatternForSign(pattern, sign) { - if (pattern.indexOf(";") < 0) { - pattern = "".concat(pattern, ";-").concat(pattern); - } - var _a = pattern.split(";"), zeroPattern = _a[0], negativePattern = _a[1]; - switch (sign) { - case 0: - return zeroPattern; - case -1: - return negativePattern; - default: - return negativePattern.indexOf("-") >= 0 ? negativePattern.replace(/-/g, "+") : "+".concat(zeroPattern); - } - } - function getCompactDisplayPattern(numberResult, pl, data, style, compactDisplay, currencyDisplay, numberingSystem) { - var _a; - var roundedNumber = numberResult.roundedNumber, sign = numberResult.sign, magnitude = numberResult.magnitude; - var magnitudeKey = String(Math.pow(10, magnitude)); - var defaultNumberingSystem = data.numbers.nu[0]; - var pattern; - if (style === "currency" && currencyDisplay !== "name") { - var byNumberingSystem = data.numbers.currency; - var currencyData = byNumberingSystem[numberingSystem] || byNumberingSystem[defaultNumberingSystem]; - var compactPluralRules = (_a = currencyData.short) === null || _a === void 0 ? void 0 : _a[magnitudeKey]; - if (!compactPluralRules) { - return null; - } - pattern = selectPlural(pl, roundedNumber, compactPluralRules); - } else { - var byNumberingSystem = data.numbers.decimal; - var byCompactDisplay = byNumberingSystem[numberingSystem] || byNumberingSystem[defaultNumberingSystem]; - var compactPlaralRule = byCompactDisplay[compactDisplay][magnitudeKey]; - if (!compactPlaralRule) { - return null; - } - pattern = selectPlural(pl, roundedNumber, compactPlaralRule); - } - if (pattern === "0") { - return null; - } - pattern = getPatternForSign(pattern, sign).replace(/([^\s;\-\+\d¤]+)/g, "{c:$1}").replace(/0+/, "0"); - return pattern; - } - function selectPlural(pl, x, rules) { - return rules[pl.select(x)] || rules.other; - } - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberPattern.js - var require_PartitionNumberPattern = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberPattern.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.PartitionNumberPattern = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var FormatNumericToString_1 = require_FormatNumericToString(); - var _262_1 = require__(); - var ComputeExponent_1 = require_ComputeExponent(); - var format_to_parts_1 = tslib_1.__importDefault(require_format_to_parts()); - function PartitionNumberPattern(numberFormat, x, _a) { - var _b; - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - var pl = internalSlots.pl, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem; - var symbols = dataLocaleData.numbers.symbols[numberingSystem] || dataLocaleData.numbers.symbols[dataLocaleData.numbers.nu[0]]; - var magnitude = 0; - var exponent = 0; - var n; - if (isNaN(x)) { - n = symbols.nan; - } else if (x == Number.POSITIVE_INFINITY || x == Number.NEGATIVE_INFINITY) { - n = symbols.infinity; - } else { - if (!(0, _262_1.SameValue)(x, -0)) { - if (!isFinite(x)) { - throw new Error("Input must be a mathematical value"); - } - if (internalSlots.style == "percent") { - x *= 100; - } - ; - _b = (0, ComputeExponent_1.ComputeExponent)(numberFormat, x, { - getInternalSlots - }), exponent = _b[0], magnitude = _b[1]; - x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent); - } - var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(internalSlots, x); - n = formatNumberResult.formattedString; - x = formatNumberResult.roundedNumber; - } - var sign; - var signDisplay = internalSlots.signDisplay; - switch (signDisplay) { - case "never": - sign = 0; - break; - case "auto": - if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) { - sign = 0; - } else { - sign = -1; - } - break; - case "always": - if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) { - sign = 1; - } else { - sign = -1; - } - break; - default: - if (x === 0 || isNaN(x)) { - sign = 0; - } else if (x > 0) { - sign = 1; - } else { - sign = -1; - } - } - return (0, format_to_parts_1.default)({ roundedNumber: x, formattedString: n, exponent, magnitude, sign }, internalSlots.dataLocaleData, pl, internalSlots); - } - exports.PartitionNumberPattern = PartitionNumberPattern; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToParts.js - var require_FormatNumericToParts = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToParts.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.FormatNumericToParts = void 0; - var PartitionNumberPattern_1 = require_PartitionNumberPattern(); - var _262_1 = require__(); - function FormatNumericToParts(nf, x, implDetails) { - var parts = (0, PartitionNumberPattern_1.PartitionNumberPattern)(nf, x, implDetails); - var result = (0, _262_1.ArrayCreate)(0); - for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { - var part = parts_1[_i]; - result.push({ - type: part.type, - value: part.value - }); - } - return result; - } - exports.FormatNumericToParts = FormatNumericToParts; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/GetUnsignedRoundingMode.js - var require_GetUnsignedRoundingMode = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/GetUnsignedRoundingMode.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetUnsignedRoundingMode = void 0; - var negativeMapping = { - ceil: "zero", - floor: "infinity", - expand: "infinity", - trunc: "zero", - halfCeil: "half-zero", - halfFloor: "half-infinity", - halfExpand: "half-infinity", - halfTrunc: "half-zero", - halfEven: "half-even" - }; - var positiveMapping = { - ceil: "infinity", - floor: "zero", - expand: "infinity", - trunc: "zero", - halfCeil: "half-infinity", - halfFloor: "half-zero", - halfExpand: "half-infinity", - halfTrunc: "half-zero", - halfEven: "half-even" - }; - function GetUnsignedRoundingMode(roundingMode, isNegative) { - if (isNegative) { - return negativeMapping[roundingMode]; - } - return positiveMapping[roundingMode]; - } - exports.GetUnsignedRoundingMode = GetUnsignedRoundingMode; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/CanonicalizeLocaleList.js - var require_CanonicalizeLocaleList2 = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/CanonicalizeLocaleList.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CanonicalizeLocaleList = void 0; - function CanonicalizeLocaleList(locales) { - return Intl.getCanonicalLocales(locales); - } - exports.CanonicalizeLocaleList = CanonicalizeLocaleList; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/utils.js - var require_utils2 = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = void 0; - exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; - function invariant(condition, message, Err) { - if (Err === void 0) { - Err = Error; - } - if (!condition) { - throw new Err(message); - } - } - exports.invariant = invariant; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestAvailableLocale.js - var require_BestAvailableLocale = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestAvailableLocale.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.BestAvailableLocale = void 0; - function BestAvailableLocale(availableLocales, locale) { - var candidate = locale; - while (true) { - if (availableLocales.has(candidate)) { - return candidate; - } - var pos = candidate.lastIndexOf("-"); - if (!~pos) { - return void 0; - } - if (pos >= 2 && candidate[pos - 2] === "-") { - pos -= 2; - } - candidate = candidate.slice(0, pos); - } - } - exports.BestAvailableLocale = BestAvailableLocale; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupMatcher.js - var require_LookupMatcher = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupMatcher.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.LookupMatcher = void 0; - var utils_1 = require_utils2(); - var BestAvailableLocale_1 = require_BestAvailableLocale(); - function LookupMatcher(availableLocales, requestedLocales, getDefaultLocale) { - var result = { locale: "" }; - for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { - var locale = requestedLocales_1[_i]; - var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); - var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); - if (availableLocale) { - result.locale = availableLocale; - if (locale !== noExtensionLocale) { - result.extension = locale.slice(noExtensionLocale.length + 1, locale.length); - } - return result; - } - } - result.locale = getDefaultLocale(); - return result; - } - exports.LookupMatcher = LookupMatcher; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestFitMatcher.js - var require_BestFitMatcher = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestFitMatcher.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.BestFitMatcher = void 0; - var BestAvailableLocale_1 = require_BestAvailableLocale(); - var utils_1 = require_utils2(); - function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) { - var minimizedAvailableLocaleMap = {}; - var availableLocaleMap = {}; - var canonicalizedLocaleMap = {}; - var minimizedAvailableLocales = /* @__PURE__ */ new Set(); - availableLocales.forEach(function(locale2) { - var minimizedLocale = new Intl.Locale(locale2).minimize().toString(); - var canonicalizedLocale = Intl.getCanonicalLocales(locale2)[0] || locale2; - minimizedAvailableLocaleMap[minimizedLocale] = locale2; - availableLocaleMap[locale2] = locale2; - canonicalizedLocaleMap[canonicalizedLocale] = locale2; - minimizedAvailableLocales.add(minimizedLocale); - minimizedAvailableLocales.add(locale2); - minimizedAvailableLocales.add(canonicalizedLocale); - }); - var foundLocale; - for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { - var l = requestedLocales_1[_i]; - if (foundLocale) { - break; - } - var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); - if (availableLocales.has(noExtensionLocale)) { - foundLocale = noExtensionLocale; - break; - } - if (minimizedAvailableLocales.has(noExtensionLocale)) { - foundLocale = noExtensionLocale; - break; - } - var locale = new Intl.Locale(noExtensionLocale); - var maximizedRequestedLocale = locale.maximize().toString(); - var minimizedRequestedLocale = locale.minimize().toString(); - if (minimizedAvailableLocales.has(minimizedRequestedLocale)) { - foundLocale = minimizedRequestedLocale; - break; - } - foundLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(minimizedAvailableLocales, maximizedRequestedLocale); - } - if (!foundLocale) { - return { locale: getDefaultLocale() }; - } - return { - locale: availableLocaleMap[foundLocale] || canonicalizedLocaleMap[foundLocale] || minimizedAvailableLocaleMap[foundLocale] || foundLocale - }; - } - exports.BestFitMatcher = BestFitMatcher; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/UnicodeExtensionValue.js - var require_UnicodeExtensionValue = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/UnicodeExtensionValue.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.UnicodeExtensionValue = void 0; - var utils_1 = require_utils2(); - function UnicodeExtensionValue(extension, key) { - (0, utils_1.invariant)(key.length === 2, "key must have 2 elements"); - var size = extension.length; - var searchValue = "-".concat(key, "-"); - var pos = extension.indexOf(searchValue); - if (pos !== -1) { - var start = pos + 4; - var end = start; - var k = start; - var done = false; - while (!done) { - var e = extension.indexOf("-", k); - var len = void 0; - if (e === -1) { - len = size - k; - } else { - len = e - k; - } - if (len === 2) { - done = true; - } else if (e === -1) { - end = size; - done = true; - } else { - end = e; - k = e + 1; - } - } - return extension.slice(start, end); - } - searchValue = "-".concat(key); - pos = extension.indexOf(searchValue); - if (pos !== -1 && pos + 3 === size) { - return ""; - } - return void 0; - } - exports.UnicodeExtensionValue = UnicodeExtensionValue; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/ResolveLocale.js - var require_ResolveLocale = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/ResolveLocale.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ResolveLocale = void 0; - var LookupMatcher_1 = require_LookupMatcher(); - var BestFitMatcher_1 = require_BestFitMatcher(); - var utils_1 = require_utils2(); - var UnicodeExtensionValue_1 = require_UnicodeExtensionValue(); - function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) { - var matcher = options.localeMatcher; - var r; - if (matcher === "lookup") { - r = (0, LookupMatcher_1.LookupMatcher)(availableLocales, requestedLocales, getDefaultLocale); - } else { - r = (0, BestFitMatcher_1.BestFitMatcher)(availableLocales, requestedLocales, getDefaultLocale); - } - var foundLocale = r.locale; - var result = { locale: "", dataLocale: foundLocale }; - var supportedExtension = "-u"; - for (var _i = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _i < relevantExtensionKeys_1.length; _i++) { - var key = relevantExtensionKeys_1[_i]; - (0, utils_1.invariant)(foundLocale in localeData, "Missing locale data for ".concat(foundLocale)); - var foundLocaleData = localeData[foundLocale]; - (0, utils_1.invariant)(typeof foundLocaleData === "object" && foundLocaleData !== null, "locale data ".concat(key, " must be an object")); - var keyLocaleData = foundLocaleData[key]; - (0, utils_1.invariant)(Array.isArray(keyLocaleData), "keyLocaleData for ".concat(key, " must be an array")); - var value = keyLocaleData[0]; - (0, utils_1.invariant)(typeof value === "string" || value === null, "value must be string or null but got ".concat(typeof value, " in key ").concat(key)); - var supportedExtensionAddition = ""; - if (r.extension) { - var requestedValue = (0, UnicodeExtensionValue_1.UnicodeExtensionValue)(r.extension, key); - if (requestedValue !== void 0) { - if (requestedValue !== "") { - if (~keyLocaleData.indexOf(requestedValue)) { - value = requestedValue; - supportedExtensionAddition = "-".concat(key, "-").concat(value); - } - } else if (~requestedValue.indexOf("true")) { - value = "true"; - supportedExtensionAddition = "-".concat(key); - } - } - } - if (key in options) { - var optionsValue = options[key]; - (0, utils_1.invariant)(typeof optionsValue === "string" || typeof optionsValue === "undefined" || optionsValue === null, "optionsValue must be String, Undefined or Null"); - if (~keyLocaleData.indexOf(optionsValue)) { - if (optionsValue !== value) { - value = optionsValue; - supportedExtensionAddition = ""; - } - } - } - result[key] = value; - supportedExtension += supportedExtensionAddition; - } - if (supportedExtension.length > 2) { - var privateIndex = foundLocale.indexOf("-x-"); - if (privateIndex === -1) { - foundLocale = foundLocale + supportedExtension; - } else { - var preExtension = foundLocale.slice(0, privateIndex); - var postExtension = foundLocale.slice(privateIndex, foundLocale.length); - foundLocale = preExtension + supportedExtension + postExtension; - } - foundLocale = Intl.getCanonicalLocales(foundLocale)[0]; - } - result.locale = foundLocale; - return result; - } - exports.ResolveLocale = ResolveLocale; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupSupportedLocales.js - var require_LookupSupportedLocales = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupSupportedLocales.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.LookupSupportedLocales = void 0; - var utils_1 = require_utils2(); - var BestAvailableLocale_1 = require_BestAvailableLocale(); - function LookupSupportedLocales(availableLocales, requestedLocales) { - var subset = []; - for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { - var locale = requestedLocales_1[_i]; - var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); - var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); - if (availableLocale) { - subset.push(availableLocale); - } - } - return subset; - } - exports.LookupSupportedLocales = LookupSupportedLocales; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/index.js - var require_intl_localematcher = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ResolveLocale = exports.LookupSupportedLocales = exports.match = void 0; - var CanonicalizeLocaleList_1 = require_CanonicalizeLocaleList2(); - var ResolveLocale_1 = require_ResolveLocale(); - function match(requestedLocales, availableLocales, defaultLocale, opts) { - var locales = availableLocales.reduce(function(all, l) { - all.add(l); - return all; - }, /* @__PURE__ */ new Set()); - return (0, ResolveLocale_1.ResolveLocale)(locales, (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(requestedLocales), { - localeMatcher: (opts === null || opts === void 0 ? void 0 : opts.algorithm) || "best fit" - }, [], {}, function() { - return defaultLocale; - }).locale; - } - exports.match = match; - var LookupSupportedLocales_1 = require_LookupSupportedLocales(); - Object.defineProperty(exports, "LookupSupportedLocales", { enumerable: true, get: function() { - return LookupSupportedLocales_1.LookupSupportedLocales; - } }); - var ResolveLocale_2 = require_ResolveLocale(); - Object.defineProperty(exports, "ResolveLocale", { enumerable: true, get: function() { - return ResolveLocale_2.ResolveLocale; - } }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatUnitOptions.js - var require_SetNumberFormatUnitOptions = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatUnitOptions.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.SetNumberFormatUnitOptions = void 0; - var GetOption_1 = require_GetOption(); - var IsWellFormedCurrencyCode_1 = require_IsWellFormedCurrencyCode(); - var IsWellFormedUnitIdentifier_1 = require_IsWellFormedUnitIdentifier(); - function SetNumberFormatUnitOptions(nf, options, _a) { - if (options === void 0) { - options = /* @__PURE__ */ Object.create(null); - } - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(nf); - var style = (0, GetOption_1.GetOption)(options, "style", "string", ["decimal", "percent", "currency", "unit"], "decimal"); - internalSlots.style = style; - var currency = (0, GetOption_1.GetOption)(options, "currency", "string", void 0, void 0); - if (currency !== void 0 && !(0, IsWellFormedCurrencyCode_1.IsWellFormedCurrencyCode)(currency)) { - throw RangeError("Malformed currency code"); - } - if (style === "currency" && currency === void 0) { - throw TypeError("currency cannot be undefined"); - } - var currencyDisplay = (0, GetOption_1.GetOption)(options, "currencyDisplay", "string", ["code", "symbol", "narrowSymbol", "name"], "symbol"); - var currencySign = (0, GetOption_1.GetOption)(options, "currencySign", "string", ["standard", "accounting"], "standard"); - var unit = (0, GetOption_1.GetOption)(options, "unit", "string", void 0, void 0); - if (unit !== void 0 && !(0, IsWellFormedUnitIdentifier_1.IsWellFormedUnitIdentifier)(unit)) { - throw RangeError("Invalid unit argument for Intl.NumberFormat()"); - } - if (style === "unit" && unit === void 0) { - throw TypeError("unit cannot be undefined"); - } - var unitDisplay = (0, GetOption_1.GetOption)(options, "unitDisplay", "string", ["short", "narrow", "long"], "short"); - if (style === "currency") { - internalSlots.currency = currency.toUpperCase(); - internalSlots.currencyDisplay = currencyDisplay; - internalSlots.currencySign = currencySign; - } - if (style === "unit") { - internalSlots.unit = unit; - internalSlots.unitDisplay = unitDisplay; - } - } - exports.SetNumberFormatUnitOptions = SetNumberFormatUnitOptions; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatDigitOptions.js - var require_SetNumberFormatDigitOptions = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatDigitOptions.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.SetNumberFormatDigitOptions = void 0; - var GetNumberOption_1 = require_GetNumberOption(); - var DefaultNumberOption_1 = require_DefaultNumberOption(); - var GetOption_1 = require_GetOption(); - function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefault, notation) { - var mnid = (0, GetNumberOption_1.GetNumberOption)(opts, "minimumIntegerDigits", 1, 21, 1); - var mnfd = opts.minimumFractionDigits; - var mxfd = opts.maximumFractionDigits; - var mnsd = opts.minimumSignificantDigits; - var mxsd = opts.maximumSignificantDigits; - internalSlots.minimumIntegerDigits = mnid; - var roundingPriority = (0, GetOption_1.GetOption)(opts, "roundingPriority", "string", ["auto", "morePrecision", "lessPrecision"], "auto"); - var hasSd = mnsd !== void 0 || mxsd !== void 0; - var hasFd = mnfd !== void 0 || mxfd !== void 0; - var needSd = true; - var needFd = true; - if (roundingPriority === "auto") { - needSd = hasSd; - if (hasSd || !hasFd && notation === "compact") { - needFd = false; - } - } - if (needSd) { - if (hasSd) { - mnsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnsd, 1, 21, 1); - mxsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxsd, mnsd, 21, 21); - internalSlots.minimumSignificantDigits = mnsd; - internalSlots.maximumSignificantDigits = mxsd; - } else { - internalSlots.minimumSignificantDigits = 1; - internalSlots.maximumSignificantDigits = 21; - } - } - if (needFd) { - if (hasFd) { - mnfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnfd, 0, 20, void 0); - mxfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxfd, 0, 20, void 0); - if (mnfd === void 0) { - mnfd = Math.min(mnfdDefault, mxfd); - } else if (mxfd === void 0) { - mxfd = Math.max(mxfdDefault, mnfd); - } else if (mnfd > mxfd) { - throw new RangeError("Invalid range, ".concat(mnfd, " > ").concat(mxfd)); - } - internalSlots.minimumFractionDigits = mnfd; - internalSlots.maximumFractionDigits = mxfd; - } else { - internalSlots.minimumFractionDigits = mnfdDefault; - internalSlots.maximumFractionDigits = mxfdDefault; - } - } - if (needSd || needFd) { - if (roundingPriority === "morePrecision") { - internalSlots.roundingType = "morePrecision"; - } else if (roundingPriority === "lessPrecision") { - internalSlots.roundingType = "lessPrecision"; - } else if (hasSd) { - internalSlots.roundingType = "significantDigits"; - } else { - internalSlots.roundingType = "fractionDigits"; - } - } else { - internalSlots.roundingType = "morePrecision"; - internalSlots.minimumFractionDigits = 0; - internalSlots.maximumFractionDigits = 0; - internalSlots.minimumSignificantDigits = 1; - internalSlots.maximumSignificantDigits = 2; - } - } - exports.SetNumberFormatDigitOptions = SetNumberFormatDigitOptions; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/InitializeNumberFormat.js - var require_InitializeNumberFormat = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/InitializeNumberFormat.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.InitializeNumberFormat = void 0; - var CanonicalizeLocaleList_1 = require_CanonicalizeLocaleList(); - var GetOption_1 = require_GetOption(); - var intl_localematcher_1 = require_intl_localematcher(); - var SetNumberFormatUnitOptions_1 = require_SetNumberFormatUnitOptions(); - var CurrencyDigits_1 = require_CurrencyDigits(); - var SetNumberFormatDigitOptions_1 = require_SetNumberFormatDigitOptions(); - var utils_1 = require_utils(); - var CoerceOptionsToObject_1 = require_CoerceOptionsToObject(); - var GetNumberOption_1 = require_GetNumberOption(); - var GetStringOrBooleanOption_1 = require_GetStringOrBooleanOption(); - var VALID_ROUND_INCREMENT_VALUES = [ - 1, - 2, - 5, - 10, - 20, - 25, - 50, - 100, - 200, - 250, - 500, - 1e3, - 2e3 - ]; - function InitializeNumberFormat(nf, locales, opts, _a) { - var getInternalSlots = _a.getInternalSlots, localeData = _a.localeData, availableLocales = _a.availableLocales, numberingSystemNames = _a.numberingSystemNames, getDefaultLocale = _a.getDefaultLocale, currencyDigitsData = _a.currencyDigitsData; - var requestedLocales = (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(locales); - var options = (0, CoerceOptionsToObject_1.CoerceOptionsToObject)(opts); - var opt = /* @__PURE__ */ Object.create(null); - var matcher = (0, GetOption_1.GetOption)(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); - opt.localeMatcher = matcher; - var numberingSystem = (0, GetOption_1.GetOption)(options, "numberingSystem", "string", void 0, void 0); - if (numberingSystem !== void 0 && numberingSystemNames.indexOf(numberingSystem) < 0) { - throw RangeError("Invalid numberingSystems: ".concat(numberingSystem)); - } - opt.nu = numberingSystem; - var r = (0, intl_localematcher_1.ResolveLocale)( - availableLocales, - requestedLocales, - opt, - // [[RelevantExtensionKeys]] slot, which is a constant - ["nu"], - localeData, - getDefaultLocale - ); - var dataLocaleData = localeData[r.dataLocale]; - (0, utils_1.invariant)(!!dataLocaleData, "Missing locale data for ".concat(r.dataLocale)); - var internalSlots = getInternalSlots(nf); - internalSlots.locale = r.locale; - internalSlots.dataLocale = r.dataLocale; - internalSlots.numberingSystem = r.nu; - internalSlots.dataLocaleData = dataLocaleData; - (0, SetNumberFormatUnitOptions_1.SetNumberFormatUnitOptions)(nf, options, { getInternalSlots }); - var style = internalSlots.style; - var mnfdDefault; - var mxfdDefault; - if (style === "currency") { - var currency = internalSlots.currency; - var cDigits = (0, CurrencyDigits_1.CurrencyDigits)(currency, { currencyDigitsData }); - mnfdDefault = cDigits; - mxfdDefault = cDigits; - } else { - mnfdDefault = 0; - mxfdDefault = style === "percent" ? 0 : 3; - } - var notation = (0, GetOption_1.GetOption)(options, "notation", "string", ["standard", "scientific", "engineering", "compact"], "standard"); - internalSlots.notation = notation; - (0, SetNumberFormatDigitOptions_1.SetNumberFormatDigitOptions)(internalSlots, options, mnfdDefault, mxfdDefault, notation); - var roundingIncrement = (0, GetNumberOption_1.GetNumberOption)(options, "roundingIncrement", 1, 5e3, 1); - if (VALID_ROUND_INCREMENT_VALUES.indexOf(roundingIncrement) === -1) { - throw new RangeError("Invalid rounding increment value: ".concat(roundingIncrement, ".\nValid values are ").concat(VALID_ROUND_INCREMENT_VALUES, ".")); - } - if (roundingIncrement !== 1 && internalSlots.roundingType !== "fractionDigits") { - throw new TypeError("For roundingIncrement > 1 only fractionDigits is a valid roundingType"); - } - if (roundingIncrement !== 1 && internalSlots.maximumFractionDigits !== internalSlots.minimumFractionDigits) { - throw new RangeError("With roundingIncrement > 1, maximumFractionDigits and minimumFractionDigits must be equal."); - } - internalSlots.roundingIncrement = roundingIncrement; - var trailingZeroDisplay = (0, GetOption_1.GetOption)(options, "trailingZeroDisplay", "string", ["auto", "stripIfInteger"], "auto"); - internalSlots.trailingZeroDisplay = trailingZeroDisplay; - var compactDisplay = (0, GetOption_1.GetOption)(options, "compactDisplay", "string", ["short", "long"], "short"); - var defaultUseGrouping = "auto"; - if (notation === "compact") { - internalSlots.compactDisplay = compactDisplay; - defaultUseGrouping = "min2"; - } - internalSlots.useGrouping = (0, GetStringOrBooleanOption_1.GetStringOrBooleanOption)(options, "useGrouping", ["min2", "auto", "always"], "always", false, defaultUseGrouping); - internalSlots.signDisplay = (0, GetOption_1.GetOption)(options, "signDisplay", "string", ["auto", "never", "always", "exceptZero", "negative"], "auto"); - internalSlots.roundingMode = (0, GetOption_1.GetOption)(options, "roundingMode", "string", [ - "ceil", - "floor", - "expand", - "trunc", - "halfCeil", - "halfFloor", - "halfExpand", - "halfTrunc", - "halfEven" - ], "halfExpand"); - return nf; - } - exports.InitializeNumberFormat = InitializeNumberFormat; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberRangePattern.js - var require_PartitionNumberRangePattern = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberRangePattern.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.PartitionNumberRangePattern = void 0; - var _262_1 = require__(); - var PartitionNumberPattern_1 = require_PartitionNumberPattern(); - var CollapseNumberRange_1 = require_CollapseNumberRange(); - var FormatApproximately_1 = require_FormatApproximately(); - function PartitionNumberRangePattern(numberFormat, x, y, _a) { - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - if (isNaN(x) || isNaN(y)) { - throw new RangeError("Input must be a number"); - } - if (isFinite(x)) { - if (isFinite(y) && y < x) { - throw new RangeError("Y input must be bigger than X"); - } else if (y == Number.NEGATIVE_INFINITY) { - throw new RangeError("Y input must not be NegativeInfinity"); - } else if ((0, _262_1.SameValue)(y, -0) && x >= 0) { - throw new RangeError("Y input must be bigger than X"); - } - } else if (x == Number.POSITIVE_INFINITY) { - if (isFinite(y) || y == Number.NEGATIVE_INFINITY || (0, _262_1.SameValue)(y, -0)) { - throw new RangeError("Y input must be bigger than X"); - } - } else if ((0, _262_1.SameValue)(x, -0)) { - if (isFinite(y) && y < 0) { - throw new RangeError("Y input must be bigger than X"); - } else if (y == Number.NEGATIVE_INFINITY) { - throw new RangeError("Y input must be bigger than X"); - } - } - var result = []; - var xResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, x, { getInternalSlots }); - var yResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, y, { getInternalSlots }); - if (xResult === yResult) { - return (0, FormatApproximately_1.FormatApproximately)(numberFormat, xResult, { getInternalSlots }); - } - for (var _i = 0, xResult_1 = xResult; _i < xResult_1.length; _i++) { - var r = xResult_1[_i]; - r.source = "startRange"; - } - result = result.concat(xResult); - var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]; - var rangeSeparator = symbols.timeSeparator; - result.push({ type: "literal", value: rangeSeparator, source: "shared" }); - for (var _b = 0, yResult_1 = yResult; _b < yResult_1.length; _b++) { - var r = yResult_1[_b]; - r.source = "endRange"; - } - result = result.concat(yResult); - return (0, CollapseNumberRange_1.CollapseNumberRange)(result); - } - exports.PartitionNumberRangePattern = PartitionNumberRangePattern; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/PartitionPattern.js - var require_PartitionPattern = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/PartitionPattern.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.PartitionPattern = void 0; - var utils_1 = require_utils(); - function PartitionPattern(pattern) { - var result = []; - var beginIndex = pattern.indexOf("{"); - var endIndex = 0; - var nextIndex = 0; - var length = pattern.length; - while (beginIndex < pattern.length && beginIndex > -1) { - endIndex = pattern.indexOf("}", beginIndex); - (0, utils_1.invariant)(endIndex > beginIndex, "Invalid pattern ".concat(pattern)); - if (beginIndex > nextIndex) { - result.push({ - type: "literal", - value: pattern.substring(nextIndex, beginIndex) - }); - } - result.push({ - type: pattern.substring(beginIndex + 1, endIndex), - value: void 0 - }); - nextIndex = endIndex + 1; - beginIndex = pattern.indexOf("{", nextIndex); - } - if (nextIndex < length) { - result.push({ - type: "literal", - value: pattern.substring(nextIndex, length) - }); - } - return result; - } - exports.PartitionPattern = PartitionPattern; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/SupportedLocales.js - var require_SupportedLocales = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/SupportedLocales.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.SupportedLocales = void 0; - var _262_1 = require__(); - var GetOption_1 = require_GetOption(); - var intl_localematcher_1 = require_intl_localematcher(); - function SupportedLocales(availableLocales, requestedLocales, options) { - var matcher = "best fit"; - if (options !== void 0) { - options = (0, _262_1.ToObject)(options); - matcher = (0, GetOption_1.GetOption)(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); - } - if (matcher === "best fit") { - return (0, intl_localematcher_1.LookupSupportedLocales)(availableLocales, requestedLocales); - } - return (0, intl_localematcher_1.LookupSupportedLocales)(availableLocales, requestedLocales); - } - exports.SupportedLocales = SupportedLocales; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/data.js - var require_data = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/data.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.isMissingLocaleDataError = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var MissingLocaleDataError = ( - /** @class */ - function(_super) { - tslib_1.__extends(MissingLocaleDataError2, _super); - function MissingLocaleDataError2() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.type = "MISSING_LOCALE_DATA"; - return _this; - } - return MissingLocaleDataError2; - }(Error) - ); - function isMissingLocaleDataError(e) { - return e.type === "MISSING_LOCALE_DATA"; - } - exports.isMissingLocaleDataError = isMissingLocaleDataError; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/relative-time.js - var require_relative_time = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/relative-time.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/date-time.js - var require_date_time = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/date-time.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.RangePatternType = void 0; - var RangePatternType; - (function(RangePatternType2) { - RangePatternType2["startRange"] = "startRange"; - RangePatternType2["shared"] = "shared"; - RangePatternType2["endRange"] = "endRange"; - })(RangePatternType = exports.RangePatternType || (exports.RangePatternType = {})); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/list.js - var require_list = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/list.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/plural-rules.js - var require_plural_rules = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/plural-rules.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/number.js - var require_number = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/number.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/displaynames.js - var require_displaynames = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/displaynames.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/index.js - var require_ecma402_abstract = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.invariant = exports.isMissingLocaleDataError = exports.defineProperty = exports.getMagnitude = exports.setMultiInternalSlots = exports.setInternalSlot = exports.isLiteralPart = exports.getMultiInternalSlots = exports.getInternalSlot = exports._formatToParts = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - tslib_1.__exportStar(require_CanonicalizeLocaleList(), exports); - tslib_1.__exportStar(require_CanonicalizeTimeZoneName(), exports); - tslib_1.__exportStar(require_CoerceOptionsToObject(), exports); - tslib_1.__exportStar(require_GetNumberOption(), exports); - tslib_1.__exportStar(require_GetOption(), exports); - tslib_1.__exportStar(require_GetOptionsObject(), exports); - tslib_1.__exportStar(require_GetStringOrBooleanOption(), exports); - tslib_1.__exportStar(require_IsSanctionedSimpleUnitIdentifier(), exports); - tslib_1.__exportStar(require_IsValidTimeZoneName(), exports); - tslib_1.__exportStar(require_IsWellFormedCurrencyCode(), exports); - tslib_1.__exportStar(require_IsWellFormedUnitIdentifier(), exports); - tslib_1.__exportStar(require_ApplyUnsignedRoundingMode(), exports); - tslib_1.__exportStar(require_CollapseNumberRange(), exports); - tslib_1.__exportStar(require_ComputeExponent(), exports); - tslib_1.__exportStar(require_ComputeExponentForMagnitude(), exports); - tslib_1.__exportStar(require_CurrencyDigits(), exports); - tslib_1.__exportStar(require_FormatApproximately(), exports); - tslib_1.__exportStar(require_FormatNumericToParts(), exports); - tslib_1.__exportStar(require_FormatNumericToString(), exports); - tslib_1.__exportStar(require_GetUnsignedRoundingMode(), exports); - tslib_1.__exportStar(require_InitializeNumberFormat(), exports); - tslib_1.__exportStar(require_PartitionNumberPattern(), exports); - tslib_1.__exportStar(require_PartitionNumberRangePattern(), exports); - tslib_1.__exportStar(require_SetNumberFormatDigitOptions(), exports); - tslib_1.__exportStar(require_SetNumberFormatUnitOptions(), exports); - tslib_1.__exportStar(require_ToRawFixed(), exports); - tslib_1.__exportStar(require_ToRawPrecision(), exports); - var format_to_parts_1 = require_format_to_parts(); - Object.defineProperty(exports, "_formatToParts", { enumerable: true, get: function() { - return tslib_1.__importDefault(format_to_parts_1).default; - } }); - tslib_1.__exportStar(require_PartitionPattern(), exports); - tslib_1.__exportStar(require_SupportedLocales(), exports); - var utils_1 = require_utils(); - Object.defineProperty(exports, "getInternalSlot", { enumerable: true, get: function() { - return utils_1.getInternalSlot; - } }); - Object.defineProperty(exports, "getMultiInternalSlots", { enumerable: true, get: function() { - return utils_1.getMultiInternalSlots; - } }); - Object.defineProperty(exports, "isLiteralPart", { enumerable: true, get: function() { - return utils_1.isLiteralPart; - } }); - Object.defineProperty(exports, "setInternalSlot", { enumerable: true, get: function() { - return utils_1.setInternalSlot; - } }); - Object.defineProperty(exports, "setMultiInternalSlots", { enumerable: true, get: function() { - return utils_1.setMultiInternalSlots; - } }); - Object.defineProperty(exports, "getMagnitude", { enumerable: true, get: function() { - return utils_1.getMagnitude; - } }); - Object.defineProperty(exports, "defineProperty", { enumerable: true, get: function() { - return utils_1.defineProperty; - } }); - var data_1 = require_data(); - Object.defineProperty(exports, "isMissingLocaleDataError", { enumerable: true, get: function() { - return data_1.isMissingLocaleDataError; - } }); - tslib_1.__exportStar(require_relative_time(), exports); - tslib_1.__exportStar(require_date_time(), exports); - tslib_1.__exportStar(require_list(), exports); - tslib_1.__exportStar(require_plural_rules(), exports); - tslib_1.__exportStar(require_number(), exports); - tslib_1.__exportStar(require_displaynames(), exports); - var utils_2 = require_utils(); - Object.defineProperty(exports, "invariant", { enumerable: true, get: function() { - return utils_2.invariant; - } }); - tslib_1.__exportStar(require__(), exports); - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/parser.js - var require_parser = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/parser.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.parseUnicodeLocaleId = exports.parseUnicodeLanguageId = exports.isUnicodeVariantSubtag = exports.isUnicodeScriptSubtag = exports.isUnicodeRegionSubtag = exports.isStructurallyValidLanguageTag = exports.isUnicodeLanguageSubtag = exports.SEPARATOR = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var ALPHANUM_1_8 = /^[a-z0-9]{1,8}$/i; - var ALPHANUM_2_8 = /^[a-z0-9]{2,8}$/i; - var ALPHANUM_3_8 = /^[a-z0-9]{3,8}$/i; - var KEY_REGEX = /^[a-z0-9][a-z]$/i; - var TYPE_REGEX = /^[a-z0-9]{3,8}$/i; - var ALPHA_4 = /^[a-z]{4}$/i; - var OTHER_EXTENSION_TYPE = /^[0-9a-svwyz]$/i; - var UNICODE_REGION_SUBTAG_REGEX = /^([a-z]{2}|[0-9]{3})$/i; - var UNICODE_VARIANT_SUBTAG_REGEX = /^([a-z0-9]{5,8}|[0-9][a-z0-9]{3})$/i; - var UNICODE_LANGUAGE_SUBTAG_REGEX = /^([a-z]{2,3}|[a-z]{5,8})$/i; - var TKEY_REGEX = /^[a-z][0-9]$/i; - exports.SEPARATOR = "-"; - function isUnicodeLanguageSubtag(lang) { - return UNICODE_LANGUAGE_SUBTAG_REGEX.test(lang); - } - exports.isUnicodeLanguageSubtag = isUnicodeLanguageSubtag; - function isStructurallyValidLanguageTag(tag) { - try { - parseUnicodeLanguageId(tag.split(exports.SEPARATOR)); - } catch (e) { - return false; - } - return true; - } - exports.isStructurallyValidLanguageTag = isStructurallyValidLanguageTag; - function isUnicodeRegionSubtag(region) { - return UNICODE_REGION_SUBTAG_REGEX.test(region); - } - exports.isUnicodeRegionSubtag = isUnicodeRegionSubtag; - function isUnicodeScriptSubtag(script) { - return ALPHA_4.test(script); - } - exports.isUnicodeScriptSubtag = isUnicodeScriptSubtag; - function isUnicodeVariantSubtag(variant) { - return UNICODE_VARIANT_SUBTAG_REGEX.test(variant); - } - exports.isUnicodeVariantSubtag = isUnicodeVariantSubtag; - function parseUnicodeLanguageId(chunks) { - if (typeof chunks === "string") { - chunks = chunks.split(exports.SEPARATOR); - } - var lang = chunks.shift(); - if (!lang) { - throw new RangeError("Missing unicode_language_subtag"); - } - if (lang === "root") { - return { lang: "root", variants: [] }; - } - if (!isUnicodeLanguageSubtag(lang)) { - throw new RangeError("Malformed unicode_language_subtag"); - } - var script; - if (chunks.length && isUnicodeScriptSubtag(chunks[0])) { - script = chunks.shift(); - } - var region; - if (chunks.length && isUnicodeRegionSubtag(chunks[0])) { - region = chunks.shift(); - } - var variants = {}; - while (chunks.length && isUnicodeVariantSubtag(chunks[0])) { - var variant = chunks.shift(); - if (variant in variants) { - throw new RangeError('Duplicate variant "'.concat(variant, '"')); - } - variants[variant] = 1; - } - return { - lang, - script, - region, - variants: Object.keys(variants) - }; - } - exports.parseUnicodeLanguageId = parseUnicodeLanguageId; - function parseUnicodeExtension(chunks) { - var keywords = []; - var keyword; - while (chunks.length && (keyword = parseKeyword(chunks))) { - keywords.push(keyword); - } - if (keywords.length) { - return { - type: "u", - keywords, - attributes: [] - }; - } - var attributes = []; - while (chunks.length && ALPHANUM_3_8.test(chunks[0])) { - attributes.push(chunks.shift()); - } - while (chunks.length && (keyword = parseKeyword(chunks))) { - keywords.push(keyword); - } - if (keywords.length || attributes.length) { - return { - type: "u", - attributes, - keywords - }; - } - throw new RangeError("Malformed unicode_extension"); - } - function parseKeyword(chunks) { - var key; - if (!KEY_REGEX.test(chunks[0])) { - return; - } - key = chunks.shift(); - var type = []; - while (chunks.length && TYPE_REGEX.test(chunks[0])) { - type.push(chunks.shift()); - } - var value = ""; - if (type.length) { - value = type.join(exports.SEPARATOR); - } - return [key, value]; - } - function parseTransformedExtension(chunks) { - var lang; - try { - lang = parseUnicodeLanguageId(chunks); - } catch (e) { - } - var fields = []; - while (chunks.length && TKEY_REGEX.test(chunks[0])) { - var key = chunks.shift(); - var value = []; - while (chunks.length && ALPHANUM_3_8.test(chunks[0])) { - value.push(chunks.shift()); - } - if (!value.length) { - throw new RangeError('Missing tvalue for tkey "'.concat(key, '"')); - } - fields.push([key, value.join(exports.SEPARATOR)]); - } - if (fields.length) { - return { - type: "t", - fields, - lang - }; - } - throw new RangeError("Malformed transformed_extension"); - } - function parsePuExtension(chunks) { - var exts = []; - while (chunks.length && ALPHANUM_1_8.test(chunks[0])) { - exts.push(chunks.shift()); - } - if (exts.length) { - return { - type: "x", - value: exts.join(exports.SEPARATOR) - }; - } - throw new RangeError("Malformed private_use_extension"); - } - function parseOtherExtensionValue(chunks) { - var exts = []; - while (chunks.length && ALPHANUM_2_8.test(chunks[0])) { - exts.push(chunks.shift()); - } - if (exts.length) { - return exts.join(exports.SEPARATOR); - } - return ""; - } - function parseExtensions(chunks) { - if (!chunks.length) { - return { extensions: [] }; - } - var extensions = []; - var unicodeExtension; - var transformedExtension; - var puExtension; - var otherExtensionMap = {}; - do { - var type = chunks.shift(); - switch (type) { - case "u": - case "U": - if (unicodeExtension) { - throw new RangeError("There can only be 1 -u- extension"); - } - unicodeExtension = parseUnicodeExtension(chunks); - extensions.push(unicodeExtension); - break; - case "t": - case "T": - if (transformedExtension) { - throw new RangeError("There can only be 1 -t- extension"); - } - transformedExtension = parseTransformedExtension(chunks); - extensions.push(transformedExtension); - break; - case "x": - case "X": - if (puExtension) { - throw new RangeError("There can only be 1 -x- extension"); - } - puExtension = parsePuExtension(chunks); - extensions.push(puExtension); - break; - default: - if (!OTHER_EXTENSION_TYPE.test(type)) { - throw new RangeError("Malformed extension type"); - } - if (type in otherExtensionMap) { - throw new RangeError("There can only be 1 -".concat(type, "- extension")); - } - var extension = { - type, - value: parseOtherExtensionValue(chunks) - }; - otherExtensionMap[extension.type] = extension; - extensions.push(extension); - break; - } - } while (chunks.length); - return { extensions }; - } - function parseUnicodeLocaleId(locale) { - var chunks = locale.split(exports.SEPARATOR); - var lang = parseUnicodeLanguageId(chunks); - return tslib_1.__assign({ lang }, parseExtensions(chunks)); - } - exports.parseUnicodeLocaleId = parseUnicodeLocaleId; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/emitter.js - var require_emitter = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/emitter.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.emitUnicodeLocaleId = exports.emitUnicodeLanguageId = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - function emitUnicodeLanguageId(lang) { - if (!lang) { - return ""; - } - return tslib_1.__spreadArray([lang.lang, lang.script, lang.region], lang.variants || [], true).filter(Boolean).join("-"); - } - exports.emitUnicodeLanguageId = emitUnicodeLanguageId; - function emitUnicodeLocaleId(_a) { - var lang = _a.lang, extensions = _a.extensions; - var chunks = [emitUnicodeLanguageId(lang)]; - for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) { - var ext = extensions_1[_i]; - chunks.push(ext.type); - switch (ext.type) { - case "u": - chunks.push.apply(chunks, tslib_1.__spreadArray(tslib_1.__spreadArray([], ext.attributes, false), ext.keywords.reduce(function(all, kv) { - return all.concat(kv); - }, []), false)); - break; - case "t": - chunks.push.apply(chunks, tslib_1.__spreadArray([emitUnicodeLanguageId(ext.lang)], ext.fields.reduce(function(all, kv) { - return all.concat(kv); - }, []), false)); - break; - default: - chunks.push(ext.value); - break; - } - } - return chunks.filter(Boolean).join("-"); - } - exports.emitUnicodeLocaleId = emitUnicodeLocaleId; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/aliases.generated.js - var require_aliases_generated = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/aliases.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.variantAlias = exports.scriptAlias = exports.territoryAlias = exports.languageAlias = void 0; - exports.languageAlias = { - "aa-saaho": "ssy", - "aam": "aas", - "aar": "aa", - "abk": "ab", - "adp": "dz", - "afr": "af", - "agp": "apf", - "ais": "ami", - "aju": "jrb", - "aka": "ak", - "alb": "sq", - "als": "sq", - "amh": "am", - "ara": "ar", - "arb": "ar", - "arg": "an", - "arm": "hy", - "art-lojban": "jbo", - "asd": "snz", - "asm": "as", - "aue": "ktz", - "ava": "av", - "ave": "ae", - "aym": "ay", - "ayr": "ay", - "ayx": "nun", - "aze": "az", - "azj": "az", - "bak": "ba", - "bam": "bm", - "baq": "eu", - "baz": "nvo", - "bcc": "bal", - "bcl": "bik", - "bel": "be", - "ben": "bn", - "bgm": "bcg", - "bh": "bho", - "bhk": "fbl", - "bic": "bir", - "bih": "bho", - "bis": "bi", - "bjd": "drl", - "bjq": "bzc", - "bkb": "ebk", - "blg": "iba", - "bod": "bo", - "bos": "bs", - "bre": "br", - "btb": "beb", - "bul": "bg", - "bur": "my", - "bxk": "luy", - "bxr": "bua", - "cat": "ca", - "ccq": "rki", - "cel-gaulish": "xtg", - "ces": "cs", - "cha": "ch", - "che": "ce", - "chi": "zh", - "chu": "cu", - "chv": "cv", - "cjr": "mom", - "cka": "cmr", - "cld": "syr", - "cmk": "xch", - "cmn": "zh", - "cnr": "sr-ME", - "cor": "kw", - "cos": "co", - "coy": "pij", - "cqu": "quh", - "cre": "cr", - "cwd": "cr", - "cym": "cy", - "cze": "cs", - "daf": "dnj", - "dan": "da", - "dap": "njz", - "deu": "de", - "dgo": "doi", - "dhd": "mwr", - "dik": "din", - "diq": "zza", - "dit": "dif", - "div": "dv", - "djl": "dze", - "dkl": "aqd", - "drh": "mn", - "drr": "kzk", - "drw": "fa-AF", - "dud": "uth", - "duj": "dwu", - "dut": "nl", - "dwl": "dbt", - "dzo": "dz", - "ekk": "et", - "ell": "el", - "elp": "amq", - "emk": "man", - "en-GB-oed": "en-GB-oxendict", - "eng": "en", - "epo": "eo", - "esk": "ik", - "est": "et", - "eus": "eu", - "ewe": "ee", - "fao": "fo", - "fas": "fa", - "fat": "ak", - "fij": "fj", - "fin": "fi", - "fra": "fr", - "fre": "fr", - "fry": "fy", - "fuc": "ff", - "ful": "ff", - "gav": "dev", - "gaz": "om", - "gbc": "wny", - "gbo": "grb", - "geo": "ka", - "ger": "de", - "gfx": "vaj", - "ggn": "gvr", - "ggo": "esg", - "ggr": "gtu", - "gio": "aou", - "gla": "gd", - "gle": "ga", - "glg": "gl", - "gli": "kzk", - "glv": "gv", - "gno": "gon", - "gre": "el", - "grn": "gn", - "gti": "nyc", - "gug": "gn", - "guj": "gu", - "guv": "duz", - "gya": "gba", - "hat": "ht", - "hau": "ha", - "hbs": "sr-Latn", - "hdn": "hai", - "hea": "hmn", - "heb": "he", - "her": "hz", - "him": "srx", - "hin": "hi", - "hmo": "ho", - "hrr": "jal", - "hrv": "hr", - "hun": "hu", - "hy-arevmda": "hyw", - "hye": "hy", - "i-ami": "ami", - "i-bnn": "bnn", - "i-default": "en-x-i-default", - "i-enochian": "und-x-i-enochian", - "i-hak": "hak", - "i-klingon": "tlh", - "i-lux": "lb", - "i-mingo": "see-x-i-mingo", - "i-navajo": "nv", - "i-pwn": "pwn", - "i-tao": "tao", - "i-tay": "tay", - "i-tsu": "tsu", - "ibi": "opa", - "ibo": "ig", - "ice": "is", - "ido": "io", - "iii": "ii", - "ike": "iu", - "iku": "iu", - "ile": "ie", - "ill": "ilm", - "ilw": "gal", - "in": "id", - "ina": "ia", - "ind": "id", - "ipk": "ik", - "isl": "is", - "ita": "it", - "iw": "he", - "izi": "eza", - "jar": "jgk", - "jav": "jv", - "jeg": "oyb", - "ji": "yi", - "jpn": "ja", - "jw": "jv", - "kal": "kl", - "kan": "kn", - "kas": "ks", - "kat": "ka", - "kau": "kr", - "kaz": "kk", - "kdv": "zkd", - "kgc": "tdf", - "kgd": "ncq", - "kgh": "kml", - "khk": "mn", - "khm": "km", - "kik": "ki", - "kin": "rw", - "kir": "ky", - "kmr": "ku", - "knc": "kr", - "kng": "kg", - "knn": "kok", - "koj": "kwv", - "kom": "kv", - "kon": "kg", - "kor": "ko", - "kpp": "jkm", - "kpv": "kv", - "krm": "bmf", - "ktr": "dtp", - "kua": "kj", - "kur": "ku", - "kvs": "gdj", - "kwq": "yam", - "kxe": "tvd", - "kxl": "kru", - "kzh": "dgl", - "kzj": "dtp", - "kzt": "dtp", - "lao": "lo", - "lat": "la", - "lav": "lv", - "lbk": "bnc", - "leg": "enl", - "lii": "raq", - "lim": "li", - "lin": "ln", - "lit": "lt", - "llo": "ngt", - "lmm": "rmx", - "ltz": "lb", - "lub": "lu", - "lug": "lg", - "lvs": "lv", - "mac": "mk", - "mah": "mh", - "mal": "ml", - "mao": "mi", - "mar": "mr", - "may": "ms", - "meg": "cir", - "mgx": "jbk", - "mhr": "chm", - "mkd": "mk", - "mlg": "mg", - "mlt": "mt", - "mnk": "man", - "mnt": "wnn", - "mo": "ro", - "mof": "xnt", - "mol": "ro", - "mon": "mn", - "mri": "mi", - "msa": "ms", - "mst": "mry", - "mup": "raj", - "mwd": "dmw", - "mwj": "vaj", - "mya": "my", - "myd": "aog", - "myt": "mry", - "nad": "xny", - "nau": "na", - "nav": "nv", - "nbf": "nru", - "nbl": "nr", - "nbx": "ekc", - "ncp": "kdz", - "nde": "nd", - "ndo": "ng", - "nep": "ne", - "nld": "nl", - "nln": "azd", - "nlr": "nrk", - "nno": "nn", - "nns": "nbr", - "nnx": "ngv", - "no-bok": "nb", - "no-bokmal": "nb", - "no-nyn": "nn", - "no-nynorsk": "nn", - "nob": "nb", - "noo": "dtd", - "nor": "no", - "npi": "ne", - "nts": "pij", - "nxu": "bpp", - "nya": "ny", - "oci": "oc", - "ojg": "oj", - "oji": "oj", - "ori": "or", - "orm": "om", - "ory": "or", - "oss": "os", - "oun": "vaj", - "pan": "pa", - "pat": "kxr", - "pbu": "ps", - "pcr": "adx", - "per": "fa", - "pes": "fa", - "pli": "pi", - "plt": "mg", - "pmc": "huw", - "pmu": "phr", - "pnb": "lah", - "pol": "pl", - "por": "pt", - "ppa": "bfy", - "ppr": "lcq", - "prs": "fa-AF", - "pry": "prt", - "pus": "ps", - "puz": "pub", - "que": "qu", - "quz": "qu", - "rmr": "emx", - "rmy": "rom", - "roh": "rm", - "ron": "ro", - "rum": "ro", - "run": "rn", - "rus": "ru", - "sag": "sg", - "san": "sa", - "sap": "aqt", - "sca": "hle", - "scc": "sr", - "scr": "hr", - "sgl": "isk", - "sgn-BE-FR": "sfb", - "sgn-BE-NL": "vgt", - "sgn-BR": "bzs", - "sgn-CH-DE": "sgg", - "sgn-CO": "csn", - "sgn-DE": "gsg", - "sgn-DK": "dsl", - "sgn-ES": "ssp", - "sgn-FR": "fsl", - "sgn-GB": "bfi", - "sgn-GR": "gss", - "sgn-IE": "isg", - "sgn-IT": "ise", - "sgn-JP": "jsl", - "sgn-MX": "mfs", - "sgn-NI": "ncs", - "sgn-NL": "dse", - "sgn-NO": "nsi", - "sgn-PT": "psr", - "sgn-SE": "swl", - "sgn-US": "ase", - "sgn-ZA": "sfs", - "sh": "sr-Latn", - "sin": "si", - "skk": "oyb", - "slk": "sk", - "slo": "sk", - "slv": "sl", - "sme": "se", - "smo": "sm", - "sna": "sn", - "snd": "sd", - "som": "so", - "sot": "st", - "spa": "es", - "spy": "kln", - "sqi": "sq", - "src": "sc", - "srd": "sc", - "srp": "sr", - "ssw": "ss", - "sul": "sgd", - "sum": "ulw", - "sun": "su", - "swa": "sw", - "swc": "sw-CD", - "swe": "sv", - "swh": "sw", - "tah": "ty", - "tam": "ta", - "tat": "tt", - "tdu": "dtp", - "tel": "te", - "tgg": "bjp", - "tgk": "tg", - "tgl": "fil", - "tha": "th", - "thc": "tpo", - "thw": "ola", - "thx": "oyb", - "tib": "bo", - "tid": "itd", - "tie": "ras", - "tir": "ti", - "tkk": "twm", - "tl": "fil", - "tlw": "weo", - "tmp": "tyj", - "tne": "kak", - "tnf": "fa-AF", - "ton": "to", - "tsf": "taj", - "tsn": "tn", - "tso": "ts", - "ttq": "tmh", - "tuk": "tk", - "tur": "tr", - "tw": "ak", - "twi": "ak", - "uig": "ug", - "ukr": "uk", - "umu": "del", - "und-aaland": "und-AX", - "und-arevela": "und", - "und-arevmda": "und", - "und-bokmal": "und", - "und-hakka": "und", - "und-hepburn-heploc": "und-alalc97", - "und-lojban": "und", - "und-nynorsk": "und", - "und-saaho": "und", - "und-xiang": "und", - "unp": "wro", - "uok": "ema", - "urd": "ur", - "uzb": "uz", - "uzn": "uz", - "ven": "ve", - "vie": "vi", - "vol": "vo", - "wel": "cy", - "wgw": "wgb", - "wit": "nol", - "wiw": "nwo", - "wln": "wa", - "wol": "wo", - "xba": "cax", - "xho": "xh", - "xia": "acn", - "xkh": "waw", - "xpe": "kpe", - "xrq": "dmw", - "xsj": "suj", - "xsl": "den", - "ybd": "rki", - "ydd": "yi", - "yen": "ynq", - "yid": "yi", - "yiy": "yrm", - "yma": "lrr", - "ymt": "mtm", - "yor": "yo", - "yos": "zom", - "yuu": "yug", - "zai": "zap", - "zh-cmn": "zh", - "zh-cmn-Hans": "zh-Hans", - "zh-cmn-Hant": "zh-Hant", - "zh-gan": "gan", - "zh-guoyu": "zh", - "zh-hakka": "hak", - "zh-min": "nan-x-zh-min", - "zh-min-nan": "nan", - "zh-wuu": "wuu", - "zh-xiang": "hsn", - "zh-yue": "yue", - "zha": "za", - "zho": "zh", - "zir": "scv", - "zsm": "ms", - "zul": "zu", - "zyb": "za" - }; - exports.territoryAlias = { - "100": "BG", - "104": "MM", - "108": "BI", - "112": "BY", - "116": "KH", - "120": "CM", - "124": "CA", - "132": "CV", - "136": "KY", - "140": "CF", - "144": "LK", - "148": "TD", - "152": "CL", - "156": "CN", - "158": "TW", - "162": "CX", - "166": "CC", - "170": "CO", - "172": "RU AM AZ BY GE KG KZ MD TJ TM UA UZ", - "174": "KM", - "175": "YT", - "178": "CG", - "180": "CD", - "184": "CK", - "188": "CR", - "191": "HR", - "192": "CU", - "196": "CY", - "200": "CZ SK", - "203": "CZ", - "204": "BJ", - "208": "DK", - "212": "DM", - "214": "DO", - "218": "EC", - "222": "SV", - "226": "GQ", - "230": "ET", - "231": "ET", - "232": "ER", - "233": "EE", - "234": "FO", - "238": "FK", - "239": "GS", - "242": "FJ", - "246": "FI", - "248": "AX", - "249": "FR", - "250": "FR", - "254": "GF", - "258": "PF", - "260": "TF", - "262": "DJ", - "266": "GA", - "268": "GE", - "270": "GM", - "275": "PS", - "276": "DE", - "278": "DE", - "280": "DE", - "288": "GH", - "292": "GI", - "296": "KI", - "300": "GR", - "304": "GL", - "308": "GD", - "312": "GP", - "316": "GU", - "320": "GT", - "324": "GN", - "328": "GY", - "332": "HT", - "334": "HM", - "336": "VA", - "340": "HN", - "344": "HK", - "348": "HU", - "352": "IS", - "356": "IN", - "360": "ID", - "364": "IR", - "368": "IQ", - "372": "IE", - "376": "IL", - "380": "IT", - "384": "CI", - "388": "JM", - "392": "JP", - "398": "KZ", - "400": "JO", - "404": "KE", - "408": "KP", - "410": "KR", - "414": "KW", - "417": "KG", - "418": "LA", - "422": "LB", - "426": "LS", - "428": "LV", - "430": "LR", - "434": "LY", - "438": "LI", - "440": "LT", - "442": "LU", - "446": "MO", - "450": "MG", - "454": "MW", - "458": "MY", - "462": "MV", - "466": "ML", - "470": "MT", - "474": "MQ", - "478": "MR", - "480": "MU", - "484": "MX", - "492": "MC", - "496": "MN", - "498": "MD", - "499": "ME", - "500": "MS", - "504": "MA", - "508": "MZ", - "512": "OM", - "516": "NA", - "520": "NR", - "524": "NP", - "528": "NL", - "530": "CW SX BQ", - "531": "CW", - "532": "CW SX BQ", - "533": "AW", - "534": "SX", - "535": "BQ", - "536": "SA IQ", - "540": "NC", - "548": "VU", - "554": "NZ", - "558": "NI", - "562": "NE", - "566": "NG", - "570": "NU", - "574": "NF", - "578": "NO", - "580": "MP", - "581": "UM", - "582": "FM MH MP PW", - "583": "FM", - "584": "MH", - "585": "PW", - "586": "PK", - "591": "PA", - "598": "PG", - "600": "PY", - "604": "PE", - "608": "PH", - "612": "PN", - "616": "PL", - "620": "PT", - "624": "GW", - "626": "TL", - "630": "PR", - "634": "QA", - "638": "RE", - "642": "RO", - "643": "RU", - "646": "RW", - "652": "BL", - "654": "SH", - "659": "KN", - "660": "AI", - "662": "LC", - "663": "MF", - "666": "PM", - "670": "VC", - "674": "SM", - "678": "ST", - "682": "SA", - "686": "SN", - "688": "RS", - "690": "SC", - "694": "SL", - "702": "SG", - "703": "SK", - "704": "VN", - "705": "SI", - "706": "SO", - "710": "ZA", - "716": "ZW", - "720": "YE", - "724": "ES", - "728": "SS", - "729": "SD", - "732": "EH", - "736": "SD", - "740": "SR", - "744": "SJ", - "748": "SZ", - "752": "SE", - "756": "CH", - "760": "SY", - "762": "TJ", - "764": "TH", - "768": "TG", - "772": "TK", - "776": "TO", - "780": "TT", - "784": "AE", - "788": "TN", - "792": "TR", - "795": "TM", - "796": "TC", - "798": "TV", - "800": "UG", - "804": "UA", - "807": "MK", - "810": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", - "818": "EG", - "826": "GB", - "830": "JE GG", - "831": "GG", - "832": "JE", - "833": "IM", - "834": "TZ", - "840": "US", - "850": "VI", - "854": "BF", - "858": "UY", - "860": "UZ", - "862": "VE", - "876": "WF", - "882": "WS", - "886": "YE", - "887": "YE", - "890": "RS ME SI HR MK BA", - "891": "RS ME", - "894": "ZM", - "958": "AA", - "959": "QM", - "960": "QN", - "962": "QP", - "963": "QQ", - "964": "QR", - "965": "QS", - "966": "QT", - "967": "EU", - "968": "QV", - "969": "QW", - "970": "QX", - "971": "QY", - "972": "QZ", - "973": "XA", - "974": "XB", - "975": "XC", - "976": "XD", - "977": "XE", - "978": "XF", - "979": "XG", - "980": "XH", - "981": "XI", - "982": "XJ", - "983": "XK", - "984": "XL", - "985": "XM", - "986": "XN", - "987": "XO", - "988": "XP", - "989": "XQ", - "990": "XR", - "991": "XS", - "992": "XT", - "993": "XU", - "994": "XV", - "995": "XW", - "996": "XX", - "997": "XY", - "998": "XZ", - "999": "ZZ", - "004": "AF", - "008": "AL", - "010": "AQ", - "012": "DZ", - "016": "AS", - "020": "AD", - "024": "AO", - "028": "AG", - "031": "AZ", - "032": "AR", - "036": "AU", - "040": "AT", - "044": "BS", - "048": "BH", - "050": "BD", - "051": "AM", - "052": "BB", - "056": "BE", - "060": "BM", - "062": "034 143", - "064": "BT", - "068": "BO", - "070": "BA", - "072": "BW", - "074": "BV", - "076": "BR", - "084": "BZ", - "086": "IO", - "090": "SB", - "092": "VG", - "096": "BN", - "AAA": "AA", - "ABW": "AW", - "AFG": "AF", - "AGO": "AO", - "AIA": "AI", - "ALA": "AX", - "ALB": "AL", - "AN": "CW SX BQ", - "AND": "AD", - "ANT": "CW SX BQ", - "ARE": "AE", - "ARG": "AR", - "ARM": "AM", - "ASC": "AC", - "ASM": "AS", - "ATA": "AQ", - "ATF": "TF", - "ATG": "AG", - "AUS": "AU", - "AUT": "AT", - "AZE": "AZ", - "BDI": "BI", - "BEL": "BE", - "BEN": "BJ", - "BES": "BQ", - "BFA": "BF", - "BGD": "BD", - "BGR": "BG", - "BHR": "BH", - "BHS": "BS", - "BIH": "BA", - "BLM": "BL", - "BLR": "BY", - "BLZ": "BZ", - "BMU": "BM", - "BOL": "BO", - "BRA": "BR", - "BRB": "BB", - "BRN": "BN", - "BTN": "BT", - "BU": "MM", - "BUR": "MM", - "BVT": "BV", - "BWA": "BW", - "CAF": "CF", - "CAN": "CA", - "CCK": "CC", - "CHE": "CH", - "CHL": "CL", - "CHN": "CN", - "CIV": "CI", - "CMR": "CM", - "COD": "CD", - "COG": "CG", - "COK": "CK", - "COL": "CO", - "COM": "KM", - "CPT": "CP", - "CPV": "CV", - "CRI": "CR", - "CS": "RS ME", - "CT": "KI", - "CUB": "CU", - "CUW": "CW", - "CXR": "CX", - "CYM": "KY", - "CYP": "CY", - "CZE": "CZ", - "DD": "DE", - "DDR": "DE", - "DEU": "DE", - "DGA": "DG", - "DJI": "DJ", - "DMA": "DM", - "DNK": "DK", - "DOM": "DO", - "DY": "BJ", - "DZA": "DZ", - "ECU": "EC", - "EGY": "EG", - "ERI": "ER", - "ESH": "EH", - "ESP": "ES", - "EST": "EE", - "ETH": "ET", - "FIN": "FI", - "FJI": "FJ", - "FLK": "FK", - "FQ": "AQ TF", - "FRA": "FR", - "FRO": "FO", - "FSM": "FM", - "FX": "FR", - "FXX": "FR", - "GAB": "GA", - "GBR": "GB", - "GEO": "GE", - "GGY": "GG", - "GHA": "GH", - "GIB": "GI", - "GIN": "GN", - "GLP": "GP", - "GMB": "GM", - "GNB": "GW", - "GNQ": "GQ", - "GRC": "GR", - "GRD": "GD", - "GRL": "GL", - "GTM": "GT", - "GUF": "GF", - "GUM": "GU", - "GUY": "GY", - "HKG": "HK", - "HMD": "HM", - "HND": "HN", - "HRV": "HR", - "HTI": "HT", - "HUN": "HU", - "HV": "BF", - "IDN": "ID", - "IMN": "IM", - "IND": "IN", - "IOT": "IO", - "IRL": "IE", - "IRN": "IR", - "IRQ": "IQ", - "ISL": "IS", - "ISR": "IL", - "ITA": "IT", - "JAM": "JM", - "JEY": "JE", - "JOR": "JO", - "JPN": "JP", - "JT": "UM", - "KAZ": "KZ", - "KEN": "KE", - "KGZ": "KG", - "KHM": "KH", - "KIR": "KI", - "KNA": "KN", - "KOR": "KR", - "KWT": "KW", - "LAO": "LA", - "LBN": "LB", - "LBR": "LR", - "LBY": "LY", - "LCA": "LC", - "LIE": "LI", - "LKA": "LK", - "LSO": "LS", - "LTU": "LT", - "LUX": "LU", - "LVA": "LV", - "MAC": "MO", - "MAF": "MF", - "MAR": "MA", - "MCO": "MC", - "MDA": "MD", - "MDG": "MG", - "MDV": "MV", - "MEX": "MX", - "MHL": "MH", - "MI": "UM", - "MKD": "MK", - "MLI": "ML", - "MLT": "MT", - "MMR": "MM", - "MNE": "ME", - "MNG": "MN", - "MNP": "MP", - "MOZ": "MZ", - "MRT": "MR", - "MSR": "MS", - "MTQ": "MQ", - "MUS": "MU", - "MWI": "MW", - "MYS": "MY", - "MYT": "YT", - "NAM": "NA", - "NCL": "NC", - "NER": "NE", - "NFK": "NF", - "NGA": "NG", - "NH": "VU", - "NIC": "NI", - "NIU": "NU", - "NLD": "NL", - "NOR": "NO", - "NPL": "NP", - "NQ": "AQ", - "NRU": "NR", - "NT": "SA IQ", - "NTZ": "SA IQ", - "NZL": "NZ", - "OMN": "OM", - "PAK": "PK", - "PAN": "PA", - "PC": "FM MH MP PW", - "PCN": "PN", - "PER": "PE", - "PHL": "PH", - "PLW": "PW", - "PNG": "PG", - "POL": "PL", - "PRI": "PR", - "PRK": "KP", - "PRT": "PT", - "PRY": "PY", - "PSE": "PS", - "PU": "UM", - "PYF": "PF", - "PZ": "PA", - "QAT": "QA", - "QMM": "QM", - "QNN": "QN", - "QPP": "QP", - "QQQ": "QQ", - "QRR": "QR", - "QSS": "QS", - "QTT": "QT", - "QU": "EU", - "QUU": "EU", - "QVV": "QV", - "QWW": "QW", - "QXX": "QX", - "QYY": "QY", - "QZZ": "QZ", - "REU": "RE", - "RH": "ZW", - "ROU": "RO", - "RUS": "RU", - "RWA": "RW", - "SAU": "SA", - "SCG": "RS ME", - "SDN": "SD", - "SEN": "SN", - "SGP": "SG", - "SGS": "GS", - "SHN": "SH", - "SJM": "SJ", - "SLB": "SB", - "SLE": "SL", - "SLV": "SV", - "SMR": "SM", - "SOM": "SO", - "SPM": "PM", - "SRB": "RS", - "SSD": "SS", - "STP": "ST", - "SU": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", - "SUN": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", - "SUR": "SR", - "SVK": "SK", - "SVN": "SI", - "SWE": "SE", - "SWZ": "SZ", - "SXM": "SX", - "SYC": "SC", - "SYR": "SY", - "TAA": "TA", - "TCA": "TC", - "TCD": "TD", - "TGO": "TG", - "THA": "TH", - "TJK": "TJ", - "TKL": "TK", - "TKM": "TM", - "TLS": "TL", - "TMP": "TL", - "TON": "TO", - "TP": "TL", - "TTO": "TT", - "TUN": "TN", - "TUR": "TR", - "TUV": "TV", - "TWN": "TW", - "TZA": "TZ", - "UGA": "UG", - "UK": "GB", - "UKR": "UA", - "UMI": "UM", - "URY": "UY", - "USA": "US", - "UZB": "UZ", - "VAT": "VA", - "VCT": "VC", - "VD": "VN", - "VEN": "VE", - "VGB": "VG", - "VIR": "VI", - "VNM": "VN", - "VUT": "VU", - "WK": "UM", - "WLF": "WF", - "WSM": "WS", - "XAA": "XA", - "XBB": "XB", - "XCC": "XC", - "XDD": "XD", - "XEE": "XE", - "XFF": "XF", - "XGG": "XG", - "XHH": "XH", - "XII": "XI", - "XJJ": "XJ", - "XKK": "XK", - "XLL": "XL", - "XMM": "XM", - "XNN": "XN", - "XOO": "XO", - "XPP": "XP", - "XQQ": "XQ", - "XRR": "XR", - "XSS": "XS", - "XTT": "XT", - "XUU": "XU", - "XVV": "XV", - "XWW": "XW", - "XXX": "XX", - "XYY": "XY", - "XZZ": "XZ", - "YD": "YE", - "YEM": "YE", - "YMD": "YE", - "YU": "RS ME", - "YUG": "RS ME", - "ZAF": "ZA", - "ZAR": "CD", - "ZMB": "ZM", - "ZR": "CD", - "ZWE": "ZW", - "ZZZ": "ZZ" - }; - exports.scriptAlias = { - "Qaai": "Zinh" - }; - exports.variantAlias = { - "heploc": "alalc97", - "polytoni": "polyton" - }; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/likelySubtags.generated.js - var require_likelySubtags_generated = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/likelySubtags.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.likelySubtags = void 0; - exports.likelySubtags = { - "aa": "aa-Latn-ET", - "aai": "aai-Latn-ZZ", - "aak": "aak-Latn-ZZ", - "aau": "aau-Latn-ZZ", - "ab": "ab-Cyrl-GE", - "abi": "abi-Latn-ZZ", - "abq": "abq-Cyrl-ZZ", - "abr": "abr-Latn-GH", - "abt": "abt-Latn-ZZ", - "aby": "aby-Latn-ZZ", - "acd": "acd-Latn-ZZ", - "ace": "ace-Latn-ID", - "ach": "ach-Latn-UG", - "ada": "ada-Latn-GH", - "ade": "ade-Latn-ZZ", - "adj": "adj-Latn-ZZ", - "adp": "adp-Tibt-BT", - "ady": "ady-Cyrl-RU", - "adz": "adz-Latn-ZZ", - "ae": "ae-Avst-IR", - "aeb": "aeb-Arab-TN", - "aey": "aey-Latn-ZZ", - "af": "af-Latn-ZA", - "agc": "agc-Latn-ZZ", - "agd": "agd-Latn-ZZ", - "agg": "agg-Latn-ZZ", - "agm": "agm-Latn-ZZ", - "ago": "ago-Latn-ZZ", - "agq": "agq-Latn-CM", - "aha": "aha-Latn-ZZ", - "ahl": "ahl-Latn-ZZ", - "aho": "aho-Ahom-IN", - "ajg": "ajg-Latn-ZZ", - "ak": "ak-Latn-GH", - "akk": "akk-Xsux-IQ", - "ala": "ala-Latn-ZZ", - "ali": "ali-Latn-ZZ", - "aln": "aln-Latn-XK", - "alt": "alt-Cyrl-RU", - "am": "am-Ethi-ET", - "amm": "amm-Latn-ZZ", - "amn": "amn-Latn-ZZ", - "amo": "amo-Latn-NG", - "amp": "amp-Latn-ZZ", - "an": "an-Latn-ES", - "anc": "anc-Latn-ZZ", - "ank": "ank-Latn-ZZ", - "ann": "ann-Latn-ZZ", - "any": "any-Latn-ZZ", - "aoj": "aoj-Latn-ZZ", - "aom": "aom-Latn-ZZ", - "aoz": "aoz-Latn-ID", - "apc": "apc-Arab-ZZ", - "apd": "apd-Arab-TG", - "ape": "ape-Latn-ZZ", - "apr": "apr-Latn-ZZ", - "aps": "aps-Latn-ZZ", - "apz": "apz-Latn-ZZ", - "ar": "ar-Arab-EG", - "arc": "arc-Armi-IR", - "arc-Nbat": "arc-Nbat-JO", - "arc-Palm": "arc-Palm-SY", - "arh": "arh-Latn-ZZ", - "arn": "arn-Latn-CL", - "aro": "aro-Latn-BO", - "arq": "arq-Arab-DZ", - "ars": "ars-Arab-SA", - "ary": "ary-Arab-MA", - "arz": "arz-Arab-EG", - "as": "as-Beng-IN", - "asa": "asa-Latn-TZ", - "ase": "ase-Sgnw-US", - "asg": "asg-Latn-ZZ", - "aso": "aso-Latn-ZZ", - "ast": "ast-Latn-ES", - "ata": "ata-Latn-ZZ", - "atg": "atg-Latn-ZZ", - "atj": "atj-Latn-CA", - "auy": "auy-Latn-ZZ", - "av": "av-Cyrl-RU", - "avl": "avl-Arab-ZZ", - "avn": "avn-Latn-ZZ", - "avt": "avt-Latn-ZZ", - "avu": "avu-Latn-ZZ", - "awa": "awa-Deva-IN", - "awb": "awb-Latn-ZZ", - "awo": "awo-Latn-ZZ", - "awx": "awx-Latn-ZZ", - "ay": "ay-Latn-BO", - "ayb": "ayb-Latn-ZZ", - "az": "az-Latn-AZ", - "az-Arab": "az-Arab-IR", - "az-IQ": "az-Arab-IQ", - "az-IR": "az-Arab-IR", - "az-RU": "az-Cyrl-RU", - "ba": "ba-Cyrl-RU", - "bal": "bal-Arab-PK", - "ban": "ban-Latn-ID", - "bap": "bap-Deva-NP", - "bar": "bar-Latn-AT", - "bas": "bas-Latn-CM", - "bav": "bav-Latn-ZZ", - "bax": "bax-Bamu-CM", - "bba": "bba-Latn-ZZ", - "bbb": "bbb-Latn-ZZ", - "bbc": "bbc-Latn-ID", - "bbd": "bbd-Latn-ZZ", - "bbj": "bbj-Latn-CM", - "bbp": "bbp-Latn-ZZ", - "bbr": "bbr-Latn-ZZ", - "bcf": "bcf-Latn-ZZ", - "bch": "bch-Latn-ZZ", - "bci": "bci-Latn-CI", - "bcm": "bcm-Latn-ZZ", - "bcn": "bcn-Latn-ZZ", - "bco": "bco-Latn-ZZ", - "bcq": "bcq-Ethi-ZZ", - "bcu": "bcu-Latn-ZZ", - "bdd": "bdd-Latn-ZZ", - "be": "be-Cyrl-BY", - "bef": "bef-Latn-ZZ", - "beh": "beh-Latn-ZZ", - "bej": "bej-Arab-SD", - "bem": "bem-Latn-ZM", - "bet": "bet-Latn-ZZ", - "bew": "bew-Latn-ID", - "bex": "bex-Latn-ZZ", - "bez": "bez-Latn-TZ", - "bfd": "bfd-Latn-CM", - "bfq": "bfq-Taml-IN", - "bft": "bft-Arab-PK", - "bfy": "bfy-Deva-IN", - "bg": "bg-Cyrl-BG", - "bgc": "bgc-Deva-IN", - "bgn": "bgn-Arab-PK", - "bgx": "bgx-Grek-TR", - "bhb": "bhb-Deva-IN", - "bhg": "bhg-Latn-ZZ", - "bhi": "bhi-Deva-IN", - "bhl": "bhl-Latn-ZZ", - "bho": "bho-Deva-IN", - "bhy": "bhy-Latn-ZZ", - "bi": "bi-Latn-VU", - "bib": "bib-Latn-ZZ", - "big": "big-Latn-ZZ", - "bik": "bik-Latn-PH", - "bim": "bim-Latn-ZZ", - "bin": "bin-Latn-NG", - "bio": "bio-Latn-ZZ", - "biq": "biq-Latn-ZZ", - "bjh": "bjh-Latn-ZZ", - "bji": "bji-Ethi-ZZ", - "bjj": "bjj-Deva-IN", - "bjn": "bjn-Latn-ID", - "bjo": "bjo-Latn-ZZ", - "bjr": "bjr-Latn-ZZ", - "bjt": "bjt-Latn-SN", - "bjz": "bjz-Latn-ZZ", - "bkc": "bkc-Latn-ZZ", - "bkm": "bkm-Latn-CM", - "bkq": "bkq-Latn-ZZ", - "bku": "bku-Latn-PH", - "bkv": "bkv-Latn-ZZ", - "blg": "blg-Latn-MY", - "blt": "blt-Tavt-VN", - "bm": "bm-Latn-ML", - "bmh": "bmh-Latn-ZZ", - "bmk": "bmk-Latn-ZZ", - "bmq": "bmq-Latn-ML", - "bmu": "bmu-Latn-ZZ", - "bn": "bn-Beng-BD", - "bng": "bng-Latn-ZZ", - "bnm": "bnm-Latn-ZZ", - "bnp": "bnp-Latn-ZZ", - "bo": "bo-Tibt-CN", - "boj": "boj-Latn-ZZ", - "bom": "bom-Latn-ZZ", - "bon": "bon-Latn-ZZ", - "bpy": "bpy-Beng-IN", - "bqc": "bqc-Latn-ZZ", - "bqi": "bqi-Arab-IR", - "bqp": "bqp-Latn-ZZ", - "bqv": "bqv-Latn-CI", - "br": "br-Latn-FR", - "bra": "bra-Deva-IN", - "brh": "brh-Arab-PK", - "brx": "brx-Deva-IN", - "brz": "brz-Latn-ZZ", - "bs": "bs-Latn-BA", - "bsj": "bsj-Latn-ZZ", - "bsq": "bsq-Bass-LR", - "bss": "bss-Latn-CM", - "bst": "bst-Ethi-ZZ", - "bto": "bto-Latn-PH", - "btt": "btt-Latn-ZZ", - "btv": "btv-Deva-PK", - "bua": "bua-Cyrl-RU", - "buc": "buc-Latn-YT", - "bud": "bud-Latn-ZZ", - "bug": "bug-Latn-ID", - "buk": "buk-Latn-ZZ", - "bum": "bum-Latn-CM", - "buo": "buo-Latn-ZZ", - "bus": "bus-Latn-ZZ", - "buu": "buu-Latn-ZZ", - "bvb": "bvb-Latn-GQ", - "bwd": "bwd-Latn-ZZ", - "bwr": "bwr-Latn-ZZ", - "bxh": "bxh-Latn-ZZ", - "bye": "bye-Latn-ZZ", - "byn": "byn-Ethi-ER", - "byr": "byr-Latn-ZZ", - "bys": "bys-Latn-ZZ", - "byv": "byv-Latn-CM", - "byx": "byx-Latn-ZZ", - "bza": "bza-Latn-ZZ", - "bze": "bze-Latn-ML", - "bzf": "bzf-Latn-ZZ", - "bzh": "bzh-Latn-ZZ", - "bzw": "bzw-Latn-ZZ", - "ca": "ca-Latn-ES", - "cad": "cad-Latn-US", - "can": "can-Latn-ZZ", - "cbj": "cbj-Latn-ZZ", - "cch": "cch-Latn-NG", - "ccp": "ccp-Cakm-BD", - "ce": "ce-Cyrl-RU", - "ceb": "ceb-Latn-PH", - "cfa": "cfa-Latn-ZZ", - "cgg": "cgg-Latn-UG", - "ch": "ch-Latn-GU", - "chk": "chk-Latn-FM", - "chm": "chm-Cyrl-RU", - "cho": "cho-Latn-US", - "chp": "chp-Latn-CA", - "chr": "chr-Cher-US", - "cic": "cic-Latn-US", - "cja": "cja-Arab-KH", - "cjm": "cjm-Cham-VN", - "cjv": "cjv-Latn-ZZ", - "ckb": "ckb-Arab-IQ", - "ckl": "ckl-Latn-ZZ", - "cko": "cko-Latn-ZZ", - "cky": "cky-Latn-ZZ", - "cla": "cla-Latn-ZZ", - "cme": "cme-Latn-ZZ", - "cmg": "cmg-Soyo-MN", - "co": "co-Latn-FR", - "cop": "cop-Copt-EG", - "cps": "cps-Latn-PH", - "cr": "cr-Cans-CA", - "crh": "crh-Cyrl-UA", - "crj": "crj-Cans-CA", - "crk": "crk-Cans-CA", - "crl": "crl-Cans-CA", - "crm": "crm-Cans-CA", - "crs": "crs-Latn-SC", - "cs": "cs-Latn-CZ", - "csb": "csb-Latn-PL", - "csw": "csw-Cans-CA", - "ctd": "ctd-Pauc-MM", - "cu": "cu-Cyrl-RU", - "cu-Glag": "cu-Glag-BG", - "cv": "cv-Cyrl-RU", - "cy": "cy-Latn-GB", - "da": "da-Latn-DK", - "dad": "dad-Latn-ZZ", - "daf": "daf-Latn-CI", - "dag": "dag-Latn-ZZ", - "dah": "dah-Latn-ZZ", - "dak": "dak-Latn-US", - "dar": "dar-Cyrl-RU", - "dav": "dav-Latn-KE", - "dbd": "dbd-Latn-ZZ", - "dbq": "dbq-Latn-ZZ", - "dcc": "dcc-Arab-IN", - "ddn": "ddn-Latn-ZZ", - "de": "de-Latn-DE", - "ded": "ded-Latn-ZZ", - "den": "den-Latn-CA", - "dga": "dga-Latn-ZZ", - "dgh": "dgh-Latn-ZZ", - "dgi": "dgi-Latn-ZZ", - "dgl": "dgl-Arab-ZZ", - "dgr": "dgr-Latn-CA", - "dgz": "dgz-Latn-ZZ", - "dia": "dia-Latn-ZZ", - "dje": "dje-Latn-NE", - "dmf": "dmf-Medf-NG", - "dnj": "dnj-Latn-CI", - "dob": "dob-Latn-ZZ", - "doi": "doi-Deva-IN", - "dop": "dop-Latn-ZZ", - "dow": "dow-Latn-ZZ", - "drh": "drh-Mong-CN", - "dri": "dri-Latn-ZZ", - "drs": "drs-Ethi-ZZ", - "dsb": "dsb-Latn-DE", - "dtm": "dtm-Latn-ML", - "dtp": "dtp-Latn-MY", - "dts": "dts-Latn-ZZ", - "dty": "dty-Deva-NP", - "dua": "dua-Latn-CM", - "duc": "duc-Latn-ZZ", - "dud": "dud-Latn-ZZ", - "dug": "dug-Latn-ZZ", - "dv": "dv-Thaa-MV", - "dva": "dva-Latn-ZZ", - "dww": "dww-Latn-ZZ", - "dyo": "dyo-Latn-SN", - "dyu": "dyu-Latn-BF", - "dz": "dz-Tibt-BT", - "dzg": "dzg-Latn-ZZ", - "ebu": "ebu-Latn-KE", - "ee": "ee-Latn-GH", - "efi": "efi-Latn-NG", - "egl": "egl-Latn-IT", - "egy": "egy-Egyp-EG", - "eka": "eka-Latn-ZZ", - "eky": "eky-Kali-MM", - "el": "el-Grek-GR", - "ema": "ema-Latn-ZZ", - "emi": "emi-Latn-ZZ", - "en": "en-Latn-US", - "en-Shaw": "en-Shaw-GB", - "enn": "enn-Latn-ZZ", - "enq": "enq-Latn-ZZ", - "eo": "eo-Latn-001", - "eri": "eri-Latn-ZZ", - "es": "es-Latn-ES", - "esg": "esg-Gonm-IN", - "esu": "esu-Latn-US", - "et": "et-Latn-EE", - "etr": "etr-Latn-ZZ", - "ett": "ett-Ital-IT", - "etu": "etu-Latn-ZZ", - "etx": "etx-Latn-ZZ", - "eu": "eu-Latn-ES", - "ewo": "ewo-Latn-CM", - "ext": "ext-Latn-ES", - "eza": "eza-Latn-ZZ", - "fa": "fa-Arab-IR", - "faa": "faa-Latn-ZZ", - "fab": "fab-Latn-ZZ", - "fag": "fag-Latn-ZZ", - "fai": "fai-Latn-ZZ", - "fan": "fan-Latn-GQ", - "ff": "ff-Latn-SN", - "ff-Adlm": "ff-Adlm-GN", - "ffi": "ffi-Latn-ZZ", - "ffm": "ffm-Latn-ML", - "fi": "fi-Latn-FI", - "fia": "fia-Arab-SD", - "fil": "fil-Latn-PH", - "fit": "fit-Latn-SE", - "fj": "fj-Latn-FJ", - "flr": "flr-Latn-ZZ", - "fmp": "fmp-Latn-ZZ", - "fo": "fo-Latn-FO", - "fod": "fod-Latn-ZZ", - "fon": "fon-Latn-BJ", - "for": "for-Latn-ZZ", - "fpe": "fpe-Latn-ZZ", - "fqs": "fqs-Latn-ZZ", - "fr": "fr-Latn-FR", - "frc": "frc-Latn-US", - "frp": "frp-Latn-FR", - "frr": "frr-Latn-DE", - "frs": "frs-Latn-DE", - "fub": "fub-Arab-CM", - "fud": "fud-Latn-WF", - "fue": "fue-Latn-ZZ", - "fuf": "fuf-Latn-GN", - "fuh": "fuh-Latn-ZZ", - "fuq": "fuq-Latn-NE", - "fur": "fur-Latn-IT", - "fuv": "fuv-Latn-NG", - "fuy": "fuy-Latn-ZZ", - "fvr": "fvr-Latn-SD", - "fy": "fy-Latn-NL", - "ga": "ga-Latn-IE", - "gaa": "gaa-Latn-GH", - "gaf": "gaf-Latn-ZZ", - "gag": "gag-Latn-MD", - "gah": "gah-Latn-ZZ", - "gaj": "gaj-Latn-ZZ", - "gam": "gam-Latn-ZZ", - "gan": "gan-Hans-CN", - "gaw": "gaw-Latn-ZZ", - "gay": "gay-Latn-ID", - "gba": "gba-Latn-ZZ", - "gbf": "gbf-Latn-ZZ", - "gbm": "gbm-Deva-IN", - "gby": "gby-Latn-ZZ", - "gbz": "gbz-Arab-IR", - "gcr": "gcr-Latn-GF", - "gd": "gd-Latn-GB", - "gde": "gde-Latn-ZZ", - "gdn": "gdn-Latn-ZZ", - "gdr": "gdr-Latn-ZZ", - "geb": "geb-Latn-ZZ", - "gej": "gej-Latn-ZZ", - "gel": "gel-Latn-ZZ", - "gez": "gez-Ethi-ET", - "gfk": "gfk-Latn-ZZ", - "ggn": "ggn-Deva-NP", - "ghs": "ghs-Latn-ZZ", - "gil": "gil-Latn-KI", - "gim": "gim-Latn-ZZ", - "gjk": "gjk-Arab-PK", - "gjn": "gjn-Latn-ZZ", - "gju": "gju-Arab-PK", - "gkn": "gkn-Latn-ZZ", - "gkp": "gkp-Latn-ZZ", - "gl": "gl-Latn-ES", - "glk": "glk-Arab-IR", - "gmm": "gmm-Latn-ZZ", - "gmv": "gmv-Ethi-ZZ", - "gn": "gn-Latn-PY", - "gnd": "gnd-Latn-ZZ", - "gng": "gng-Latn-ZZ", - "god": "god-Latn-ZZ", - "gof": "gof-Ethi-ZZ", - "goi": "goi-Latn-ZZ", - "gom": "gom-Deva-IN", - "gon": "gon-Telu-IN", - "gor": "gor-Latn-ID", - "gos": "gos-Latn-NL", - "got": "got-Goth-UA", - "grb": "grb-Latn-ZZ", - "grc": "grc-Cprt-CY", - "grc-Linb": "grc-Linb-GR", - "grt": "grt-Beng-IN", - "grw": "grw-Latn-ZZ", - "gsw": "gsw-Latn-CH", - "gu": "gu-Gujr-IN", - "gub": "gub-Latn-BR", - "guc": "guc-Latn-CO", - "gud": "gud-Latn-ZZ", - "gur": "gur-Latn-GH", - "guw": "guw-Latn-ZZ", - "gux": "gux-Latn-ZZ", - "guz": "guz-Latn-KE", - "gv": "gv-Latn-IM", - "gvf": "gvf-Latn-ZZ", - "gvr": "gvr-Deva-NP", - "gvs": "gvs-Latn-ZZ", - "gwc": "gwc-Arab-ZZ", - "gwi": "gwi-Latn-CA", - "gwt": "gwt-Arab-ZZ", - "gyi": "gyi-Latn-ZZ", - "ha": "ha-Latn-NG", - "ha-CM": "ha-Arab-CM", - "ha-SD": "ha-Arab-SD", - "hag": "hag-Latn-ZZ", - "hak": "hak-Hans-CN", - "ham": "ham-Latn-ZZ", - "haw": "haw-Latn-US", - "haz": "haz-Arab-AF", - "hbb": "hbb-Latn-ZZ", - "hdy": "hdy-Ethi-ZZ", - "he": "he-Hebr-IL", - "hhy": "hhy-Latn-ZZ", - "hi": "hi-Deva-IN", - "hia": "hia-Latn-ZZ", - "hif": "hif-Latn-FJ", - "hig": "hig-Latn-ZZ", - "hih": "hih-Latn-ZZ", - "hil": "hil-Latn-PH", - "hla": "hla-Latn-ZZ", - "hlu": "hlu-Hluw-TR", - "hmd": "hmd-Plrd-CN", - "hmt": "hmt-Latn-ZZ", - "hnd": "hnd-Arab-PK", - "hne": "hne-Deva-IN", - "hnj": "hnj-Hmnp-US", - "hnn": "hnn-Latn-PH", - "hno": "hno-Arab-PK", - "ho": "ho-Latn-PG", - "hoc": "hoc-Deva-IN", - "hoj": "hoj-Deva-IN", - "hot": "hot-Latn-ZZ", - "hr": "hr-Latn-HR", - "hsb": "hsb-Latn-DE", - "hsn": "hsn-Hans-CN", - "ht": "ht-Latn-HT", - "hu": "hu-Latn-HU", - "hui": "hui-Latn-ZZ", - "hy": "hy-Armn-AM", - "hz": "hz-Latn-NA", - "ia": "ia-Latn-001", - "ian": "ian-Latn-ZZ", - "iar": "iar-Latn-ZZ", - "iba": "iba-Latn-MY", - "ibb": "ibb-Latn-NG", - "iby": "iby-Latn-ZZ", - "ica": "ica-Latn-ZZ", - "ich": "ich-Latn-ZZ", - "id": "id-Latn-ID", - "idd": "idd-Latn-ZZ", - "idi": "idi-Latn-ZZ", - "idu": "idu-Latn-ZZ", - "ife": "ife-Latn-TG", - "ig": "ig-Latn-NG", - "igb": "igb-Latn-ZZ", - "ige": "ige-Latn-ZZ", - "ii": "ii-Yiii-CN", - "ijj": "ijj-Latn-ZZ", - "ik": "ik-Latn-US", - "ikk": "ikk-Latn-ZZ", - "ikt": "ikt-Latn-CA", - "ikw": "ikw-Latn-ZZ", - "ikx": "ikx-Latn-ZZ", - "ilo": "ilo-Latn-PH", - "imo": "imo-Latn-ZZ", - "in": "in-Latn-ID", - "inh": "inh-Cyrl-RU", - "io": "io-Latn-001", - "iou": "iou-Latn-ZZ", - "iri": "iri-Latn-ZZ", - "is": "is-Latn-IS", - "it": "it-Latn-IT", - "iu": "iu-Cans-CA", - "iw": "iw-Hebr-IL", - "iwm": "iwm-Latn-ZZ", - "iws": "iws-Latn-ZZ", - "izh": "izh-Latn-RU", - "izi": "izi-Latn-ZZ", - "ja": "ja-Jpan-JP", - "jab": "jab-Latn-ZZ", - "jam": "jam-Latn-JM", - "jar": "jar-Latn-ZZ", - "jbo": "jbo-Latn-001", - "jbu": "jbu-Latn-ZZ", - "jen": "jen-Latn-ZZ", - "jgk": "jgk-Latn-ZZ", - "jgo": "jgo-Latn-CM", - "ji": "ji-Hebr-UA", - "jib": "jib-Latn-ZZ", - "jmc": "jmc-Latn-TZ", - "jml": "jml-Deva-NP", - "jra": "jra-Latn-ZZ", - "jut": "jut-Latn-DK", - "jv": "jv-Latn-ID", - "jw": "jw-Latn-ID", - "ka": "ka-Geor-GE", - "kaa": "kaa-Cyrl-UZ", - "kab": "kab-Latn-DZ", - "kac": "kac-Latn-MM", - "kad": "kad-Latn-ZZ", - "kai": "kai-Latn-ZZ", - "kaj": "kaj-Latn-NG", - "kam": "kam-Latn-KE", - "kao": "kao-Latn-ML", - "kbd": "kbd-Cyrl-RU", - "kbm": "kbm-Latn-ZZ", - "kbp": "kbp-Latn-ZZ", - "kbq": "kbq-Latn-ZZ", - "kbx": "kbx-Latn-ZZ", - "kby": "kby-Arab-NE", - "kcg": "kcg-Latn-NG", - "kck": "kck-Latn-ZW", - "kcl": "kcl-Latn-ZZ", - "kct": "kct-Latn-ZZ", - "kde": "kde-Latn-TZ", - "kdh": "kdh-Latn-TG", - "kdl": "kdl-Latn-ZZ", - "kdt": "kdt-Thai-TH", - "kea": "kea-Latn-CV", - "ken": "ken-Latn-CM", - "kez": "kez-Latn-ZZ", - "kfo": "kfo-Latn-CI", - "kfr": "kfr-Deva-IN", - "kfy": "kfy-Deva-IN", - "kg": "kg-Latn-CD", - "kge": "kge-Latn-ID", - "kgf": "kgf-Latn-ZZ", - "kgp": "kgp-Latn-BR", - "kha": "kha-Latn-IN", - "khb": "khb-Talu-CN", - "khn": "khn-Deva-IN", - "khq": "khq-Latn-ML", - "khs": "khs-Latn-ZZ", - "kht": "kht-Mymr-IN", - "khw": "khw-Arab-PK", - "khz": "khz-Latn-ZZ", - "ki": "ki-Latn-KE", - "kij": "kij-Latn-ZZ", - "kiu": "kiu-Latn-TR", - "kiw": "kiw-Latn-ZZ", - "kj": "kj-Latn-NA", - "kjd": "kjd-Latn-ZZ", - "kjg": "kjg-Laoo-LA", - "kjs": "kjs-Latn-ZZ", - "kjy": "kjy-Latn-ZZ", - "kk": "kk-Cyrl-KZ", - "kk-AF": "kk-Arab-AF", - "kk-Arab": "kk-Arab-CN", - "kk-CN": "kk-Arab-CN", - "kk-IR": "kk-Arab-IR", - "kk-MN": "kk-Arab-MN", - "kkc": "kkc-Latn-ZZ", - "kkj": "kkj-Latn-CM", - "kl": "kl-Latn-GL", - "kln": "kln-Latn-KE", - "klq": "klq-Latn-ZZ", - "klt": "klt-Latn-ZZ", - "klx": "klx-Latn-ZZ", - "km": "km-Khmr-KH", - "kmb": "kmb-Latn-AO", - "kmh": "kmh-Latn-ZZ", - "kmo": "kmo-Latn-ZZ", - "kms": "kms-Latn-ZZ", - "kmu": "kmu-Latn-ZZ", - "kmw": "kmw-Latn-ZZ", - "kn": "kn-Knda-IN", - "knf": "knf-Latn-GW", - "knp": "knp-Latn-ZZ", - "ko": "ko-Kore-KR", - "koi": "koi-Cyrl-RU", - "kok": "kok-Deva-IN", - "kol": "kol-Latn-ZZ", - "kos": "kos-Latn-FM", - "koz": "koz-Latn-ZZ", - "kpe": "kpe-Latn-LR", - "kpf": "kpf-Latn-ZZ", - "kpo": "kpo-Latn-ZZ", - "kpr": "kpr-Latn-ZZ", - "kpx": "kpx-Latn-ZZ", - "kqb": "kqb-Latn-ZZ", - "kqf": "kqf-Latn-ZZ", - "kqs": "kqs-Latn-ZZ", - "kqy": "kqy-Ethi-ZZ", - "kr": "kr-Latn-ZZ", - "krc": "krc-Cyrl-RU", - "kri": "kri-Latn-SL", - "krj": "krj-Latn-PH", - "krl": "krl-Latn-RU", - "krs": "krs-Latn-ZZ", - "kru": "kru-Deva-IN", - "ks": "ks-Arab-IN", - "ksb": "ksb-Latn-TZ", - "ksd": "ksd-Latn-ZZ", - "ksf": "ksf-Latn-CM", - "ksh": "ksh-Latn-DE", - "ksj": "ksj-Latn-ZZ", - "ksr": "ksr-Latn-ZZ", - "ktb": "ktb-Ethi-ZZ", - "ktm": "ktm-Latn-ZZ", - "kto": "kto-Latn-ZZ", - "ktr": "ktr-Latn-MY", - "ku": "ku-Latn-TR", - "ku-Arab": "ku-Arab-IQ", - "ku-LB": "ku-Arab-LB", - "ku-Yezi": "ku-Yezi-GE", - "kub": "kub-Latn-ZZ", - "kud": "kud-Latn-ZZ", - "kue": "kue-Latn-ZZ", - "kuj": "kuj-Latn-ZZ", - "kum": "kum-Cyrl-RU", - "kun": "kun-Latn-ZZ", - "kup": "kup-Latn-ZZ", - "kus": "kus-Latn-ZZ", - "kv": "kv-Cyrl-RU", - "kvg": "kvg-Latn-ZZ", - "kvr": "kvr-Latn-ID", - "kvx": "kvx-Arab-PK", - "kw": "kw-Latn-GB", - "kwj": "kwj-Latn-ZZ", - "kwo": "kwo-Latn-ZZ", - "kwq": "kwq-Latn-ZZ", - "kxa": "kxa-Latn-ZZ", - "kxc": "kxc-Ethi-ZZ", - "kxe": "kxe-Latn-ZZ", - "kxl": "kxl-Deva-IN", - "kxm": "kxm-Thai-TH", - "kxp": "kxp-Arab-PK", - "kxw": "kxw-Latn-ZZ", - "kxz": "kxz-Latn-ZZ", - "ky": "ky-Cyrl-KG", - "ky-Arab": "ky-Arab-CN", - "ky-CN": "ky-Arab-CN", - "ky-Latn": "ky-Latn-TR", - "ky-TR": "ky-Latn-TR", - "kye": "kye-Latn-ZZ", - "kyx": "kyx-Latn-ZZ", - "kzh": "kzh-Arab-ZZ", - "kzj": "kzj-Latn-MY", - "kzr": "kzr-Latn-ZZ", - "kzt": "kzt-Latn-MY", - "la": "la-Latn-VA", - "lab": "lab-Lina-GR", - "lad": "lad-Hebr-IL", - "lag": "lag-Latn-TZ", - "lah": "lah-Arab-PK", - "laj": "laj-Latn-UG", - "las": "las-Latn-ZZ", - "lb": "lb-Latn-LU", - "lbe": "lbe-Cyrl-RU", - "lbu": "lbu-Latn-ZZ", - "lbw": "lbw-Latn-ID", - "lcm": "lcm-Latn-ZZ", - "lcp": "lcp-Thai-CN", - "ldb": "ldb-Latn-ZZ", - "led": "led-Latn-ZZ", - "lee": "lee-Latn-ZZ", - "lem": "lem-Latn-ZZ", - "lep": "lep-Lepc-IN", - "leq": "leq-Latn-ZZ", - "leu": "leu-Latn-ZZ", - "lez": "lez-Cyrl-RU", - "lg": "lg-Latn-UG", - "lgg": "lgg-Latn-ZZ", - "li": "li-Latn-NL", - "lia": "lia-Latn-ZZ", - "lid": "lid-Latn-ZZ", - "lif": "lif-Deva-NP", - "lif-Limb": "lif-Limb-IN", - "lig": "lig-Latn-ZZ", - "lih": "lih-Latn-ZZ", - "lij": "lij-Latn-IT", - "lis": "lis-Lisu-CN", - "ljp": "ljp-Latn-ID", - "lki": "lki-Arab-IR", - "lkt": "lkt-Latn-US", - "lle": "lle-Latn-ZZ", - "lln": "lln-Latn-ZZ", - "lmn": "lmn-Telu-IN", - "lmo": "lmo-Latn-IT", - "lmp": "lmp-Latn-ZZ", - "ln": "ln-Latn-CD", - "lns": "lns-Latn-ZZ", - "lnu": "lnu-Latn-ZZ", - "lo": "lo-Laoo-LA", - "loj": "loj-Latn-ZZ", - "lok": "lok-Latn-ZZ", - "lol": "lol-Latn-CD", - "lor": "lor-Latn-ZZ", - "los": "los-Latn-ZZ", - "loz": "loz-Latn-ZM", - "lrc": "lrc-Arab-IR", - "lt": "lt-Latn-LT", - "ltg": "ltg-Latn-LV", - "lu": "lu-Latn-CD", - "lua": "lua-Latn-CD", - "luo": "luo-Latn-KE", - "luy": "luy-Latn-KE", - "luz": "luz-Arab-IR", - "lv": "lv-Latn-LV", - "lwl": "lwl-Thai-TH", - "lzh": "lzh-Hans-CN", - "lzz": "lzz-Latn-TR", - "mad": "mad-Latn-ID", - "maf": "maf-Latn-CM", - "mag": "mag-Deva-IN", - "mai": "mai-Deva-IN", - "mak": "mak-Latn-ID", - "man": "man-Latn-GM", - "man-GN": "man-Nkoo-GN", - "man-Nkoo": "man-Nkoo-GN", - "mas": "mas-Latn-KE", - "maw": "maw-Latn-ZZ", - "maz": "maz-Latn-MX", - "mbh": "mbh-Latn-ZZ", - "mbo": "mbo-Latn-ZZ", - "mbq": "mbq-Latn-ZZ", - "mbu": "mbu-Latn-ZZ", - "mbw": "mbw-Latn-ZZ", - "mci": "mci-Latn-ZZ", - "mcp": "mcp-Latn-ZZ", - "mcq": "mcq-Latn-ZZ", - "mcr": "mcr-Latn-ZZ", - "mcu": "mcu-Latn-ZZ", - "mda": "mda-Latn-ZZ", - "mde": "mde-Arab-ZZ", - "mdf": "mdf-Cyrl-RU", - "mdh": "mdh-Latn-PH", - "mdj": "mdj-Latn-ZZ", - "mdr": "mdr-Latn-ID", - "mdx": "mdx-Ethi-ZZ", - "med": "med-Latn-ZZ", - "mee": "mee-Latn-ZZ", - "mek": "mek-Latn-ZZ", - "men": "men-Latn-SL", - "mer": "mer-Latn-KE", - "met": "met-Latn-ZZ", - "meu": "meu-Latn-ZZ", - "mfa": "mfa-Arab-TH", - "mfe": "mfe-Latn-MU", - "mfn": "mfn-Latn-ZZ", - "mfo": "mfo-Latn-ZZ", - "mfq": "mfq-Latn-ZZ", - "mg": "mg-Latn-MG", - "mgh": "mgh-Latn-MZ", - "mgl": "mgl-Latn-ZZ", - "mgo": "mgo-Latn-CM", - "mgp": "mgp-Deva-NP", - "mgy": "mgy-Latn-TZ", - "mh": "mh-Latn-MH", - "mhi": "mhi-Latn-ZZ", - "mhl": "mhl-Latn-ZZ", - "mi": "mi-Latn-NZ", - "mif": "mif-Latn-ZZ", - "min": "min-Latn-ID", - "miw": "miw-Latn-ZZ", - "mk": "mk-Cyrl-MK", - "mki": "mki-Arab-ZZ", - "mkl": "mkl-Latn-ZZ", - "mkp": "mkp-Latn-ZZ", - "mkw": "mkw-Latn-ZZ", - "ml": "ml-Mlym-IN", - "mle": "mle-Latn-ZZ", - "mlp": "mlp-Latn-ZZ", - "mls": "mls-Latn-SD", - "mmo": "mmo-Latn-ZZ", - "mmu": "mmu-Latn-ZZ", - "mmx": "mmx-Latn-ZZ", - "mn": "mn-Cyrl-MN", - "mn-CN": "mn-Mong-CN", - "mn-Mong": "mn-Mong-CN", - "mna": "mna-Latn-ZZ", - "mnf": "mnf-Latn-ZZ", - "mni": "mni-Beng-IN", - "mnw": "mnw-Mymr-MM", - "mo": "mo-Latn-RO", - "moa": "moa-Latn-ZZ", - "moe": "moe-Latn-CA", - "moh": "moh-Latn-CA", - "mos": "mos-Latn-BF", - "mox": "mox-Latn-ZZ", - "mpp": "mpp-Latn-ZZ", - "mps": "mps-Latn-ZZ", - "mpt": "mpt-Latn-ZZ", - "mpx": "mpx-Latn-ZZ", - "mql": "mql-Latn-ZZ", - "mr": "mr-Deva-IN", - "mrd": "mrd-Deva-NP", - "mrj": "mrj-Cyrl-RU", - "mro": "mro-Mroo-BD", - "ms": "ms-Latn-MY", - "ms-CC": "ms-Arab-CC", - "mt": "mt-Latn-MT", - "mtc": "mtc-Latn-ZZ", - "mtf": "mtf-Latn-ZZ", - "mti": "mti-Latn-ZZ", - "mtr": "mtr-Deva-IN", - "mua": "mua-Latn-CM", - "mur": "mur-Latn-ZZ", - "mus": "mus-Latn-US", - "mva": "mva-Latn-ZZ", - "mvn": "mvn-Latn-ZZ", - "mvy": "mvy-Arab-PK", - "mwk": "mwk-Latn-ML", - "mwr": "mwr-Deva-IN", - "mwv": "mwv-Latn-ID", - "mww": "mww-Hmnp-US", - "mxc": "mxc-Latn-ZW", - "mxm": "mxm-Latn-ZZ", - "my": "my-Mymr-MM", - "myk": "myk-Latn-ZZ", - "mym": "mym-Ethi-ZZ", - "myv": "myv-Cyrl-RU", - "myw": "myw-Latn-ZZ", - "myx": "myx-Latn-UG", - "myz": "myz-Mand-IR", - "mzk": "mzk-Latn-ZZ", - "mzm": "mzm-Latn-ZZ", - "mzn": "mzn-Arab-IR", - "mzp": "mzp-Latn-ZZ", - "mzw": "mzw-Latn-ZZ", - "mzz": "mzz-Latn-ZZ", - "na": "na-Latn-NR", - "nac": "nac-Latn-ZZ", - "naf": "naf-Latn-ZZ", - "nak": "nak-Latn-ZZ", - "nan": "nan-Hans-CN", - "nap": "nap-Latn-IT", - "naq": "naq-Latn-NA", - "nas": "nas-Latn-ZZ", - "nb": "nb-Latn-NO", - "nca": "nca-Latn-ZZ", - "nce": "nce-Latn-ZZ", - "ncf": "ncf-Latn-ZZ", - "nch": "nch-Latn-MX", - "nco": "nco-Latn-ZZ", - "ncu": "ncu-Latn-ZZ", - "nd": "nd-Latn-ZW", - "ndc": "ndc-Latn-MZ", - "nds": "nds-Latn-DE", - "ne": "ne-Deva-NP", - "neb": "neb-Latn-ZZ", - "new": "new-Deva-NP", - "nex": "nex-Latn-ZZ", - "nfr": "nfr-Latn-ZZ", - "ng": "ng-Latn-NA", - "nga": "nga-Latn-ZZ", - "ngb": "ngb-Latn-ZZ", - "ngl": "ngl-Latn-MZ", - "nhb": "nhb-Latn-ZZ", - "nhe": "nhe-Latn-MX", - "nhw": "nhw-Latn-MX", - "nif": "nif-Latn-ZZ", - "nii": "nii-Latn-ZZ", - "nij": "nij-Latn-ID", - "nin": "nin-Latn-ZZ", - "niu": "niu-Latn-NU", - "niy": "niy-Latn-ZZ", - "niz": "niz-Latn-ZZ", - "njo": "njo-Latn-IN", - "nkg": "nkg-Latn-ZZ", - "nko": "nko-Latn-ZZ", - "nl": "nl-Latn-NL", - "nmg": "nmg-Latn-CM", - "nmz": "nmz-Latn-ZZ", - "nn": "nn-Latn-NO", - "nnf": "nnf-Latn-ZZ", - "nnh": "nnh-Latn-CM", - "nnk": "nnk-Latn-ZZ", - "nnm": "nnm-Latn-ZZ", - "nnp": "nnp-Wcho-IN", - "no": "no-Latn-NO", - "nod": "nod-Lana-TH", - "noe": "noe-Deva-IN", - "non": "non-Runr-SE", - "nop": "nop-Latn-ZZ", - "nou": "nou-Latn-ZZ", - "nqo": "nqo-Nkoo-GN", - "nr": "nr-Latn-ZA", - "nrb": "nrb-Latn-ZZ", - "nsk": "nsk-Cans-CA", - "nsn": "nsn-Latn-ZZ", - "nso": "nso-Latn-ZA", - "nss": "nss-Latn-ZZ", - "nst": "nst-Tnsa-IN", - "ntm": "ntm-Latn-ZZ", - "ntr": "ntr-Latn-ZZ", - "nui": "nui-Latn-ZZ", - "nup": "nup-Latn-ZZ", - "nus": "nus-Latn-SS", - "nuv": "nuv-Latn-ZZ", - "nux": "nux-Latn-ZZ", - "nv": "nv-Latn-US", - "nwb": "nwb-Latn-ZZ", - "nxq": "nxq-Latn-CN", - "nxr": "nxr-Latn-ZZ", - "ny": "ny-Latn-MW", - "nym": "nym-Latn-TZ", - "nyn": "nyn-Latn-UG", - "nzi": "nzi-Latn-GH", - "oc": "oc-Latn-FR", - "ogc": "ogc-Latn-ZZ", - "okr": "okr-Latn-ZZ", - "okv": "okv-Latn-ZZ", - "om": "om-Latn-ET", - "ong": "ong-Latn-ZZ", - "onn": "onn-Latn-ZZ", - "ons": "ons-Latn-ZZ", - "opm": "opm-Latn-ZZ", - "or": "or-Orya-IN", - "oro": "oro-Latn-ZZ", - "oru": "oru-Arab-ZZ", - "os": "os-Cyrl-GE", - "osa": "osa-Osge-US", - "ota": "ota-Arab-ZZ", - "otk": "otk-Orkh-MN", - "oui": "oui-Ougr-143", - "ozm": "ozm-Latn-ZZ", - "pa": "pa-Guru-IN", - "pa-Arab": "pa-Arab-PK", - "pa-PK": "pa-Arab-PK", - "pag": "pag-Latn-PH", - "pal": "pal-Phli-IR", - "pal-Phlp": "pal-Phlp-CN", - "pam": "pam-Latn-PH", - "pap": "pap-Latn-AW", - "pau": "pau-Latn-PW", - "pbi": "pbi-Latn-ZZ", - "pcd": "pcd-Latn-FR", - "pcm": "pcm-Latn-NG", - "pdc": "pdc-Latn-US", - "pdt": "pdt-Latn-CA", - "ped": "ped-Latn-ZZ", - "peo": "peo-Xpeo-IR", - "pex": "pex-Latn-ZZ", - "pfl": "pfl-Latn-DE", - "phl": "phl-Arab-ZZ", - "phn": "phn-Phnx-LB", - "pil": "pil-Latn-ZZ", - "pip": "pip-Latn-ZZ", - "pka": "pka-Brah-IN", - "pko": "pko-Latn-KE", - "pl": "pl-Latn-PL", - "pla": "pla-Latn-ZZ", - "pms": "pms-Latn-IT", - "png": "png-Latn-ZZ", - "pnn": "pnn-Latn-ZZ", - "pnt": "pnt-Grek-GR", - "pon": "pon-Latn-FM", - "ppa": "ppa-Deva-IN", - "ppo": "ppo-Latn-ZZ", - "pra": "pra-Khar-PK", - "prd": "prd-Arab-IR", - "prg": "prg-Latn-001", - "ps": "ps-Arab-AF", - "pss": "pss-Latn-ZZ", - "pt": "pt-Latn-BR", - "ptp": "ptp-Latn-ZZ", - "puu": "puu-Latn-GA", - "pwa": "pwa-Latn-ZZ", - "qu": "qu-Latn-PE", - "quc": "quc-Latn-GT", - "qug": "qug-Latn-EC", - "rai": "rai-Latn-ZZ", - "raj": "raj-Deva-IN", - "rao": "rao-Latn-ZZ", - "rcf": "rcf-Latn-RE", - "rej": "rej-Latn-ID", - "rel": "rel-Latn-ZZ", - "res": "res-Latn-ZZ", - "rgn": "rgn-Latn-IT", - "rhg": "rhg-Rohg-MM", - "ria": "ria-Latn-IN", - "rif": "rif-Tfng-MA", - "rif-NL": "rif-Latn-NL", - "rjs": "rjs-Deva-NP", - "rkt": "rkt-Beng-BD", - "rm": "rm-Latn-CH", - "rmf": "rmf-Latn-FI", - "rmo": "rmo-Latn-CH", - "rmt": "rmt-Arab-IR", - "rmu": "rmu-Latn-SE", - "rn": "rn-Latn-BI", - "rna": "rna-Latn-ZZ", - "rng": "rng-Latn-MZ", - "ro": "ro-Latn-RO", - "rob": "rob-Latn-ID", - "rof": "rof-Latn-TZ", - "roo": "roo-Latn-ZZ", - "rro": "rro-Latn-ZZ", - "rtm": "rtm-Latn-FJ", - "ru": "ru-Cyrl-RU", - "rue": "rue-Cyrl-UA", - "rug": "rug-Latn-SB", - "rw": "rw-Latn-RW", - "rwk": "rwk-Latn-TZ", - "rwo": "rwo-Latn-ZZ", - "ryu": "ryu-Kana-JP", - "sa": "sa-Deva-IN", - "saf": "saf-Latn-GH", - "sah": "sah-Cyrl-RU", - "saq": "saq-Latn-KE", - "sas": "sas-Latn-ID", - "sat": "sat-Olck-IN", - "sav": "sav-Latn-SN", - "saz": "saz-Saur-IN", - "sba": "sba-Latn-ZZ", - "sbe": "sbe-Latn-ZZ", - "sbp": "sbp-Latn-TZ", - "sc": "sc-Latn-IT", - "sck": "sck-Deva-IN", - "scl": "scl-Arab-ZZ", - "scn": "scn-Latn-IT", - "sco": "sco-Latn-GB", - "scs": "scs-Latn-CA", - "sd": "sd-Arab-PK", - "sd-Deva": "sd-Deva-IN", - "sd-Khoj": "sd-Khoj-IN", - "sd-Sind": "sd-Sind-IN", - "sdc": "sdc-Latn-IT", - "sdh": "sdh-Arab-IR", - "se": "se-Latn-NO", - "sef": "sef-Latn-CI", - "seh": "seh-Latn-MZ", - "sei": "sei-Latn-MX", - "ses": "ses-Latn-ML", - "sg": "sg-Latn-CF", - "sga": "sga-Ogam-IE", - "sgs": "sgs-Latn-LT", - "sgw": "sgw-Ethi-ZZ", - "sgz": "sgz-Latn-ZZ", - "shi": "shi-Tfng-MA", - "shk": "shk-Latn-ZZ", - "shn": "shn-Mymr-MM", - "shu": "shu-Arab-ZZ", - "si": "si-Sinh-LK", - "sid": "sid-Latn-ET", - "sig": "sig-Latn-ZZ", - "sil": "sil-Latn-ZZ", - "sim": "sim-Latn-ZZ", - "sjr": "sjr-Latn-ZZ", - "sk": "sk-Latn-SK", - "skc": "skc-Latn-ZZ", - "skr": "skr-Arab-PK", - "sks": "sks-Latn-ZZ", - "sl": "sl-Latn-SI", - "sld": "sld-Latn-ZZ", - "sli": "sli-Latn-PL", - "sll": "sll-Latn-ZZ", - "sly": "sly-Latn-ID", - "sm": "sm-Latn-WS", - "sma": "sma-Latn-SE", - "smj": "smj-Latn-SE", - "smn": "smn-Latn-FI", - "smp": "smp-Samr-IL", - "smq": "smq-Latn-ZZ", - "sms": "sms-Latn-FI", - "sn": "sn-Latn-ZW", - "snc": "snc-Latn-ZZ", - "snk": "snk-Latn-ML", - "snp": "snp-Latn-ZZ", - "snx": "snx-Latn-ZZ", - "sny": "sny-Latn-ZZ", - "so": "so-Latn-SO", - "sog": "sog-Sogd-UZ", - "sok": "sok-Latn-ZZ", - "soq": "soq-Latn-ZZ", - "sou": "sou-Thai-TH", - "soy": "soy-Latn-ZZ", - "spd": "spd-Latn-ZZ", - "spl": "spl-Latn-ZZ", - "sps": "sps-Latn-ZZ", - "sq": "sq-Latn-AL", - "sr": "sr-Cyrl-RS", - "sr-ME": "sr-Latn-ME", - "sr-RO": "sr-Latn-RO", - "sr-RU": "sr-Latn-RU", - "sr-TR": "sr-Latn-TR", - "srb": "srb-Sora-IN", - "srn": "srn-Latn-SR", - "srr": "srr-Latn-SN", - "srx": "srx-Deva-IN", - "ss": "ss-Latn-ZA", - "ssd": "ssd-Latn-ZZ", - "ssg": "ssg-Latn-ZZ", - "ssy": "ssy-Latn-ER", - "st": "st-Latn-ZA", - "stk": "stk-Latn-ZZ", - "stq": "stq-Latn-DE", - "su": "su-Latn-ID", - "sua": "sua-Latn-ZZ", - "sue": "sue-Latn-ZZ", - "suk": "suk-Latn-TZ", - "sur": "sur-Latn-ZZ", - "sus": "sus-Latn-GN", - "sv": "sv-Latn-SE", - "sw": "sw-Latn-TZ", - "swb": "swb-Arab-YT", - "swc": "swc-Latn-CD", - "swg": "swg-Latn-DE", - "swp": "swp-Latn-ZZ", - "swv": "swv-Deva-IN", - "sxn": "sxn-Latn-ID", - "sxw": "sxw-Latn-ZZ", - "syl": "syl-Beng-BD", - "syr": "syr-Syrc-IQ", - "szl": "szl-Latn-PL", - "ta": "ta-Taml-IN", - "taj": "taj-Deva-NP", - "tal": "tal-Latn-ZZ", - "tan": "tan-Latn-ZZ", - "taq": "taq-Latn-ZZ", - "tbc": "tbc-Latn-ZZ", - "tbd": "tbd-Latn-ZZ", - "tbf": "tbf-Latn-ZZ", - "tbg": "tbg-Latn-ZZ", - "tbo": "tbo-Latn-ZZ", - "tbw": "tbw-Latn-PH", - "tbz": "tbz-Latn-ZZ", - "tci": "tci-Latn-ZZ", - "tcy": "tcy-Knda-IN", - "tdd": "tdd-Tale-CN", - "tdg": "tdg-Deva-NP", - "tdh": "tdh-Deva-NP", - "tdu": "tdu-Latn-MY", - "te": "te-Telu-IN", - "ted": "ted-Latn-ZZ", - "tem": "tem-Latn-SL", - "teo": "teo-Latn-UG", - "tet": "tet-Latn-TL", - "tfi": "tfi-Latn-ZZ", - "tg": "tg-Cyrl-TJ", - "tg-Arab": "tg-Arab-PK", - "tg-PK": "tg-Arab-PK", - "tgc": "tgc-Latn-ZZ", - "tgo": "tgo-Latn-ZZ", - "tgu": "tgu-Latn-ZZ", - "th": "th-Thai-TH", - "thl": "thl-Deva-NP", - "thq": "thq-Deva-NP", - "thr": "thr-Deva-NP", - "ti": "ti-Ethi-ET", - "tif": "tif-Latn-ZZ", - "tig": "tig-Ethi-ER", - "tik": "tik-Latn-ZZ", - "tim": "tim-Latn-ZZ", - "tio": "tio-Latn-ZZ", - "tiv": "tiv-Latn-NG", - "tk": "tk-Latn-TM", - "tkl": "tkl-Latn-TK", - "tkr": "tkr-Latn-AZ", - "tkt": "tkt-Deva-NP", - "tl": "tl-Latn-PH", - "tlf": "tlf-Latn-ZZ", - "tlx": "tlx-Latn-ZZ", - "tly": "tly-Latn-AZ", - "tmh": "tmh-Latn-NE", - "tmy": "tmy-Latn-ZZ", - "tn": "tn-Latn-ZA", - "tnh": "tnh-Latn-ZZ", - "to": "to-Latn-TO", - "tof": "tof-Latn-ZZ", - "tog": "tog-Latn-MW", - "toq": "toq-Latn-ZZ", - "tpi": "tpi-Latn-PG", - "tpm": "tpm-Latn-ZZ", - "tpz": "tpz-Latn-ZZ", - "tqo": "tqo-Latn-ZZ", - "tr": "tr-Latn-TR", - "tru": "tru-Latn-TR", - "trv": "trv-Latn-TW", - "trw": "trw-Arab-PK", - "ts": "ts-Latn-ZA", - "tsd": "tsd-Grek-GR", - "tsf": "tsf-Deva-NP", - "tsg": "tsg-Latn-PH", - "tsj": "tsj-Tibt-BT", - "tsw": "tsw-Latn-ZZ", - "tt": "tt-Cyrl-RU", - "ttd": "ttd-Latn-ZZ", - "tte": "tte-Latn-ZZ", - "ttj": "ttj-Latn-UG", - "ttr": "ttr-Latn-ZZ", - "tts": "tts-Thai-TH", - "ttt": "ttt-Latn-AZ", - "tuh": "tuh-Latn-ZZ", - "tul": "tul-Latn-ZZ", - "tum": "tum-Latn-MW", - "tuq": "tuq-Latn-ZZ", - "tvd": "tvd-Latn-ZZ", - "tvl": "tvl-Latn-TV", - "tvu": "tvu-Latn-ZZ", - "twh": "twh-Latn-ZZ", - "twq": "twq-Latn-NE", - "txg": "txg-Tang-CN", - "txo": "txo-Toto-IN", - "ty": "ty-Latn-PF", - "tya": "tya-Latn-ZZ", - "tyv": "tyv-Cyrl-RU", - "tzm": "tzm-Latn-MA", - "ubu": "ubu-Latn-ZZ", - "udi": "udi-Aghb-RU", - "udm": "udm-Cyrl-RU", - "ug": "ug-Arab-CN", - "ug-Cyrl": "ug-Cyrl-KZ", - "ug-KZ": "ug-Cyrl-KZ", - "ug-MN": "ug-Cyrl-MN", - "uga": "uga-Ugar-SY", - "uk": "uk-Cyrl-UA", - "uli": "uli-Latn-FM", - "umb": "umb-Latn-AO", - "und": "en-Latn-US", - "und-002": "en-Latn-NG", - "und-003": "en-Latn-US", - "und-005": "pt-Latn-BR", - "und-009": "en-Latn-AU", - "und-011": "en-Latn-NG", - "und-013": "es-Latn-MX", - "und-014": "sw-Latn-TZ", - "und-015": "ar-Arab-EG", - "und-017": "sw-Latn-CD", - "und-018": "en-Latn-ZA", - "und-019": "en-Latn-US", - "und-021": "en-Latn-US", - "und-029": "es-Latn-CU", - "und-030": "zh-Hans-CN", - "und-034": "hi-Deva-IN", - "und-035": "id-Latn-ID", - "und-039": "it-Latn-IT", - "und-053": "en-Latn-AU", - "und-054": "en-Latn-PG", - "und-057": "en-Latn-GU", - "und-061": "sm-Latn-WS", - "und-142": "zh-Hans-CN", - "und-143": "uz-Latn-UZ", - "und-145": "ar-Arab-SA", - "und-150": "ru-Cyrl-RU", - "und-151": "ru-Cyrl-RU", - "und-154": "en-Latn-GB", - "und-155": "de-Latn-DE", - "und-202": "en-Latn-NG", - "und-419": "es-Latn-419", - "und-AD": "ca-Latn-AD", - "und-Adlm": "ff-Adlm-GN", - "und-AE": "ar-Arab-AE", - "und-AF": "fa-Arab-AF", - "und-Aghb": "udi-Aghb-RU", - "und-Ahom": "aho-Ahom-IN", - "und-AL": "sq-Latn-AL", - "und-AM": "hy-Armn-AM", - "und-AO": "pt-Latn-AO", - "und-AQ": "und-Latn-AQ", - "und-AR": "es-Latn-AR", - "und-Arab": "ar-Arab-EG", - "und-Arab-CC": "ms-Arab-CC", - "und-Arab-CN": "ug-Arab-CN", - "und-Arab-GB": "ks-Arab-GB", - "und-Arab-ID": "ms-Arab-ID", - "und-Arab-IN": "ur-Arab-IN", - "und-Arab-KH": "cja-Arab-KH", - "und-Arab-MM": "rhg-Arab-MM", - "und-Arab-MN": "kk-Arab-MN", - "und-Arab-MU": "ur-Arab-MU", - "und-Arab-NG": "ha-Arab-NG", - "und-Arab-PK": "ur-Arab-PK", - "und-Arab-TG": "apd-Arab-TG", - "und-Arab-TH": "mfa-Arab-TH", - "und-Arab-TJ": "fa-Arab-TJ", - "und-Arab-TR": "az-Arab-TR", - "und-Arab-YT": "swb-Arab-YT", - "und-Armi": "arc-Armi-IR", - "und-Armn": "hy-Armn-AM", - "und-AS": "sm-Latn-AS", - "und-AT": "de-Latn-AT", - "und-Avst": "ae-Avst-IR", - "und-AW": "nl-Latn-AW", - "und-AX": "sv-Latn-AX", - "und-AZ": "az-Latn-AZ", - "und-BA": "bs-Latn-BA", - "und-Bali": "ban-Bali-ID", - "und-Bamu": "bax-Bamu-CM", - "und-Bass": "bsq-Bass-LR", - "und-Batk": "bbc-Batk-ID", - "und-BD": "bn-Beng-BD", - "und-BE": "nl-Latn-BE", - "und-Beng": "bn-Beng-BD", - "und-BF": "fr-Latn-BF", - "und-BG": "bg-Cyrl-BG", - "und-BH": "ar-Arab-BH", - "und-Bhks": "sa-Bhks-IN", - "und-BI": "rn-Latn-BI", - "und-BJ": "fr-Latn-BJ", - "und-BL": "fr-Latn-BL", - "und-BN": "ms-Latn-BN", - "und-BO": "es-Latn-BO", - "und-Bopo": "zh-Bopo-TW", - "und-BQ": "pap-Latn-BQ", - "und-BR": "pt-Latn-BR", - "und-Brah": "pka-Brah-IN", - "und-Brai": "fr-Brai-FR", - "und-BT": "dz-Tibt-BT", - "und-Bugi": "bug-Bugi-ID", - "und-Buhd": "bku-Buhd-PH", - "und-BV": "und-Latn-BV", - "und-BY": "be-Cyrl-BY", - "und-Cakm": "ccp-Cakm-BD", - "und-Cans": "cr-Cans-CA", - "und-Cari": "xcr-Cari-TR", - "und-CD": "sw-Latn-CD", - "und-CF": "fr-Latn-CF", - "und-CG": "fr-Latn-CG", - "und-CH": "de-Latn-CH", - "und-Cham": "cjm-Cham-VN", - "und-Cher": "chr-Cher-US", - "und-Chrs": "xco-Chrs-UZ", - "und-CI": "fr-Latn-CI", - "und-CL": "es-Latn-CL", - "und-CM": "fr-Latn-CM", - "und-CN": "zh-Hans-CN", - "und-CO": "es-Latn-CO", - "und-Copt": "cop-Copt-EG", - "und-CP": "und-Latn-CP", - "und-Cpmn": "und-Cpmn-CY", - "und-Cpmn-CY": "und-Cpmn-CY", - "und-Cprt": "grc-Cprt-CY", - "und-CR": "es-Latn-CR", - "und-CU": "es-Latn-CU", - "und-CV": "pt-Latn-CV", - "und-CW": "pap-Latn-CW", - "und-CY": "el-Grek-CY", - "und-Cyrl": "ru-Cyrl-RU", - "und-Cyrl-AL": "mk-Cyrl-AL", - "und-Cyrl-BA": "sr-Cyrl-BA", - "und-Cyrl-GE": "os-Cyrl-GE", - "und-Cyrl-GR": "mk-Cyrl-GR", - "und-Cyrl-MD": "uk-Cyrl-MD", - "und-Cyrl-RO": "bg-Cyrl-RO", - "und-Cyrl-SK": "uk-Cyrl-SK", - "und-Cyrl-TR": "kbd-Cyrl-TR", - "und-Cyrl-XK": "sr-Cyrl-XK", - "und-CZ": "cs-Latn-CZ", - "und-DE": "de-Latn-DE", - "und-Deva": "hi-Deva-IN", - "und-Deva-BT": "ne-Deva-BT", - "und-Deva-FJ": "hif-Deva-FJ", - "und-Deva-MU": "bho-Deva-MU", - "und-Deva-PK": "btv-Deva-PK", - "und-Diak": "dv-Diak-MV", - "und-DJ": "aa-Latn-DJ", - "und-DK": "da-Latn-DK", - "und-DO": "es-Latn-DO", - "und-Dogr": "doi-Dogr-IN", - "und-Dupl": "fr-Dupl-FR", - "und-DZ": "ar-Arab-DZ", - "und-EA": "es-Latn-EA", - "und-EC": "es-Latn-EC", - "und-EE": "et-Latn-EE", - "und-EG": "ar-Arab-EG", - "und-Egyp": "egy-Egyp-EG", - "und-EH": "ar-Arab-EH", - "und-Elba": "sq-Elba-AL", - "und-Elym": "arc-Elym-IR", - "und-ER": "ti-Ethi-ER", - "und-ES": "es-Latn-ES", - "und-ET": "am-Ethi-ET", - "und-Ethi": "am-Ethi-ET", - "und-EU": "en-Latn-IE", - "und-EZ": "de-Latn-EZ", - "und-FI": "fi-Latn-FI", - "und-FO": "fo-Latn-FO", - "und-FR": "fr-Latn-FR", - "und-GA": "fr-Latn-GA", - "und-GE": "ka-Geor-GE", - "und-Geor": "ka-Geor-GE", - "und-GF": "fr-Latn-GF", - "und-GH": "ak-Latn-GH", - "und-GL": "kl-Latn-GL", - "und-Glag": "cu-Glag-BG", - "und-GN": "fr-Latn-GN", - "und-Gong": "wsg-Gong-IN", - "und-Gonm": "esg-Gonm-IN", - "und-Goth": "got-Goth-UA", - "und-GP": "fr-Latn-GP", - "und-GQ": "es-Latn-GQ", - "und-GR": "el-Grek-GR", - "und-Gran": "sa-Gran-IN", - "und-Grek": "el-Grek-GR", - "und-Grek-TR": "bgx-Grek-TR", - "und-GS": "und-Latn-GS", - "und-GT": "es-Latn-GT", - "und-Gujr": "gu-Gujr-IN", - "und-Guru": "pa-Guru-IN", - "und-GW": "pt-Latn-GW", - "und-Hanb": "zh-Hanb-TW", - "und-Hang": "ko-Hang-KR", - "und-Hani": "zh-Hani-CN", - "und-Hano": "hnn-Hano-PH", - "und-Hans": "zh-Hans-CN", - "und-Hant": "zh-Hant-TW", - "und-Hebr": "he-Hebr-IL", - "und-Hebr-CA": "yi-Hebr-CA", - "und-Hebr-GB": "yi-Hebr-GB", - "und-Hebr-SE": "yi-Hebr-SE", - "und-Hebr-UA": "yi-Hebr-UA", - "und-Hebr-US": "yi-Hebr-US", - "und-Hira": "ja-Hira-JP", - "und-HK": "zh-Hant-HK", - "und-Hluw": "hlu-Hluw-TR", - "und-HM": "und-Latn-HM", - "und-Hmng": "hnj-Hmng-LA", - "und-Hmnp": "hnj-Hmnp-US", - "und-HN": "es-Latn-HN", - "und-HR": "hr-Latn-HR", - "und-HT": "ht-Latn-HT", - "und-HU": "hu-Latn-HU", - "und-Hung": "hu-Hung-HU", - "und-IC": "es-Latn-IC", - "und-ID": "id-Latn-ID", - "und-IL": "he-Hebr-IL", - "und-IN": "hi-Deva-IN", - "und-IQ": "ar-Arab-IQ", - "und-IR": "fa-Arab-IR", - "und-IS": "is-Latn-IS", - "und-IT": "it-Latn-IT", - "und-Ital": "ett-Ital-IT", - "und-Jamo": "ko-Jamo-KR", - "und-Java": "jv-Java-ID", - "und-JO": "ar-Arab-JO", - "und-JP": "ja-Jpan-JP", - "und-Jpan": "ja-Jpan-JP", - "und-Kali": "eky-Kali-MM", - "und-Kana": "ja-Kana-JP", - "und-KE": "sw-Latn-KE", - "und-KG": "ky-Cyrl-KG", - "und-KH": "km-Khmr-KH", - "und-Khar": "pra-Khar-PK", - "und-Khmr": "km-Khmr-KH", - "und-Khoj": "sd-Khoj-IN", - "und-Kits": "zkt-Kits-CN", - "und-KM": "ar-Arab-KM", - "und-Knda": "kn-Knda-IN", - "und-Kore": "ko-Kore-KR", - "und-KP": "ko-Kore-KP", - "und-KR": "ko-Kore-KR", - "und-Kthi": "bho-Kthi-IN", - "und-KW": "ar-Arab-KW", - "und-KZ": "ru-Cyrl-KZ", - "und-LA": "lo-Laoo-LA", - "und-Lana": "nod-Lana-TH", - "und-Laoo": "lo-Laoo-LA", - "und-Latn-AF": "tk-Latn-AF", - "und-Latn-AM": "ku-Latn-AM", - "und-Latn-CN": "za-Latn-CN", - "und-Latn-CY": "tr-Latn-CY", - "und-Latn-DZ": "fr-Latn-DZ", - "und-Latn-ET": "en-Latn-ET", - "und-Latn-GE": "ku-Latn-GE", - "und-Latn-IR": "tk-Latn-IR", - "und-Latn-KM": "fr-Latn-KM", - "und-Latn-MA": "fr-Latn-MA", - "und-Latn-MK": "sq-Latn-MK", - "und-Latn-MM": "kac-Latn-MM", - "und-Latn-MO": "pt-Latn-MO", - "und-Latn-MR": "fr-Latn-MR", - "und-Latn-RU": "krl-Latn-RU", - "und-Latn-SY": "fr-Latn-SY", - "und-Latn-TN": "fr-Latn-TN", - "und-Latn-TW": "trv-Latn-TW", - "und-Latn-UA": "pl-Latn-UA", - "und-LB": "ar-Arab-LB", - "und-Lepc": "lep-Lepc-IN", - "und-LI": "de-Latn-LI", - "und-Limb": "lif-Limb-IN", - "und-Lina": "lab-Lina-GR", - "und-Linb": "grc-Linb-GR", - "und-Lisu": "lis-Lisu-CN", - "und-LK": "si-Sinh-LK", - "und-LS": "st-Latn-LS", - "und-LT": "lt-Latn-LT", - "und-LU": "fr-Latn-LU", - "und-LV": "lv-Latn-LV", - "und-LY": "ar-Arab-LY", - "und-Lyci": "xlc-Lyci-TR", - "und-Lydi": "xld-Lydi-TR", - "und-MA": "ar-Arab-MA", - "und-Mahj": "hi-Mahj-IN", - "und-Maka": "mak-Maka-ID", - "und-Mand": "myz-Mand-IR", - "und-Mani": "xmn-Mani-CN", - "und-Marc": "bo-Marc-CN", - "und-MC": "fr-Latn-MC", - "und-MD": "ro-Latn-MD", - "und-ME": "sr-Latn-ME", - "und-Medf": "dmf-Medf-NG", - "und-Mend": "men-Mend-SL", - "und-Merc": "xmr-Merc-SD", - "und-Mero": "xmr-Mero-SD", - "und-MF": "fr-Latn-MF", - "und-MG": "mg-Latn-MG", - "und-MK": "mk-Cyrl-MK", - "und-ML": "bm-Latn-ML", - "und-Mlym": "ml-Mlym-IN", - "und-MM": "my-Mymr-MM", - "und-MN": "mn-Cyrl-MN", - "und-MO": "zh-Hant-MO", - "und-Modi": "mr-Modi-IN", - "und-Mong": "mn-Mong-CN", - "und-MQ": "fr-Latn-MQ", - "und-MR": "ar-Arab-MR", - "und-Mroo": "mro-Mroo-BD", - "und-MT": "mt-Latn-MT", - "und-Mtei": "mni-Mtei-IN", - "und-MU": "mfe-Latn-MU", - "und-Mult": "skr-Mult-PK", - "und-MV": "dv-Thaa-MV", - "und-MX": "es-Latn-MX", - "und-MY": "ms-Latn-MY", - "und-Mymr": "my-Mymr-MM", - "und-Mymr-IN": "kht-Mymr-IN", - "und-Mymr-TH": "mnw-Mymr-TH", - "und-MZ": "pt-Latn-MZ", - "und-NA": "af-Latn-NA", - "und-Nand": "sa-Nand-IN", - "und-Narb": "xna-Narb-SA", - "und-Nbat": "arc-Nbat-JO", - "und-NC": "fr-Latn-NC", - "und-NE": "ha-Latn-NE", - "und-Newa": "new-Newa-NP", - "und-NI": "es-Latn-NI", - "und-Nkoo": "man-Nkoo-GN", - "und-NL": "nl-Latn-NL", - "und-NO": "nb-Latn-NO", - "und-NP": "ne-Deva-NP", - "und-Nshu": "zhx-Nshu-CN", - "und-Ogam": "sga-Ogam-IE", - "und-Olck": "sat-Olck-IN", - "und-OM": "ar-Arab-OM", - "und-Orkh": "otk-Orkh-MN", - "und-Orya": "or-Orya-IN", - "und-Osge": "osa-Osge-US", - "und-Osma": "so-Osma-SO", - "und-Ougr": "oui-Ougr-143", - "und-PA": "es-Latn-PA", - "und-Palm": "arc-Palm-SY", - "und-Pauc": "ctd-Pauc-MM", - "und-PE": "es-Latn-PE", - "und-Perm": "kv-Perm-RU", - "und-PF": "fr-Latn-PF", - "und-PG": "tpi-Latn-PG", - "und-PH": "fil-Latn-PH", - "und-Phag": "lzh-Phag-CN", - "und-Phli": "pal-Phli-IR", - "und-Phlp": "pal-Phlp-CN", - "und-Phnx": "phn-Phnx-LB", - "und-PK": "ur-Arab-PK", - "und-PL": "pl-Latn-PL", - "und-Plrd": "hmd-Plrd-CN", - "und-PM": "fr-Latn-PM", - "und-PR": "es-Latn-PR", - "und-Prti": "xpr-Prti-IR", - "und-PS": "ar-Arab-PS", - "und-PT": "pt-Latn-PT", - "und-PW": "pau-Latn-PW", - "und-PY": "gn-Latn-PY", - "und-QA": "ar-Arab-QA", - "und-QO": "en-Latn-DG", - "und-RE": "fr-Latn-RE", - "und-Rjng": "rej-Rjng-ID", - "und-RO": "ro-Latn-RO", - "und-Rohg": "rhg-Rohg-MM", - "und-RS": "sr-Cyrl-RS", - "und-RU": "ru-Cyrl-RU", - "und-Runr": "non-Runr-SE", - "und-RW": "rw-Latn-RW", - "und-SA": "ar-Arab-SA", - "und-Samr": "smp-Samr-IL", - "und-Sarb": "xsa-Sarb-YE", - "und-Saur": "saz-Saur-IN", - "und-SC": "fr-Latn-SC", - "und-SD": "ar-Arab-SD", - "und-SE": "sv-Latn-SE", - "und-Sgnw": "ase-Sgnw-US", - "und-Shaw": "en-Shaw-GB", - "und-Shrd": "sa-Shrd-IN", - "und-SI": "sl-Latn-SI", - "und-Sidd": "sa-Sidd-IN", - "und-Sind": "sd-Sind-IN", - "und-Sinh": "si-Sinh-LK", - "und-SJ": "nb-Latn-SJ", - "und-SK": "sk-Latn-SK", - "und-SM": "it-Latn-SM", - "und-SN": "fr-Latn-SN", - "und-SO": "so-Latn-SO", - "und-Sogd": "sog-Sogd-UZ", - "und-Sogo": "sog-Sogo-UZ", - "und-Sora": "srb-Sora-IN", - "und-Soyo": "cmg-Soyo-MN", - "und-SR": "nl-Latn-SR", - "und-ST": "pt-Latn-ST", - "und-Sund": "su-Sund-ID", - "und-SV": "es-Latn-SV", - "und-SY": "ar-Arab-SY", - "und-Sylo": "syl-Sylo-BD", - "und-Syrc": "syr-Syrc-IQ", - "und-Tagb": "tbw-Tagb-PH", - "und-Takr": "doi-Takr-IN", - "und-Tale": "tdd-Tale-CN", - "und-Talu": "khb-Talu-CN", - "und-Taml": "ta-Taml-IN", - "und-Tang": "txg-Tang-CN", - "und-Tavt": "blt-Tavt-VN", - "und-TD": "fr-Latn-TD", - "und-Telu": "te-Telu-IN", - "und-TF": "fr-Latn-TF", - "und-Tfng": "zgh-Tfng-MA", - "und-TG": "fr-Latn-TG", - "und-Tglg": "fil-Tglg-PH", - "und-TH": "th-Thai-TH", - "und-Thaa": "dv-Thaa-MV", - "und-Thai": "th-Thai-TH", - "und-Thai-CN": "lcp-Thai-CN", - "und-Thai-KH": "kdt-Thai-KH", - "und-Thai-LA": "kdt-Thai-LA", - "und-Tibt": "bo-Tibt-CN", - "und-Tirh": "mai-Tirh-IN", - "und-TJ": "tg-Cyrl-TJ", - "und-TK": "tkl-Latn-TK", - "und-TL": "pt-Latn-TL", - "und-TM": "tk-Latn-TM", - "und-TN": "ar-Arab-TN", - "und-Tnsa": "nst-Tnsa-IN", - "und-TO": "to-Latn-TO", - "und-Toto": "txo-Toto-IN", - "und-TR": "tr-Latn-TR", - "und-TV": "tvl-Latn-TV", - "und-TW": "zh-Hant-TW", - "und-TZ": "sw-Latn-TZ", - "und-UA": "uk-Cyrl-UA", - "und-UG": "sw-Latn-UG", - "und-Ugar": "uga-Ugar-SY", - "und-UY": "es-Latn-UY", - "und-UZ": "uz-Latn-UZ", - "und-VA": "it-Latn-VA", - "und-Vaii": "vai-Vaii-LR", - "und-VE": "es-Latn-VE", - "und-Vith": "sq-Vith-AL", - "und-VN": "vi-Latn-VN", - "und-VU": "bi-Latn-VU", - "und-Wara": "hoc-Wara-IN", - "und-Wcho": "nnp-Wcho-IN", - "und-WF": "fr-Latn-WF", - "und-WS": "sm-Latn-WS", - "und-XK": "sq-Latn-XK", - "und-Xpeo": "peo-Xpeo-IR", - "und-Xsux": "akk-Xsux-IQ", - "und-YE": "ar-Arab-YE", - "und-Yezi": "ku-Yezi-GE", - "und-Yiii": "ii-Yiii-CN", - "und-YT": "fr-Latn-YT", - "und-Zanb": "cmg-Zanb-MN", - "und-ZW": "sn-Latn-ZW", - "unr": "unr-Beng-IN", - "unr-Deva": "unr-Deva-NP", - "unr-NP": "unr-Deva-NP", - "unx": "unx-Beng-IN", - "uok": "uok-Latn-ZZ", - "ur": "ur-Arab-PK", - "uri": "uri-Latn-ZZ", - "urt": "urt-Latn-ZZ", - "urw": "urw-Latn-ZZ", - "usa": "usa-Latn-ZZ", - "uth": "uth-Latn-ZZ", - "utr": "utr-Latn-ZZ", - "uvh": "uvh-Latn-ZZ", - "uvl": "uvl-Latn-ZZ", - "uz": "uz-Latn-UZ", - "uz-AF": "uz-Arab-AF", - "uz-Arab": "uz-Arab-AF", - "uz-CN": "uz-Cyrl-CN", - "vag": "vag-Latn-ZZ", - "vai": "vai-Vaii-LR", - "van": "van-Latn-ZZ", - "ve": "ve-Latn-ZA", - "vec": "vec-Latn-IT", - "vep": "vep-Latn-RU", - "vi": "vi-Latn-VN", - "vic": "vic-Latn-SX", - "viv": "viv-Latn-ZZ", - "vls": "vls-Latn-BE", - "vmf": "vmf-Latn-DE", - "vmw": "vmw-Latn-MZ", - "vo": "vo-Latn-001", - "vot": "vot-Latn-RU", - "vro": "vro-Latn-EE", - "vun": "vun-Latn-TZ", - "vut": "vut-Latn-ZZ", - "wa": "wa-Latn-BE", - "wae": "wae-Latn-CH", - "waj": "waj-Latn-ZZ", - "wal": "wal-Ethi-ET", - "wan": "wan-Latn-ZZ", - "war": "war-Latn-PH", - "wbp": "wbp-Latn-AU", - "wbq": "wbq-Telu-IN", - "wbr": "wbr-Deva-IN", - "wci": "wci-Latn-ZZ", - "wer": "wer-Latn-ZZ", - "wgi": "wgi-Latn-ZZ", - "whg": "whg-Latn-ZZ", - "wib": "wib-Latn-ZZ", - "wiu": "wiu-Latn-ZZ", - "wiv": "wiv-Latn-ZZ", - "wja": "wja-Latn-ZZ", - "wji": "wji-Latn-ZZ", - "wls": "wls-Latn-WF", - "wmo": "wmo-Latn-ZZ", - "wnc": "wnc-Latn-ZZ", - "wni": "wni-Arab-KM", - "wnu": "wnu-Latn-ZZ", - "wo": "wo-Latn-SN", - "wob": "wob-Latn-ZZ", - "wos": "wos-Latn-ZZ", - "wrs": "wrs-Latn-ZZ", - "wsg": "wsg-Gong-IN", - "wsk": "wsk-Latn-ZZ", - "wtm": "wtm-Deva-IN", - "wuu": "wuu-Hans-CN", - "wuv": "wuv-Latn-ZZ", - "wwa": "wwa-Latn-ZZ", - "xav": "xav-Latn-BR", - "xbi": "xbi-Latn-ZZ", - "xco": "xco-Chrs-UZ", - "xcr": "xcr-Cari-TR", - "xes": "xes-Latn-ZZ", - "xh": "xh-Latn-ZA", - "xla": "xla-Latn-ZZ", - "xlc": "xlc-Lyci-TR", - "xld": "xld-Lydi-TR", - "xmf": "xmf-Geor-GE", - "xmn": "xmn-Mani-CN", - "xmr": "xmr-Merc-SD", - "xna": "xna-Narb-SA", - "xnr": "xnr-Deva-IN", - "xog": "xog-Latn-UG", - "xon": "xon-Latn-ZZ", - "xpr": "xpr-Prti-IR", - "xrb": "xrb-Latn-ZZ", - "xsa": "xsa-Sarb-YE", - "xsi": "xsi-Latn-ZZ", - "xsm": "xsm-Latn-ZZ", - "xsr": "xsr-Deva-NP", - "xwe": "xwe-Latn-ZZ", - "yam": "yam-Latn-ZZ", - "yao": "yao-Latn-MZ", - "yap": "yap-Latn-FM", - "yas": "yas-Latn-ZZ", - "yat": "yat-Latn-ZZ", - "yav": "yav-Latn-CM", - "yay": "yay-Latn-ZZ", - "yaz": "yaz-Latn-ZZ", - "yba": "yba-Latn-ZZ", - "ybb": "ybb-Latn-CM", - "yby": "yby-Latn-ZZ", - "yer": "yer-Latn-ZZ", - "ygr": "ygr-Latn-ZZ", - "ygw": "ygw-Latn-ZZ", - "yi": "yi-Hebr-001", - "yko": "yko-Latn-ZZ", - "yle": "yle-Latn-ZZ", - "ylg": "ylg-Latn-ZZ", - "yll": "yll-Latn-ZZ", - "yml": "yml-Latn-ZZ", - "yo": "yo-Latn-NG", - "yon": "yon-Latn-ZZ", - "yrb": "yrb-Latn-ZZ", - "yre": "yre-Latn-ZZ", - "yrl": "yrl-Latn-BR", - "yss": "yss-Latn-ZZ", - "yua": "yua-Latn-MX", - "yue": "yue-Hant-HK", - "yue-CN": "yue-Hans-CN", - "yue-Hans": "yue-Hans-CN", - "yuj": "yuj-Latn-ZZ", - "yut": "yut-Latn-ZZ", - "yuw": "yuw-Latn-ZZ", - "za": "za-Latn-CN", - "zag": "zag-Latn-SD", - "zdj": "zdj-Arab-KM", - "zea": "zea-Latn-NL", - "zgh": "zgh-Tfng-MA", - "zh": "zh-Hans-CN", - "zh-AU": "zh-Hant-AU", - "zh-BN": "zh-Hant-BN", - "zh-Bopo": "zh-Bopo-TW", - "zh-GB": "zh-Hant-GB", - "zh-GF": "zh-Hant-GF", - "zh-Hanb": "zh-Hanb-TW", - "zh-Hant": "zh-Hant-TW", - "zh-HK": "zh-Hant-HK", - "zh-ID": "zh-Hant-ID", - "zh-MO": "zh-Hant-MO", - "zh-PA": "zh-Hant-PA", - "zh-PF": "zh-Hant-PF", - "zh-PH": "zh-Hant-PH", - "zh-SR": "zh-Hant-SR", - "zh-TH": "zh-Hant-TH", - "zh-TW": "zh-Hant-TW", - "zh-US": "zh-Hant-US", - "zh-VN": "zh-Hant-VN", - "zhx": "zhx-Nshu-CN", - "zia": "zia-Latn-ZZ", - "zkt": "zkt-Kits-CN", - "zlm": "zlm-Latn-TG", - "zmi": "zmi-Latn-MY", - "zne": "zne-Latn-ZZ", - "zu": "zu-Latn-ZA", - "zza": "zza-Latn-TR" - }; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/canonicalizer.js - var require_canonicalizer = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/canonicalizer.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.canonicalizeUnicodeLocaleId = exports.canonicalizeUnicodeLanguageId = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var aliases_generated_1 = require_aliases_generated(); - var parser_1 = require_parser(); - var likelySubtags_generated_1 = require_likelySubtags_generated(); - var emitter_1 = require_emitter(); - function canonicalizeAttrs(strs) { - return Object.keys(strs.reduce(function(all, str) { - all[str.toLowerCase()] = 1; - return all; - }, {})).sort(); - } - function canonicalizeKVs(arr) { - var all = {}; - var result = []; - for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) { - var kv = arr_1[_i]; - if (kv[0] in all) { - continue; - } - all[kv[0]] = 1; - if (!kv[1] || kv[1] === "true") { - result.push([kv[0].toLowerCase()]); - } else { - result.push([kv[0].toLowerCase(), kv[1].toLowerCase()]); - } - } - return result.sort(compareKV); - } - function compareKV(t1, t2) { - return t1[0] < t2[0] ? -1 : t1[0] > t2[0] ? 1 : 0; - } - function compareExtension(e1, e2) { - return e1.type < e2.type ? -1 : e1.type > e2.type ? 1 : 0; - } - function mergeVariants(v1, v2) { - var result = tslib_1.__spreadArray([], v1, true); - for (var _i = 0, v2_1 = v2; _i < v2_1.length; _i++) { - var v = v2_1[_i]; - if (v1.indexOf(v) < 0) { - result.push(v); - } - } - return result; - } - function canonicalizeUnicodeLanguageId(unicodeLanguageId) { - var finalLangAst = unicodeLanguageId; - if (unicodeLanguageId.variants.length) { - var replacedLang_1 = ""; - for (var _i = 0, _a = unicodeLanguageId.variants; _i < _a.length; _i++) { - var variant = _a[_i]; - if (replacedLang_1 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: unicodeLanguageId.lang, - variants: [variant] - })]) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_1.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: finalLangAst.script || replacedLangAst.script, - region: finalLangAst.region || replacedLangAst.region, - variants: mergeVariants(finalLangAst.variants, replacedLangAst.variants) - }; - break; - } - } - } - if (finalLangAst.script && finalLangAst.region) { - var replacedLang_2 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - script: finalLangAst.script, - region: finalLangAst.region, - variants: [] - })]; - if (replacedLang_2) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_2.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: replacedLangAst.script, - region: replacedLangAst.region, - variants: finalLangAst.variants - }; - } - } - if (finalLangAst.region) { - var replacedLang_3 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - region: finalLangAst.region, - variants: [] - })]; - if (replacedLang_3) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_3.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: finalLangAst.script || replacedLangAst.script, - region: replacedLangAst.region, - variants: finalLangAst.variants - }; - } - } - var replacedLang = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - variants: [] - })]; - if (replacedLang) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: finalLangAst.script || replacedLangAst.script, - region: finalLangAst.region || replacedLangAst.region, - variants: finalLangAst.variants - }; - } - if (finalLangAst.region) { - var region = finalLangAst.region.toUpperCase(); - var regionAlias = aliases_generated_1.territoryAlias[region]; - var replacedRegion = void 0; - if (regionAlias) { - var regions = regionAlias.split(" "); - replacedRegion = regions[0]; - var likelySubtag = likelySubtags_generated_1.likelySubtags[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - script: finalLangAst.script, - variants: [] - })]; - if (likelySubtag) { - var likelyRegion = (0, parser_1.parseUnicodeLanguageId)(likelySubtag.split(parser_1.SEPARATOR)).region; - if (likelyRegion && regions.indexOf(likelyRegion) > -1) { - replacedRegion = likelyRegion; - } - } - } - if (replacedRegion) { - finalLangAst.region = replacedRegion; - } - finalLangAst.region = finalLangAst.region.toUpperCase(); - } - if (finalLangAst.script) { - finalLangAst.script = finalLangAst.script[0].toUpperCase() + finalLangAst.script.slice(1).toLowerCase(); - if (aliases_generated_1.scriptAlias[finalLangAst.script]) { - finalLangAst.script = aliases_generated_1.scriptAlias[finalLangAst.script]; - } - } - if (finalLangAst.variants.length) { - for (var i = 0; i < finalLangAst.variants.length; i++) { - var variant = finalLangAst.variants[i].toLowerCase(); - if (aliases_generated_1.variantAlias[variant]) { - var alias = aliases_generated_1.variantAlias[variant]; - if ((0, parser_1.isUnicodeVariantSubtag)(alias)) { - finalLangAst.variants[i] = alias; - } else if ((0, parser_1.isUnicodeLanguageSubtag)(alias)) { - finalLangAst.lang = alias; - } - } - } - finalLangAst.variants.sort(); - } - return finalLangAst; - } - exports.canonicalizeUnicodeLanguageId = canonicalizeUnicodeLanguageId; - function canonicalizeUnicodeLocaleId(locale) { - locale.lang = canonicalizeUnicodeLanguageId(locale.lang); - if (locale.extensions) { - for (var _i = 0, _a = locale.extensions; _i < _a.length; _i++) { - var extension = _a[_i]; - switch (extension.type) { - case "u": - extension.keywords = canonicalizeKVs(extension.keywords); - if (extension.attributes) { - extension.attributes = canonicalizeAttrs(extension.attributes); - } - break; - case "t": - if (extension.lang) { - extension.lang = canonicalizeUnicodeLanguageId(extension.lang); - } - extension.fields = canonicalizeKVs(extension.fields); - break; - default: - extension.value = extension.value.toLowerCase(); - break; - } - } - locale.extensions.sort(compareExtension); - } - return locale; - } - exports.canonicalizeUnicodeLocaleId = canonicalizeUnicodeLocaleId; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/types.js - var require_types = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/types.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/index.js - var require_intl_getcanonicallocales = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.isUnicodeLanguageSubtag = exports.isUnicodeScriptSubtag = exports.isUnicodeRegionSubtag = exports.isStructurallyValidLanguageTag = exports.parseUnicodeLanguageId = exports.parseUnicodeLocaleId = exports.getCanonicalLocales = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var parser_1 = require_parser(); - var emitter_1 = require_emitter(); - var canonicalizer_1 = require_canonicalizer(); - function CanonicalizeLocaleList(locales) { - if (locales === void 0) { - return []; - } - var seen = []; - if (typeof locales === "string") { - locales = [locales]; - } - for (var _i = 0, locales_1 = locales; _i < locales_1.length; _i++) { - var locale = locales_1[_i]; - var canonicalizedTag = (0, emitter_1.emitUnicodeLocaleId)((0, canonicalizer_1.canonicalizeUnicodeLocaleId)((0, parser_1.parseUnicodeLocaleId)(locale))); - if (seen.indexOf(canonicalizedTag) < 0) { - seen.push(canonicalizedTag); - } - } - return seen; - } - function getCanonicalLocales(locales) { - return CanonicalizeLocaleList(locales); - } - exports.getCanonicalLocales = getCanonicalLocales; - var parser_2 = require_parser(); - Object.defineProperty(exports, "parseUnicodeLocaleId", { enumerable: true, get: function() { - return parser_2.parseUnicodeLocaleId; - } }); - Object.defineProperty(exports, "parseUnicodeLanguageId", { enumerable: true, get: function() { - return parser_2.parseUnicodeLanguageId; - } }); - Object.defineProperty(exports, "isStructurallyValidLanguageTag", { enumerable: true, get: function() { - return parser_2.isStructurallyValidLanguageTag; - } }); - Object.defineProperty(exports, "isUnicodeRegionSubtag", { enumerable: true, get: function() { - return parser_2.isUnicodeRegionSubtag; - } }); - Object.defineProperty(exports, "isUnicodeScriptSubtag", { enumerable: true, get: function() { - return parser_2.isUnicodeScriptSubtag; - } }); - Object.defineProperty(exports, "isUnicodeLanguageSubtag", { enumerable: true, get: function() { - return parser_2.isUnicodeLanguageSubtag; - } }); - tslib_1.__exportStar(require_types(), exports); - tslib_1.__exportStar(require_emitter(), exports); - tslib_1.__exportStar(require_likelySubtags_generated(), exports); - } - }); - - // node_modules/@formatjs/intl-locale/get_internal_slots.js - var require_get_internal_slots = __commonJS({ - "node_modules/@formatjs/intl-locale/get_internal_slots.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var internalSlotMap = /* @__PURE__ */ new WeakMap(); - function getInternalSlots(x) { - var internalSlots = internalSlotMap.get(x); - if (!internalSlots) { - internalSlots = /* @__PURE__ */ Object.create(null); - internalSlotMap.set(x, internalSlots); - } - return internalSlots; - } - exports.default = getInternalSlots; - } - }); - - // node_modules/@formatjs/intl-locale/index.js - var require_intl_locale = __commonJS({ - "node_modules/@formatjs/intl-locale/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.Locale = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var ecma402_abstract_1 = require_ecma402_abstract(); - var intl_getcanonicallocales_1 = require_intl_getcanonicallocales(); - var get_internal_slots_1 = tslib_1.__importDefault(require_get_internal_slots()); - var RELEVANT_EXTENSION_KEYS = ["ca", "co", "hc", "kf", "kn", "nu"]; - var UNICODE_TYPE_REGEX = /^[a-z0-9]{3,8}(-[a-z0-9]{3,8})*$/i; - function applyOptionsToTag(tag, options) { - (0, ecma402_abstract_1.invariant)(typeof tag === "string", "language tag must be a string"); - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isStructurallyValidLanguageTag)(tag), "malformed language tag", RangeError); - var language = (0, ecma402_abstract_1.GetOption)(options, "language", "string", void 0, void 0); - if (language !== void 0) { - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeLanguageSubtag)(language), "Malformed unicode_language_subtag", RangeError); - } - var script = (0, ecma402_abstract_1.GetOption)(options, "script", "string", void 0, void 0); - if (script !== void 0) { - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeScriptSubtag)(script), "Malformed unicode_script_subtag", RangeError); - } - var region = (0, ecma402_abstract_1.GetOption)(options, "region", "string", void 0, void 0); - if (region !== void 0) { - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeRegionSubtag)(region), "Malformed unicode_region_subtag", RangeError); - } - var languageId = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(tag); - if (language !== void 0) { - languageId.lang = language; - } - if (script !== void 0) { - languageId.script = script; - } - if (region !== void 0) { - languageId.region = region; - } - return Intl.getCanonicalLocales((0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag)), { lang: languageId })))[0]; - } - function applyUnicodeExtensionToTag(tag, options, relevantExtensionKeys) { - var unicodeExtension; - var keywords = []; - var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); - for (var _i = 0, _a = ast.extensions; _i < _a.length; _i++) { - var ext = _a[_i]; - if (ext.type === "u") { - unicodeExtension = ext; - if (Array.isArray(ext.keywords)) - keywords = ext.keywords; - } - } - var result = /* @__PURE__ */ Object.create(null); - for (var _b = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _b < relevantExtensionKeys_1.length; _b++) { - var key = relevantExtensionKeys_1[_b]; - var value = void 0, entry = void 0; - for (var _c = 0, keywords_1 = keywords; _c < keywords_1.length; _c++) { - var keyword = keywords_1[_c]; - if (keyword[0] === key) { - entry = keyword; - value = entry[1]; - } - } - (0, ecma402_abstract_1.invariant)(key in options, "".concat(key, " must be in options")); - var optionsValue = options[key]; - if (optionsValue !== void 0) { - (0, ecma402_abstract_1.invariant)(typeof optionsValue === "string", "Value for ".concat(key, " must be a string")); - value = optionsValue; - if (entry) { - entry[1] = value; - } else { - keywords.push([key, value]); - } - } - result[key] = value; - } - if (!unicodeExtension) { - if (keywords.length) { - ast.extensions.push({ - type: "u", - keywords, - attributes: [] - }); - } - } else { - unicodeExtension.keywords = keywords; - } - result.locale = Intl.getCanonicalLocales((0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast))[0]; - return result; - } - function mergeUnicodeLanguageId(lang, script, region, variants, replacement) { - if (variants === void 0) { - variants = []; - } - if (!replacement) { - return { - lang: lang || "und", - script, - region, - variants - }; - } - return { - lang: !lang || lang === "und" ? replacement.lang : lang, - script: script || replacement.script, - region: region || replacement.region, - variants: tslib_1.__spreadArray(tslib_1.__spreadArray([], variants, true), replacement.variants, true) - }; - } - function addLikelySubtags(tag) { - var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); - var unicodeLangId = ast.lang; - var lang = unicodeLangId.lang, script = unicodeLangId.script, region = unicodeLangId.region, variants = unicodeLangId.variants; - if (script && region) { - var match_1 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, region, variants: [] })]; - if (match_1) { - var parts_1 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_1); - ast.lang = mergeUnicodeLanguageId(void 0, void 0, void 0, variants, parts_1); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - } - if (script) { - var match_2 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, variants: [] })]; - if (match_2) { - var parts_2 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_2); - ast.lang = mergeUnicodeLanguageId(void 0, void 0, region, variants, parts_2); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - } - if (region) { - var match_3 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, region, variants: [] })]; - if (match_3) { - var parts_3 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_3); - ast.lang = mergeUnicodeLanguageId(void 0, script, void 0, variants, parts_3); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - } - var match = intl_getcanonicallocales_1.likelySubtags[lang] || intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang: "und", script, variants: [] })]; - if (!match) { - throw new Error("No match for addLikelySubtags"); - } - var parts = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match); - ast.lang = mergeUnicodeLanguageId(void 0, script, region, variants, parts); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - function removeLikelySubtags(tag) { - var maxLocale = addLikelySubtags(tag); - if (!maxLocale) { - return tag; - } - maxLocale = (0, intl_getcanonicallocales_1.emitUnicodeLanguageId)(tslib_1.__assign(tslib_1.__assign({}, (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(maxLocale)), { variants: [] })); - var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); - var _a = ast.lang, lang = _a.lang, script = _a.script, region = _a.region, variants = _a.variants; - var trial = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, variants: [] })); - if (trial === maxLocale) { - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, void 0, void 0, variants) })); - } - if (region) { - var trial_1 = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, region, variants: [] })); - if (trial_1 === maxLocale) { - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, void 0, region, variants) })); - } - } - if (script) { - var trial_2 = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, variants: [] })); - if (trial_2 === maxLocale) { - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, script, void 0, variants) })); - } - } - return tag; - } - var Locale = ( - /** @class */ - function() { - function Locale2(tag, opts) { - var newTarget = this && this instanceof Locale2 ? this.constructor : void 0; - if (!newTarget) { - throw new TypeError("Intl.Locale must be called with 'new'"); - } - var relevantExtensionKeys = Locale2.relevantExtensionKeys; - var internalSlotsList = [ - "initializedLocale", - "locale", - "calendar", - "collation", - "hourCycle", - "numberingSystem" - ]; - if (relevantExtensionKeys.indexOf("kf") > -1) { - internalSlotsList.push("caseFirst"); - } - if (relevantExtensionKeys.indexOf("kn") > -1) { - internalSlotsList.push("numeric"); - } - if (tag === void 0) { - throw new TypeError("First argument to Intl.Locale constructor can't be empty or missing"); - } - if (typeof tag !== "string" && typeof tag !== "object") { - throw new TypeError("tag must be a string or object"); - } - var internalSlots; - if (typeof tag === "object" && (internalSlots = (0, get_internal_slots_1.default)(tag)) && internalSlots.initializedLocale) { - tag = internalSlots.locale; - } else { - tag = tag.toString(); - } - internalSlots = (0, get_internal_slots_1.default)(this); - var options = (0, ecma402_abstract_1.CoerceOptionsToObject)(opts); - tag = applyOptionsToTag(tag, options); - var opt = /* @__PURE__ */ Object.create(null); - var calendar = (0, ecma402_abstract_1.GetOption)(options, "calendar", "string", void 0, void 0); - if (calendar !== void 0) { - if (!UNICODE_TYPE_REGEX.test(calendar)) { - throw new RangeError("invalid calendar"); - } - } - opt.ca = calendar; - var collation = (0, ecma402_abstract_1.GetOption)(options, "collation", "string", void 0, void 0); - if (collation !== void 0) { - if (!UNICODE_TYPE_REGEX.test(collation)) { - throw new RangeError("invalid collation"); - } - } - opt.co = collation; - var hc = (0, ecma402_abstract_1.GetOption)(options, "hourCycle", "string", ["h11", "h12", "h23", "h24"], void 0); - opt.hc = hc; - var kf = (0, ecma402_abstract_1.GetOption)(options, "caseFirst", "string", ["upper", "lower", "false"], void 0); - opt.kf = kf; - var _kn = (0, ecma402_abstract_1.GetOption)(options, "numeric", "boolean", void 0, void 0); - var kn; - if (_kn !== void 0) { - kn = String(_kn); - } - opt.kn = kn; - var numberingSystem = (0, ecma402_abstract_1.GetOption)(options, "numberingSystem", "string", void 0, void 0); - if (numberingSystem !== void 0) { - if (!UNICODE_TYPE_REGEX.test(numberingSystem)) { - throw new RangeError("Invalid numberingSystem"); - } - } - opt.nu = numberingSystem; - var r = applyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys); - internalSlots.locale = r.locale; - internalSlots.calendar = r.ca; - internalSlots.collation = r.co; - internalSlots.hourCycle = r.hc; - if (relevantExtensionKeys.indexOf("kf") > -1) { - internalSlots.caseFirst = r.kf; - } - if (relevantExtensionKeys.indexOf("kn") > -1) { - internalSlots.numeric = (0, ecma402_abstract_1.SameValue)(r.kn, "true"); - } - internalSlots.numberingSystem = r.nu; - } - Locale2.prototype.maximize = function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - try { - var maximizedLocale = addLikelySubtags(locale); - return new Locale2(maximizedLocale); - } catch (e) { - return new Locale2(locale); - } - }; - Locale2.prototype.minimize = function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - try { - var minimizedLocale = removeLikelySubtags(locale); - return new Locale2(minimizedLocale); - } catch (e) { - return new Locale2(locale); - } - }; - Locale2.prototype.toString = function() { - return (0, get_internal_slots_1.default)(this).locale; - }; - Object.defineProperty(Locale2.prototype, "baseName", { - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.emitUnicodeLanguageId)((0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale)); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "calendar", { - get: function() { - return (0, get_internal_slots_1.default)(this).calendar; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "collation", { - get: function() { - return (0, get_internal_slots_1.default)(this).collation; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "hourCycle", { - get: function() { - return (0, get_internal_slots_1.default)(this).hourCycle; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "caseFirst", { - get: function() { - return (0, get_internal_slots_1.default)(this).caseFirst; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "numeric", { - get: function() { - return (0, get_internal_slots_1.default)(this).numeric; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "numberingSystem", { - get: function() { - return (0, get_internal_slots_1.default)(this).numberingSystem; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "language", { - /** - * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.language - */ - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).lang; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "script", { - /** - * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.script - */ - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).script; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "region", { - /** - * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.region - */ - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).region; - }, - enumerable: false, - configurable: true - }); - Locale2.relevantExtensionKeys = RELEVANT_EXTENSION_KEYS; - return Locale2; - }() - ); - exports.Locale = Locale; - try { - if (typeof Symbol !== "undefined") { - Object.defineProperty(Locale.prototype, Symbol.toStringTag, { - value: "Intl.Locale", - writable: false, - enumerable: false, - configurable: true - }); - } - Object.defineProperty(Locale.prototype.constructor, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true - }); - } catch (e) { - } - exports.default = Locale; - } - }); - - // node_modules/@formatjs/intl-locale/should-polyfill.js - var require_should_polyfill = __commonJS({ - "node_modules/@formatjs/intl-locale/should-polyfill.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.shouldPolyfill = void 0; - function hasIntlGetCanonicalLocalesBug() { - try { - return new Intl.Locale("und-x-private").toString() === "x-private"; - } catch (e) { - return true; - } - } - function shouldPolyfill() { - return !("Locale" in Intl) || hasIntlGetCanonicalLocalesBug(); - } - exports.shouldPolyfill = shouldPolyfill; - } - }); - - // node_modules/@formatjs/intl-locale/polyfill.js - var require_polyfill = __commonJS({ - "node_modules/@formatjs/intl-locale/polyfill.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var _1 = require_intl_locale(); - var should_polyfill_1 = require_should_polyfill(); - if ((0, should_polyfill_1.shouldPolyfill)()) { - Object.defineProperty(Intl, "Locale", { - value: _1.Locale, - writable: true, - enumerable: false, - configurable: true - }); - } - } - }); - - // shared/js/polyfill.js - var import_polyfill = __toESM(require_polyfill()); -})(); diff --git a/package-lock.json b/package-lock.json index 18c007a54436..5273b8f69aca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", - "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1724449523" + "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" }, "devDependencies": { "@rollup/plugin-json": "^4.1.0", @@ -76,24 +76,24 @@ } }, "node_modules/@duckduckgo/privacy-dashboard": { - "resolved": "git+ssh://git@github.com/duckduckgo/privacy-dashboard.git#597bffc321a8f4b8d23b13aa0145406c393c0d8e", + "resolved": "git+ssh://git@github.com/duckduckgo/privacy-dashboard.git#e1ec13370ac302307e7d5cb172f45106da911c9e", "engines": { - "node": ">=18.0.0", + "node": ">=22.0.0", "npm": ">=9.0.0" } }, "node_modules/@duckduckgo/privacy-reference-tests": { - "resolved": "git+ssh://git@github.com/duckduckgo/privacy-reference-tests.git#6133e7d9d9cd5f1b925cab1971b4d785dc639df7", + "resolved": "git+ssh://git@github.com/duckduckgo/privacy-reference-tests.git#a75e09ff6bfff0709e6a457f1c3478326cbb3dc5", "license": "Apache-2.0" }, "node_modules/@ghostery/adblocker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ghostery/adblocker/-/adblocker-2.1.1.tgz", - "integrity": "sha512-FL4yWrpNTCmtbAfeLotUoo94ZyNqHdZpZRo4Qlk0guPzDGcOtW4/c84UzS9D/Z9Z4H3nWSCrW0q38pjwAbDykA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@ghostery/adblocker/-/adblocker-2.3.1.tgz", + "integrity": "sha512-6k8ZFHjYII54a32qrKwhnTbrPfR+KPgM6GlyAiEm8OCZoewN1cfBfSw5GVpzaAB2yJ4DzazmP8Wq/UBvEk5mHg==", "license": "MPL-2.0", "dependencies": { - "@ghostery/adblocker-content": "^2.1.1", - "@ghostery/adblocker-extended-selectors": "^2.1.1", + "@ghostery/adblocker-content": "^2.3.1", + "@ghostery/adblocker-extended-selectors": "^2.3.1", "@remusao/guess-url-type": "^1.3.0", "@remusao/small": "^1.2.1", "@remusao/smaz": "^1.9.1", @@ -101,24 +101,24 @@ } }, "node_modules/@ghostery/adblocker-content": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ghostery/adblocker-content/-/adblocker-content-2.1.1.tgz", - "integrity": "sha512-1DKHmPnlQleXapaL36xZOwwZmpdbjMP/IcWdTTzyriyCDIFlSwBDT1DJ3xg0TK61ahZMEwz1MnTGM6X99z/5rQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@ghostery/adblocker-content/-/adblocker-content-2.3.1.tgz", + "integrity": "sha512-8ZTY1sEE218b0EMk3Q9fv/cWwUxunSCyBOaKuviEmJY5EyvPa1VbGPuTq/Qdvo1kduD8nLEzCwgWhcT3F3TT0Q==", "license": "MPL-2.0", "dependencies": { - "@ghostery/adblocker-extended-selectors": "^2.1.1" + "@ghostery/adblocker-extended-selectors": "^2.3.1" } }, "node_modules/@ghostery/adblocker-extended-selectors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ghostery/adblocker-extended-selectors/-/adblocker-extended-selectors-2.1.1.tgz", - "integrity": "sha512-jEHjU2CarS2MtRYfm/6iTKMS1DVzepuwXSMKg1zTyHl+u4ZKvKNYFK7plD0nUlL5a8akyRkYwLheXnKsW3nChQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@ghostery/adblocker-extended-selectors/-/adblocker-extended-selectors-2.3.1.tgz", + "integrity": "sha512-hDNiOd/1V4b6NTkNnMkZUUmhMwwo8+5rpSUtQUFzCCCzy+v5izHt4rBr2RGeK5L1pNq0NbFxZJjBHFDbiQiS1A==", "license": "MPL-2.0" }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, "license": "MIT", "dependencies": { @@ -282,9 +282,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", - "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -429,9 +429,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", + "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", "dev": true, "license": "MIT", "dependencies": { @@ -518,13 +518,13 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.9", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz", + "integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -647,9 +647,9 @@ } }, "node_modules/terser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", - "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -666,18 +666,18 @@ } }, "node_modules/tldts-core": { - "version": "6.1.64", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.64.tgz", - "integrity": "sha512-uqnl8vGV16KsyflHOzqrYjjArjfXaU6rMPXYy2/ZWoRKCkXtghgB4VwTDXUG+t0OTGeSewNAG31/x1gCTfLt+Q==", + "version": "6.1.68", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.68.tgz", + "integrity": "sha512-85TdlS/DLW/gVdf2oyyzqp3ocS30WxjaL4la85EArl9cHUR/nizifKAJPziWewSZjDZS71U517/i6ciUeqtB5Q==", "license": "MIT" }, "node_modules/tldts-experimental": { - "version": "6.1.64", - "resolved": "https://registry.npmjs.org/tldts-experimental/-/tldts-experimental-6.1.64.tgz", - "integrity": "sha512-Lm6dwThCCmUecyvOJwTfZgYRP9JB6UDam//96OSvZffBtBA3GuwucIiycLT5yO5nz0ZAGV37FF1hef2HE0K8BQ==", + "version": "6.1.68", + "resolved": "https://registry.npmjs.org/tldts-experimental/-/tldts-experimental-6.1.68.tgz", + "integrity": "sha512-cQ7OdvIpATiNKu3bdyaDzn2bLqg6Ln3BpyGLyLwYfEcaNY3rXsXi+5apxtzfH/+KT30+gzN3gswdsdF+KFHflw==", "license": "MIT", "dependencies": { - "tldts-core": "^6.1.64" + "tldts-core": "^6.1.68" } }, "node_modules/undici-types": { diff --git a/package.json b/package.json index 1cc8abc7c538..fec54817138f 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,6 @@ "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", - "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1724449523" + "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" } } From ad5e0d989117fa7b6c26c9bb4f8dfad756f3627f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gonz=C3=A1lez?= Date: Thu, 19 Dec 2024 13:03:19 +0100 Subject: [PATCH 15/32] GHA: Improve PR review notifications (#5409) Task/Issue URL: https://app.asana.com/0/0/1208984904365490/f ### Description Use remote workflow to post comments in an Asana task based on the review state. Depends on https://github.com/duckduckgo/native-github-asana-sync/pull/6 being merged and relased ### Steps to test this PR See https://github.com/duckduckgo/Android/actions/runs/12400985000/job/34619364179?pr=5274 --- .github/workflows/action-pr-approved.yaml | 17 ----------------- .github/workflows/pr-review-notifications.yaml | 6 +++--- 2 files changed, 3 insertions(+), 20 deletions(-) delete mode 100644 .github/workflows/action-pr-approved.yaml diff --git a/.github/workflows/action-pr-approved.yaml b/.github/workflows/action-pr-approved.yaml deleted file mode 100644 index d9289e66cad8..000000000000 --- a/.github/workflows/action-pr-approved.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Pull Request Reviewed - -on: - pull_request_review: - types: [submitted] - -jobs: - pr-reviewed: - if: github.event.review.state == 'approved' - runs-on: ubuntu-latest - steps: - - name: Update Asana task -> PR approved - uses: duckduckgo/native-github-asana-sync@v1.1 - with: - asana-pat: ${{ secrets.GH_ASANA_SECRET }} - trigger-phrase: "Task/Issue URL:" - action: 'notify-pr-approved' \ No newline at end of file diff --git a/.github/workflows/pr-review-notifications.yaml b/.github/workflows/pr-review-notifications.yaml index fc2c2b9d745c..406495034b5b 100644 --- a/.github/workflows/pr-review-notifications.yaml +++ b/.github/workflows/pr-review-notifications.yaml @@ -1,4 +1,4 @@ -name: Pull Request Reviewed -> Asana Sync +name: Pull Request Reviewed -> Sync With Asana on: pull_request_review: @@ -6,8 +6,8 @@ on: jobs: pr-reviewed: - name: Update Asana task -> PR reviewed - uses: duckduckgo/native-github-asana-sync/.github/workflows/pr-review-notifications.yml@david/improve-pr-notifications + name: Add PR reviewed comment + uses: duckduckgo/native-github-asana-sync/.github/workflows/pr-review-notifications.yml@v1.4 with: trigger-phrase: "Task/Issue URL:" secrets: From 23231b655477360ae10b4a334a6386b1710bd079 Mon Sep 17 00:00:00 2001 From: Dax Mobile <44842493+daxmobile@users.noreply.github.com> Date: Thu, 19 Dec 2024 23:06:52 +1100 Subject: [PATCH 16/32] Update content scope scripts to version 6.43.0 (#5403) - Automated content scope scripts dependency update This PR updates the content scope scripts dependency to the latest available version and copies the necessary files. If tests have failed, see https://app.asana.com/0/1202561462274611/1203986899650836/f for further information on what to do next. - [ ] All tests must pass Co-authored-by: daxmobile --- .../pages/duckplayer/{js => dist}/index.css | 0 .../pages/duckplayer/{js => dist}/index.js | 22 +++++----- .../pages/duckplayer/{js => dist}/inline.js | 2 +- .../{js => dist}/mobile-bg-GCRU67TC.jpg | Bin .../{js => dist}/player-bg-F7QLKTXS.jpg | Bin .../build/android/pages/duckplayer/index.html | 6 +-- .../android/pages/duckplayer/js/storage.js | 32 -------------- .../android/pages/duckplayer/js/utils.js | 40 ------------------ package-lock.json | 4 +- package.json | 2 +- 10 files changed, 18 insertions(+), 90 deletions(-) rename node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/{js => dist}/index.css (100%) rename node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/{js => dist}/index.js (99%) rename node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/{js => dist}/inline.js (90%) rename node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/{js => dist}/mobile-bg-GCRU67TC.jpg (100%) rename node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/{js => dist}/player-bg-F7QLKTXS.jpg (100%) delete mode 100644 node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/storage.js delete mode 100644 node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/utils.js diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.css b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.css similarity index 100% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.css rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.css diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.js similarity index 99% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.js rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.js index 4999e435b990..8119bf66cd0a 100644 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.js +++ b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.js @@ -1942,7 +1942,7 @@ return null; } - // pages/duckplayer/src/locales/en/duckplayer.json + // pages/duckplayer/public/locales/en/duckplayer.json var duckplayer_default = { smartling: { string_format: "icu", @@ -2004,7 +2004,7 @@ this.focusMode = focusMode; } /** - * @param {keyof import("../../../types/duckplayer").DuckPlayerPageSettings} named + * @param {keyof import("../types/duckplayer.js").DuckPlayerPageSettings} named * @param {{state: 'enabled' | 'disabled'} | null | undefined} settings * @return {Settings} */ @@ -2092,12 +2092,12 @@ }; } var MessagingContext2 = G( - /** @type {import("../src/js/index.js").DuckplayerPage} */ + /** @type {import("../src/index.js").DuckplayerPage} */ {} ); var useMessaging = () => x2(MessagingContext2); var TelemetryContext = G( - /** @type {import("../src/js/index.js").Telemetry} */ + /** @type {import("../src/index.js").Telemetry} */ {} ); var useTelemetry = () => x2(TelemetryContext); @@ -2858,7 +2858,7 @@ } }; - // pages/duckplayer/src/js/utils.js + // pages/duckplayer/src/utils.js function createYoutubeURLForError(href, urlBase) { const valid = VideoParams.forWatchPage(href); if (!valid) return null; @@ -3360,7 +3360,7 @@ } } - // pages/duckplayer/src/js/storage.js + // pages/duckplayer/src/storage.js function deleteStorage(subject) { Object.keys(subject).forEach((key) => { if (key.indexOf("yt-player") === 0) { @@ -3391,7 +3391,7 @@ }); } - // pages/duckplayer/src/js/index.js + // pages/duckplayer/src/index.js var DuckplayerPage = class { /** * @param {import("@duckduckgo/messaging").Messaging} messaging @@ -3403,7 +3403,7 @@ /** * This will be sent if the application has loaded, but a client-side error * has occurred that cannot be recovered from - * @returns {Promise} + * @returns {Promise} */ initialSetup() { if (this.injectName === "integration") { @@ -3427,7 +3427,7 @@ /** * This is sent when the user wants to set Duck Player as the default. * - * @param {import("../../../../types/duckplayer").UserValues} userValues + * @param {import("../types/duckplayer.ts").UserValues} userValues */ setUserValues(userValues) { return this.messaging.request("setUserValues", userValues); @@ -3467,7 +3467,7 @@ * } * ``` * - * @param {(value: import("../../../../types/duckplayer").UserValues) => void} cb + * @param {(value: import("../types/duckplayer.ts").UserValues) => void} cb */ onUserValuesChanged(cb) { return this.messaging.subscribe("onUserValuesChanged", cb); @@ -3501,7 +3501,7 @@ this.messaging = messaging2; } /** - * @param {import('../../../../types/duckplayer').TelemetryEvent} event + * @param {import('../types/duckplayer.ts').TelemetryEvent} event * @internal */ _event(event) { diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/inline.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/inline.js similarity index 90% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/inline.js rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/inline.js index 6f18bb2bfd2e..41908278e673 100644 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/inline.js +++ b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/inline.js @@ -1,6 +1,6 @@ "use strict"; (() => { - // pages/duckplayer/src/js/inline.js + // pages/duckplayer/src/inline.js var param = new URLSearchParams(window.location.search).get("platform"); if (isAllowed(param)) { document.documentElement.dataset.platform = String(param); diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/mobile-bg-GCRU67TC.jpg b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/mobile-bg-GCRU67TC.jpg similarity index 100% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/mobile-bg-GCRU67TC.jpg rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/mobile-bg-GCRU67TC.jpg diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/player-bg-F7QLKTXS.jpg b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/player-bg-F7QLKTXS.jpg similarity index 100% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/player-bg-F7QLKTXS.jpg rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/player-bg-F7QLKTXS.jpg diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html index f48bb6eef269..0c4099075b32 100644 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html +++ b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html @@ -4,11 +4,11 @@ Duck Player - - + +
    - + diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/storage.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/storage.js deleted file mode 100644 index be18978d7789..000000000000 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/storage.js +++ /dev/null @@ -1,32 +0,0 @@ -function deleteStorage(subject) { - Object.keys(subject).forEach((key) => { - if (key.indexOf('yt-player') === 0) { - return; - } - subject.removeItem(key); - }); -} - -function deleteAllCookies() { - const cookies = document.cookie.split(';'); - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i]; - const eqPos = cookie.indexOf('='); - const name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie; - document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;domain=youtube-nocookie.com;path=/;'; - } -} - -export function initStorage() { - window.addEventListener('unload', () => { - deleteStorage(localStorage); - deleteStorage(sessionStorage); - deleteAllCookies(); - }); - - window.addEventListener('load', () => { - deleteStorage(localStorage); - deleteStorage(sessionStorage); - deleteAllCookies(); - }); -} diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/utils.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/utils.js deleted file mode 100644 index 19781547aeab..000000000000 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/utils.js +++ /dev/null @@ -1,40 +0,0 @@ -import { VideoParams } from 'injected/src/features/duckplayer/util.js'; - -/** - * @param {string} href - * @param {string} urlBase - * @return {null | string} - */ -export function createYoutubeURLForError(href, urlBase) { - const valid = VideoParams.forWatchPage(href); - if (!valid) return null; - - // this will not throw, since it was guarded above - const original = new URL(href); - - // for now, we're only intercepting clicks when `emb_err_woyt` is present - // this may not be enough to cover all situations, but it solves our immediate - // problems whilst keeping the blast radius low - if (original.searchParams.get('feature') !== 'emb_err_woyt') return null; - - // if we get this far, we think a click is occurring that would cause a navigation loop - // construct the 'next' url - const url = new URL(urlBase); - url.searchParams.set('v', valid.id); - - if (typeof valid.time === 'string') { - url.searchParams.set('t', valid.time); - } - - return url.toString(); -} - -/** - * @param {string|null|undefined} iframeTitle - * @return {string | null} - */ -export function getValidVideoTitle(iframeTitle) { - if (typeof iframeTitle !== 'string') return null; - if (iframeTitle === 'YouTube') return null; - return iframeTitle.replace(/ - YouTube$/g, ''); -} diff --git a/package-lock.json b/package-lock.json index 5273b8f69aca..3dbb4812b8bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "dependencies": { "@duckduckgo/autoconsent": "^12.3.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", - "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", + "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" }, @@ -63,7 +63,7 @@ "license": "Apache-2.0" }, "node_modules/@duckduckgo/content-scope-scripts": { - "resolved": "git+ssh://git@github.com/duckduckgo/content-scope-scripts.git#c4bb146afdf0c7a93fb9a7d95b1cb255708a470d", + "resolved": "git+ssh://git@github.com/duckduckgo/content-scope-scripts.git#bc808eb735d9eb72d5c54cf2452b104b6a370e25", "license": "Apache-2.0", "workspaces": [ "injected", diff --git a/package.json b/package.json index fec54817138f..82ee56ef9cc0 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "dependencies": { "@duckduckgo/autoconsent": "^12.3.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", - "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", + "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" } From b7af5ce5a6b9c994d64094345591f6f80eadc30e Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Thu, 19 Dec 2024 17:19:59 +0100 Subject: [PATCH 17/32] Update Settings: Update VPN settings item (#5394) Task/Issue URL: https://app.asana.com/0/0/1208966262488271/f ### Description Updates the VPN settings item to match new designs. As the new designs require us to know more about the subscription state we need to expose more Subscription Statuses so we can reflect that in the settings screen like the "Waiting" state that is equivalent to our new "Activating" state. The biggest thing to note is that now it's not like it used to be where we had just 2 states, locked and unlocked, we now more readily show the user the VPN item and what it's subscription state is. I'm still waiting on answers regarding the [onboarded state](https://app.asana.com/0/0/1208847942321390/1208973040958179/f) And [connecting state ](https://app.asana.com/0/0/1208847942321390/1208973157895050/f) but I can always circle back later and address these as necessary. [Designs](https://www.figma.com/design/CjH849hL53lhsPlf6Ufeo4/%E2%9A%99%EF%B8%8F-Browser-Settings-Documentation-(All-Platforms)?node-id=7605-431390&node-type=instance&t=ZKIMXkdZqzh5gEjU-11) ### Steps to test this PR Prerequisite: Enable `newSettings` feature toggle Prerequisite: Apply the patch in the [Asana task](https://app.asana.com/0/1207908166761516/1208966262488271/f) Note: Only the VPN item and possibly the Settings item will be seen, depending on the different states. PIR, ITR are not included as part of this PR and so are not visible. _VPN Subscribed and Off_ - [x] Open New Settings - [x] Verify VPN item is visible with colored icon and status is off - [x] Click VPN item - [x] VPN settings screen should open _VPN Subscribed and On_ - [x] In `NetworkProtectionStateImpl` change ln 98 to `return flowOf(CONNECTED)` - [x] Open New Settings - [x] Verify VPN item is visible with colored icon and status is on - [x] Click VPN item - [x] VPN settings screen should open _Unsubscribed_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.UNKNOWN` - [x] Open New Settings - [x] Verify VPN item is not visible _VPN Expired_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.EXPIRED` - [x] Open New Settings - [x] Verify VPN item is visible with grey icon and is not clickable, and status is off - [x] Click VPN item - [x] Nothing should happen _PPro Activating_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.WAITING` - [x] Open New Settings - [x] Verify VPN item is visible with grey icon and status is off - [x] Click VPN item - [x] Nothing should happen _No Entitlement_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.AUTO_RENEWABLE` - [x] In `RealSubscriptions` change ln 77 to `return flowOf(listOf())` - [x] Open New Settings - [x] Verify VPN item is not visible _Legacy Support_ - [x] Turn off `newSettings` - [x] Verify old VPN settings works by repeating steps above ### UI changes | Before | After | | --- | --- | | ![old_vpn_active](https://github.com/user-attachments/assets/06e61f5a-7189-4ae2-b4a9-53e7f54f0d14) | ![vpn_subscribed_on](https://github.com/user-attachments/assets/7d679004-a5b3-46c9-a7d0-d6d1aa002880) | | ![old_vpn_disconnected](https://github.com/user-attachments/assets/a49017fe-ffb2-4297-a6ed-09602c758697) | ![vpn_subscribed_off](https://github.com/user-attachments/assets/6de29cef-ba0e-4d98-b7e4-6534288dd6ad) | | ![old_vpn_waiting](https://github.com/user-attachments/assets/f74e7078-af1c-4293-9493-16ecabdeb8a1) | ![vpn_activating](https://github.com/user-attachments/assets/69b8ff57-e061-4489-b6bd-98cdcef54359) | | ![old_vpn_ineligible](https://github.com/user-attachments/assets/434af3d3-3fc8-4e6b-acfd-569cda207cac) | ![new_vpn_ineligible](https://github.com/user-attachments/assets/4299bebc-911b-4f02-9eca-ac0a8829106a) | ![old_no_subscription](https://github.com/user-attachments/assets/1a47bddc-f8b7-435c-8a65-8117f1d8c68e) | ![vpn_no_subscription](https://github.com/user-attachments/assets/0510ac27-13ce-4fcc-9eb4-c560a1d4d115) | --- .../api/NetworkProtectionState.kt | 3 + .../subscription/NetpSubscriptionManager.kt | 36 +++- .../settings/LegacyProSettingNetPView.kt | 123 +++++++++++ .../settings/LegacyProSettingNetPViewModel.kt | 163 ++++++++++++++ .../NetworkProtectionSettingsState.kt | 41 ++++ .../NetworkProtectionSettingsStateImpl.kt | 71 ++++++ .../settings/ProSettingNetPView.kt | 36 ++-- .../settings/ProSettingNetPViewModel.kt | 77 +++---- .../settings/SubsSettingsPlugin.kt | 9 +- .../res/layout/legacy_view_settings_netp.xml | 25 +++ .../main/res/layout/view_settings_netp.xml | 17 +- .../LegacyProSettingNetPViewModelTest.kt | 204 ++++++++++++++++++ .../NetworkProtectionSettingsStateImplTest.kt | 124 +++++++++++ .../settings/ProSettingNetPViewModelTest.kt | 85 +++----- 14 files changed, 869 insertions(+), 145 deletions(-) create mode 100644 network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPView.kt create mode 100644 network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModel.kt create mode 100644 network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsState.kt create mode 100644 network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImpl.kt create mode 100644 network-protection/network-protection-impl/src/main/res/layout/legacy_view_settings_netp.xml create mode 100644 network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModelTest.kt create mode 100644 network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImplTest.kt diff --git a/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt b/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt index 1c67dee66dde..2119466a3fb4 100644 --- a/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt +++ b/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt @@ -91,5 +91,8 @@ interface NetworkProtectionState { CONNECTED, CONNECTING, DISCONNECTED, + ; + + fun isConnected(): Boolean = this == CONNECTED } } diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt index 643b764de7d5..7d45824807f6 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt @@ -19,6 +19,7 @@ package com.duckduckgo.networkprotection.impl.subscription import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.di.scopes.AppScope import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus +import com.duckduckgo.settings.api.NewSettingsFeature import com.duckduckgo.subscriptions.api.Product.NetP import com.duckduckgo.subscriptions.api.SubscriptionStatus import com.duckduckgo.subscriptions.api.Subscriptions @@ -37,6 +38,8 @@ interface NetpSubscriptionManager { EXPIRED, SIGNED_OUT, INACTIVE, + WAITING, + INELIGIBLE, } } @@ -52,6 +55,7 @@ fun VpnStatus.isExpired(): Boolean { class RealNetpSubscriptionManager @Inject constructor( private val subscriptions: Subscriptions, private val dispatcherProvider: DispatcherProvider, + private val newSettingsFeature: NewSettingsFeature, ) : NetpSubscriptionManager { override suspend fun getVpnStatus(): VpnStatus { @@ -71,15 +75,29 @@ class RealNetpSubscriptionManager @Inject constructor( private fun hasValidEntitlementFlow(): Flow = subscriptions.getEntitlementStatus().map { it.contains(NetP) } private suspend fun getVpnStatusInternal(hasValidEntitlement: Boolean): VpnStatus { - val subscriptionState = subscriptions.getSubscriptionStatus() - return when (subscriptionState) { - SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> VpnStatus.EXPIRED - SubscriptionStatus.UNKNOWN -> VpnStatus.SIGNED_OUT - else -> { - if (hasValidEntitlement) { - VpnStatus.ACTIVE - } else { - VpnStatus.INACTIVE + return if (newSettingsFeature.self().isEnabled()) { + when { + !hasValidEntitlement -> VpnStatus.INELIGIBLE + else -> { + when (subscriptions.getSubscriptionStatus()) { + SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> VpnStatus.EXPIRED + SubscriptionStatus.UNKNOWN -> VpnStatus.SIGNED_OUT + SubscriptionStatus.AUTO_RENEWABLE, SubscriptionStatus.NOT_AUTO_RENEWABLE, SubscriptionStatus.GRACE_PERIOD -> VpnStatus.ACTIVE + SubscriptionStatus.WAITING -> VpnStatus.WAITING + } + } + } + } else { + val subscriptionState = subscriptions.getSubscriptionStatus() + when (subscriptionState) { + SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> VpnStatus.EXPIRED + SubscriptionStatus.UNKNOWN -> VpnStatus.SIGNED_OUT + else -> { + if (hasValidEntitlement) { + VpnStatus.ACTIVE + } else { + VpnStatus.INACTIVE + } } } } diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPView.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPView.kt new file mode 100644 index 000000000000..99b2edc9d248 --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPView.kt @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.networkprotection.impl.subscription.settings + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeViewModelStoreOwner +import com.duckduckgo.anvil.annotations.InjectWith +import com.duckduckgo.common.ui.view.gone +import com.duckduckgo.common.ui.view.show +import com.duckduckgo.common.ui.viewbinding.viewBinding +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.mobile.android.R as CommonR +import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.networkprotection.impl.databinding.LegacyViewSettingsNetpBinding +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command.OpenNetPScreen +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Factory +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Pending +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.ShowState +import dagger.android.support.AndroidSupportInjection +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +@InjectWith(ViewScope::class) +class LegacyProSettingNetPView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : FrameLayout(context, attrs, defStyle) { + + @Inject + lateinit var viewModelFactory: Factory + + @Inject + lateinit var globalActivityStarter: GlobalActivityStarter + + private var coroutineScope: CoroutineScope? = null + + private val binding: LegacyViewSettingsNetpBinding by viewBinding() + + private val viewModel: LegacyProSettingNetPViewModel by lazy { + ViewModelProvider(findViewTreeViewModelStoreOwner()!!, viewModelFactory)[LegacyProSettingNetPViewModel::class.java] + } + + override fun onAttachedToWindow() { + AndroidSupportInjection.inject(this) + super.onAttachedToWindow() + + findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) + + binding.netpPSetting.setClickListener { + viewModel.onNetPSettingClicked() + } + + @SuppressLint("NoHardcodedCoroutineDispatcher") + coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + + viewModel.viewState + .onEach { updateNetPSettings(it.networkProtectionEntryState) } + .launchIn(coroutineScope!!) + + viewModel.commands() + .onEach { processCommands(it) } + .launchIn(coroutineScope!!) + } + + private fun updateNetPSettings(networkProtectionEntryState: NetPEntryState) { + with(binding.netpPSetting) { + when (networkProtectionEntryState) { + Hidden -> this.gone() + Pending -> { + this.show() + this.setLeadingIconResource(CommonR.drawable.ic_check_grey_round_16) + } + is ShowState -> { + this.show() + this.setLeadingIconResource(networkProtectionEntryState.icon) + } + } + } + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + findViewTreeLifecycleOwner()?.lifecycle?.removeObserver(viewModel) + coroutineScope?.cancel() + coroutineScope = null + } + + private fun processCommands(command: Command) { + when (command) { + is OpenNetPScreen -> { + globalActivityStarter.start(context, command.params) + } + } + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModel.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModel.kt new file mode 100644 index 000000000000..686f54ddc531 --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModel.kt @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.networkprotection.impl.subscription.settings + +import android.annotation.SuppressLint +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import com.duckduckgo.app.statistics.pixels.Pixel +import com.duckduckgo.common.utils.DispatcherProvider +import com.duckduckgo.mobile.android.R as CommonR +import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED +import com.duckduckgo.networkprotection.impl.R +import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command.OpenNetPScreen +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Pending +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.ShowState +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch +import logcat.logcat + +@SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle +class LegacyProSettingNetPViewModel( + private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionState: NetworkProtectionState, + private val dispatcherProvider: DispatcherProvider, + private val pixel: Pixel, +) : ViewModel(), DefaultLifecycleObserver { + + data class ViewState(val networkProtectionEntryState: NetPEntryState = Hidden) + + sealed class Command { + data class OpenNetPScreen(val params: ActivityParams) : Command() + } + + sealed class NetPEntryState { + data object Hidden : NetPEntryState() + data object Pending : NetPEntryState() + data class ShowState( + @DrawableRes val icon: Int, + @StringRes val subtitle: Int, + ) : NetPEntryState() + } + + private val command = Channel(1, BufferOverflow.DROP_OLDEST) + internal fun commands(): Flow = command.receiveAsFlow() + private val _viewState = MutableStateFlow(ViewState()) + val viewState = _viewState.asStateFlow() + + override fun onStart(owner: LifecycleOwner) { + super.onStart(owner) + + viewModelScope.launch { + combine(networkProtectionAccessState.getStateFlow(), networkProtectionState.getConnectionStateFlow()) { accessState, connectionState -> + _viewState.emit( + viewState.value.copy( + networkProtectionEntryState = getNetworkProtectionEntryState(accessState, connectionState), + ), + ) + }.flowOn(dispatcherProvider.main()).launchIn(viewModelScope) + } + } + + fun onNetPSettingClicked() { + viewModelScope.launch { + val screen = networkProtectionAccessState.getScreenForCurrentState() + screen?.let { + command.send(OpenNetPScreen(screen)) + pixel.fire(NETP_SETTINGS_PRESSED) + } ?: logcat { "Get screen for current NetP state is null" } + } + } + + private suspend fun getNetworkProtectionEntryState( + accessState: NetPAccessState, + networkProtectionConnectionState: ConnectionState, + ): NetPEntryState { + return when (accessState) { + is NetPAccessState.UnLocked -> { + if (networkProtectionState.isOnboarded()) { + val subtitle = when (networkProtectionConnectionState) { + CONNECTED -> R.string.netpSubscriptionSettingsConnected + CONNECTING -> R.string.netpSubscriptionSettingsConnecting + else -> R.string.netpSubscriptionSettingsDisconnected + } + + val netPItemIcon = if (networkProtectionConnectionState != DISCONNECTED) { + CommonR.drawable.ic_check_green_round_16 + } else { + CommonR.drawable.ic_exclamation_yellow_16 + } + + ShowState( + icon = netPItemIcon, + subtitle = subtitle, + ) + } else { + Pending + } + } + + NetPAccessState.Locked -> Hidden + } + } + + @Suppress("UNCHECKED_CAST") + class Factory @Inject constructor( + private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionState: NetworkProtectionState, + private val dispatcherProvider: DispatcherProvider, + private val pixel: Pixel, + ) : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return with(modelClass) { + when { + isAssignableFrom(LegacyProSettingNetPViewModel::class.java) -> LegacyProSettingNetPViewModel( + networkProtectionAccessState, + networkProtectionState, + dispatcherProvider, + pixel, + ) + + else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") + } + } as T + } + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsState.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsState.kt new file mode 100644 index 000000000000..9d4df6906dec --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsState.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.networkprotection.impl.subscription.settings + +import kotlinx.coroutines.flow.Flow + +interface NetworkProtectionSettingsState { + + /** + * Returns a flow of the visibility states of NetP + * The caller DOES NOT need to specify the dispatcher when calling this method + */ + suspend fun getNetPSettingsStateFlow(): Flow + + /** + * If the Netp Settings Item should be visible to the user and it's current subscription state + */ + sealed interface NetPSettingsState { + + sealed interface Visible : NetPSettingsState { + data object Subscribed : Visible + data object Expired : Visible + data object Activating : Visible + } + data object Hidden : NetPSettingsState + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImpl.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImpl.kt new file mode 100644 index 000000000000..a129e1208617 --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImpl.kt @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.networkprotection.impl.subscription.settings + +import com.duckduckgo.common.utils.DispatcherProvider +import com.duckduckgo.di.scopes.AppScope +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.ACTIVE +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.EXPIRED +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.INACTIVE +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.INELIGIBLE +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.SIGNED_OUT +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.WAITING +import com.duckduckgo.networkprotection.impl.subscription.isActive +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Expired +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Subscribed +import com.squareup.anvil.annotations.ContributesBinding +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map + +@ContributesBinding(AppScope::class) +class NetworkProtectionSettingsStateImpl @Inject constructor( + private val dispatcherProvider: DispatcherProvider, + private val networkProtectionState: NetworkProtectionState, + private val netpSubscriptionManager: NetpSubscriptionManager, +) : NetworkProtectionSettingsState { + + override suspend fun getNetPSettingsStateFlow(): Flow = + netpSubscriptionManager.vpnStatus().map { status -> + if (!status.isActive()) { + // if entitlement check succeeded and not an active subscription then reset state + handleRevokedVPNState() + } + + mapToSettingsState(status) + }.flowOn(dispatcherProvider.io()) + + private fun mapToSettingsState(vpnStatus: VpnStatus): NetPSettingsState = when (vpnStatus) { + ACTIVE -> Subscribed + INACTIVE, EXPIRED -> Expired + WAITING -> Activating + SIGNED_OUT, INELIGIBLE -> Hidden + } + + private suspend fun handleRevokedVPNState() { + if (networkProtectionState.isEnabled()) { + networkProtectionState.stop() + } + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt index c82423994b22..dcfc63c9974c 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt @@ -20,24 +20,25 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.widget.FrameLayout +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.common.ui.view.gone -import com.duckduckgo.common.ui.view.show import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.di.scopes.ViewScope -import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.networkprotection.impl.R import com.duckduckgo.networkprotection.impl.databinding.ViewSettingsNetpBinding import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command.OpenNetPScreen import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Factory import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Expired import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Hidden -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Pending -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.ShowState +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Subscribed import dagger.android.support.AndroidSupportInjection import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -74,10 +75,6 @@ class ProSettingNetPView @JvmOverloads constructor( findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) - binding.netpPSetting.setClickListener { - viewModel.onNetPSettingClicked() - } - @SuppressLint("NoHardcodedCoroutineDispatcher") coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) @@ -93,14 +90,21 @@ class ProSettingNetPView @JvmOverloads constructor( private fun updateNetPSettings(networkProtectionEntryState: NetPEntryState) { with(binding.netpPSetting) { when (networkProtectionEntryState) { - Hidden -> this.gone() - Pending -> { - this.show() - this.setLeadingIconResource(CommonR.drawable.ic_check_grey_round_16) + Hidden -> isGone = true + Activating, + Expired, + -> { + isVisible = true + isClickable = false + setLeadingIconResource(R.drawable.ic_vpn_grayscale_color_24) + setStatus(isOn = false) } - is ShowState -> { - this.show() - this.setLeadingIconResource(networkProtectionEntryState.icon) + is Subscribed -> { + isVisible = true + isClickable = true + setClickListener { viewModel.onNetPSettingClicked() } + setLeadingIconResource(R.drawable.ic_vpn_color_24) + setStatus(isOn = networkProtectionEntryState.isActive) } } } diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt index 866d8ca0887f..303b10d7af77 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt @@ -17,8 +17,6 @@ package com.duckduckgo.networkprotection.impl.subscription.settings import android.annotation.SuppressLint -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel @@ -26,21 +24,17 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.common.utils.DispatcherProvider -import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState -import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState import com.duckduckgo.networkprotection.api.NetworkProtectionState import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState -import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED -import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING -import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED -import com.duckduckgo.networkprotection.impl.R import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Expired +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Subscribed import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command.OpenNetPScreen -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Hidden -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Pending -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.ShowState import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.Channel @@ -56,13 +50,14 @@ import logcat.logcat @SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle class ProSettingNetPViewModel( - private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionSettingsState: NetworkProtectionSettingsState, private val networkProtectionState: NetworkProtectionState, + private val networkProtectionAccessState: NetworkProtectionAccessState, private val dispatcherProvider: DispatcherProvider, private val pixel: Pixel, ) : ViewModel(), DefaultLifecycleObserver { - data class ViewState(val networkProtectionEntryState: NetPEntryState = Hidden) + data class ViewState(val networkProtectionEntryState: NetPEntryState = NetPEntryState.Hidden) sealed class Command { data class OpenNetPScreen(val params: ActivityParams) : Command() @@ -70,11 +65,9 @@ class ProSettingNetPViewModel( sealed class NetPEntryState { data object Hidden : NetPEntryState() - data object Pending : NetPEntryState() - data class ShowState( - @DrawableRes val icon: Int, - @StringRes val subtitle: Int, - ) : NetPEntryState() + data class Subscribed(val isActive: Boolean) : NetPEntryState() + data object Expired : NetPEntryState() + data object Activating : NetPEntryState() } private val command = Channel(1, BufferOverflow.DROP_OLDEST) @@ -86,7 +79,10 @@ class ProSettingNetPViewModel( super.onStart(owner) viewModelScope.launch { - combine(networkProtectionAccessState.getStateFlow(), networkProtectionState.getConnectionStateFlow()) { accessState, connectionState -> + combine( + networkProtectionSettingsState.getNetPSettingsStateFlow(), + networkProtectionState.getConnectionStateFlow(), + ) { accessState, connectionState -> _viewState.emit( viewState.value.copy( networkProtectionEntryState = getNetworkProtectionEntryState(accessState, connectionState), @@ -106,42 +102,22 @@ class ProSettingNetPViewModel( } } - private suspend fun getNetworkProtectionEntryState( - accessState: NetPAccessState, + private fun getNetworkProtectionEntryState( + settingsState: NetPSettingsState, networkProtectionConnectionState: ConnectionState, - ): NetPEntryState { - return when (accessState) { - is NetPAccessState.UnLocked -> { - if (networkProtectionState.isOnboarded()) { - val subtitle = when (networkProtectionConnectionState) { - CONNECTED -> R.string.netpSubscriptionSettingsConnected - CONNECTING -> R.string.netpSubscriptionSettingsConnecting - else -> R.string.netpSubscriptionSettingsDisconnected - } - - val netPItemIcon = if (networkProtectionConnectionState != DISCONNECTED) { - CommonR.drawable.ic_check_green_round_16 - } else { - CommonR.drawable.ic_exclamation_yellow_16 - } - - ShowState( - icon = netPItemIcon, - subtitle = subtitle, - ) - } else { - Pending - } - } - - NetPAccessState.Locked -> Hidden + ): NetPEntryState = + when (settingsState) { + Hidden -> NetPEntryState.Hidden + Subscribed -> NetPEntryState.Subscribed(isActive = networkProtectionConnectionState.isConnected()) + Activating -> NetPEntryState.Activating + Expired -> NetPEntryState.Expired } - } @Suppress("UNCHECKED_CAST") class Factory @Inject constructor( - private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionSettingsState: NetworkProtectionSettingsState, private val networkProtectionState: NetworkProtectionState, + private val networkProtectionAccessState: NetworkProtectionAccessState, private val dispatcherProvider: DispatcherProvider, private val pixel: Pixel, ) : ViewModelProvider.NewInstanceFactory() { @@ -149,8 +125,9 @@ class ProSettingNetPViewModel( return with(modelClass) { when { isAssignableFrom(ProSettingNetPViewModel::class.java) -> ProSettingNetPViewModel( - networkProtectionAccessState, + networkProtectionSettingsState, networkProtectionState, + networkProtectionAccessState, dispatcherProvider, pixel, ) diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt index 108c75960b3d..d721a5dea065 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt @@ -20,14 +20,19 @@ import android.content.Context import android.view.View import com.duckduckgo.anvil.annotations.PriorityKey import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.settings.api.NewSettingsFeature import com.duckduckgo.settings.api.ProSettingsPlugin import com.squareup.anvil.annotations.ContributesMultibinding import javax.inject.Inject @ContributesMultibinding(ActivityScope::class) @PriorityKey(200) -class ProSettingsNetP @Inject constructor() : ProSettingsPlugin { +class ProSettingsNetP @Inject constructor(private val newSettingsFeature: NewSettingsFeature) : ProSettingsPlugin { override fun getView(context: Context): View { - return ProSettingNetPView(context) + return if (newSettingsFeature.self().isEnabled()) { + ProSettingNetPView(context) + } else { + return LegacyProSettingNetPView(context) + } } } diff --git a/network-protection/network-protection-impl/src/main/res/layout/legacy_view_settings_netp.xml b/network-protection/network-protection-impl/src/main/res/layout/legacy_view_settings_netp.xml new file mode 100644 index 000000000000..6fbef946751f --- /dev/null +++ b/network-protection/network-protection-impl/src/main/res/layout/legacy_view_settings_netp.xml @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml b/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml index 6fbef946751f..509de9f75387 100644 --- a/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml +++ b/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml @@ -14,12 +14,11 @@ ~ limitations under the License. --> - \ No newline at end of file + \ No newline at end of file diff --git a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModelTest.kt b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModelTest.kt new file mode 100644 index 000000000000..25866ec4dd9a --- /dev/null +++ b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModelTest.kt @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.networkprotection.impl.subscription.settings + +import app.cash.turbine.test +import com.duckduckgo.app.statistics.pixels.Pixel +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.mobile.android.R as CommonR +import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.Locked +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.UnLocked +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED +import com.duckduckgo.networkprotection.impl.R +import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Pending +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.ShowState +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.* +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +class LegacyProSettingNetPViewModelTest { + + @get:Rule + val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() + + private val pixel: Pixel = mock() + private val networkProtectionState: NetworkProtectionState = mock() + private val networkProtectionAccessState: NetworkProtectionAccessState = mock() + private lateinit var proSettingNetPViewModel: LegacyProSettingNetPViewModel + + @Before + fun before() { + proSettingNetPViewModel = LegacyProSettingNetPViewModel( + networkProtectionAccessState, + networkProtectionState, + coroutineTestRule.testDispatcherProvider, + pixel, + ) + } + + @Test + fun whenNetPSettingClickedThenReturnScreenForCurrentState() = runTest { + val testScreen = object : ActivityParams {} + whenever(networkProtectionAccessState.getScreenForCurrentState()).thenReturn(testScreen) + + proSettingNetPViewModel.commands().test { + proSettingNetPViewModel.onNetPSettingClicked() + + assertEquals(Command.OpenNetPScreen(testScreen), awaitItem()) + verify(pixel).fire(NETP_SETTINGS_PRESSED) + + cancelAndConsumeRemainingEvents() + } + } + + @Test + fun whenNetPIsNotUnlockedThenNetPEntryStateShouldShowHidden() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(Locked)) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + Hidden, + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaButNotAcceptedTermsThenNetPEntryStateShouldShowPending() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(false) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + Pending, + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_check_green_round_16, + subtitle = R.string.netpSubscriptionSettingsConnected, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndNotOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(false) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + Pending, + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_check_green_round_16, + subtitle = R.string.netpSubscriptionSettingsConnected, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndConnectingThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTING)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_check_green_round_16, + subtitle = R.string.netpSubscriptionSettingsConnecting, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndDisabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_exclamation_yellow_16, + subtitle = R.string.netpSubscriptionSettingsDisconnected, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } +} diff --git a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImplTest.kt b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImplTest.kt new file mode 100644 index 000000000000..c95f916d502d --- /dev/null +++ b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImplTest.kt @@ -0,0 +1,124 @@ +package com.duckduckgo.networkprotection.impl.subscription.settings + +import app.cash.turbine.test +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +class NetworkProtectionSettingsStateImplTest { + + @get:Rule + val coroutineTestRule = CoroutineTestRule() + + private lateinit var networkProtectionSettingsState: NetworkProtectionSettingsStateImpl + private lateinit var fakeNetworkProtectionState: FakeNetworkProtectionState + private lateinit var fakeNetpSubscriptionManager: FakeNetpSubscriptionManager + + @Before + fun setUp() { + fakeNetworkProtectionState = FakeNetworkProtectionState() + fakeNetpSubscriptionManager = FakeNetpSubscriptionManager() + + networkProtectionSettingsState = NetworkProtectionSettingsStateImpl( + dispatcherProvider = coroutineTestRule.testDispatcherProvider, + networkProtectionState = fakeNetworkProtectionState, + netpSubscriptionManager = fakeNetpSubscriptionManager, + ) + } + + @Test + fun `when VpnStatus is active then returns subscribed`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.ACTIVE) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Subscribed, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is inactive then returns expired`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.INACTIVE) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Expired, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is expired then returns expired`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.EXPIRED) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Expired, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is activating then returns waiting`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.WAITING) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Activating, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is signed out then returns hidden`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.SIGNED_OUT) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Hidden, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is ineligible then returns hidden`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.INELIGIBLE) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Hidden, awaitItem()) + awaitComplete() + } + } +} + +private class FakeNetworkProtectionState : NetworkProtectionState { + override suspend fun isOnboarded(): Boolean = false + override suspend fun isEnabled(): Boolean = false + override suspend fun isRunning(): Boolean = false + override fun start() {} + override fun restart() {} + override fun clearVPNConfigurationAndRestart() {} + override suspend fun stop() {} + override fun clearVPNConfigurationAndStop() {} + override fun serverLocation(): String? = null + override fun getConnectionStateFlow(): Flow = flowOf() + override suspend fun getExcludedApps(): List = emptyList() +} + +private class FakeNetpSubscriptionManager : NetpSubscriptionManager { + + private var vpnStatusFlow: Flow = flowOf() + + override suspend fun getVpnStatus(): VpnStatus = vpnStatusFlow.first() + override suspend fun vpnStatus(): Flow = vpnStatusFlow + + fun setVpnStatus(status: VpnStatus) { + vpnStatusFlow = flowOf(status) + } +} diff --git a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt index f46553aad3a8..68d72548e687 100644 --- a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt +++ b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt @@ -19,21 +19,19 @@ package com.duckduckgo.networkprotection.impl.subscription.settings import app.cash.turbine.test import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.common.test.CoroutineTestRule -import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState -import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.Locked -import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.UnLocked import com.duckduckgo.networkprotection.api.NetworkProtectionState import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED -import com.duckduckgo.networkprotection.impl.R import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Expired import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Hidden -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Pending -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.ShowState +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Subscribed import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Assert.* @@ -52,20 +50,22 @@ class ProSettingNetPViewModelTest { private val pixel: Pixel = mock() private val networkProtectionState: NetworkProtectionState = mock() private val networkProtectionAccessState: NetworkProtectionAccessState = mock() + private val networkProtectionSettingsState: NetworkProtectionSettingsState = mock() private lateinit var proSettingNetPViewModel: ProSettingNetPViewModel @Before fun before() { proSettingNetPViewModel = ProSettingNetPViewModel( - networkProtectionAccessState, + networkProtectionSettingsState, networkProtectionState, + networkProtectionAccessState, coroutineTestRule.testDispatcherProvider, pixel, ) } @Test - fun whenNetPSettingClickedThenReturnScreenForCurrentState() = runTest { + fun whenNetPSettingClickedThenNetPScreenOpened() = runTest { val testScreen = object : ActivityParams {} whenever(networkProtectionAccessState.getScreenForCurrentState()).thenReturn(testScreen) @@ -80,9 +80,9 @@ class ProSettingNetPViewModelTest { } @Test - fun whenNetPIsNotUnlockedThenNetPEntryStateShouldShowHidden() = runTest { + fun whenNetPVisibilityStateIsHiddenThenNetPEntryStateIsHidden() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(Locked)) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Hidden)) proSettingNetPViewModel.onStart(mock()) @@ -95,108 +95,75 @@ class ProSettingNetPViewModelTest { } @Test - fun whenNetPStateIsInBetaButNotAcceptedTermsThenNetPEntryStateShouldShowPending() = runTest { + fun whenNetPVisibilityStateIsActivatingThenNetPEntryStateIsActivating() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(false) - - proSettingNetPViewModel.onStart(mock()) - - proSettingNetPViewModel.viewState.test { - assertEquals( - Pending, - expectMostRecentItem().networkProtectionEntryState, - ) - } - } - - @Test - fun whenNetPStateIsInBetaAndOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { - whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Activating)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_check_green_round_16, - subtitle = R.string.netpSubscriptionSettingsConnected, - ), + Activating, expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaAndNotOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + fun whenNetPVisibilityStateConnectedAndAccessStateIsSubscribedThenNetPEntryStateIsSubscribedAndActive() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(false) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Subscribed)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - Pending, + Subscribed(isActive = true), expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { - whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + fun whenNetPVisibilityStateDisconnectedAndAccessStateIsSubscribedThenNetPEntryStateIsSubscribedAndInactive() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Subscribed)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_check_green_round_16, - subtitle = R.string.netpSubscriptionSettingsConnected, - ), + Subscribed(isActive = false), expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaAndConnectingThenNetPEntryStateShouldCorrectShowState() = runTest { + fun whenNetPVisibilityStateIsConnectingThenNetPEntryStateIsSubscribedAndNotActive() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTING)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Subscribed)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_check_green_round_16, - subtitle = R.string.netpSubscriptionSettingsConnecting, - ), + Subscribed(isActive = false), expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaAndDisabledThenNetPEntryStateShouldCorrectShowState() = runTest { + fun whenNetPVisibilityStateIsExpiredThenNetPEntryStateIsExpired() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Expired)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_exclamation_yellow_16, - subtitle = R.string.netpSubscriptionSettingsDisconnected, - ), + Expired, expectMostRecentItem().networkProtectionEntryState, ) } From 4b15b5546b56056e5a76d03cd0ee647d125bc941 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Thu, 19 Dec 2024 17:23:35 +0100 Subject: [PATCH 18/32] Update Settings: Update PIR Settings Item (#5397) Task/Issue URL: https://app.asana.com/0/1207908166761516/1208966262488272/f ### Description Adds support for different PIR (Private Information Removal) subscription states in the settings menu, including active, expired, activating, and hidden states. Introduces a new subscription manager to handle PIR status and updates the UI to reflect these states with appropriate icons and interactions. ### Steps to test this PR Prerequisite: Enable `newSettings` feature toggle Prerequisite: Apply the patch in the [Asana task](https://app.asana.com/0/1207908166761516/1208966262488271/f) Note: Only the VPN item, PIR and possibly the Settings item will be seen, depending on the different states. ITR is not included as part of this PR and so is not visible. _PIR Subscribed_ - [x] In `RealSubscriptions` change ln 77 to `return flowOf(listOf(NetP, PIR))` - [x] Open New Settings - [x] Verify PIR item is visible with colored icon and status is on - [x] Click PIR item - [x] PIR screen should open _Unsubscribed_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.UNKNOWN` - [x] Open New Settings - [x] Verify VPN item is not visible _PIR Expired_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.EXPIRED` - [x] Open New Settings - [x] Verify PIR item is visible with grey icon and is not clickable, and status is off - [x] Click PIR item - [x] Nothing should happen _PPro Activating_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.WAITING` - [x] Open New Settings - [x] Verify PIR item is visible with grey icon and status is off - [x] Click PIR item - [x] Nothing should happen _No Entitlement_ - [x] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.AUTO_RENEWABLE` - [x] In `RealSubscriptions` change ln 77 to `return flowOf(listOf())` - [x] Open New Settings - [x] Verify PIR item is not visible _Legacy Support_ - [x] Turn off `newSettings` - [ ] Verify old PIR settings works by repeating steps above ### UI changes | Before | After | | --- | --- | | ![old_pir_subscribed_active](https://github.com/user-attachments/assets/c7c47bb7-a9c7-43b8-a70e-24492dd359ec) | ![new_pir_subscribed](https://github.com/user-attachments/assets/1330d724-f488-4516-9999-636c09a9a1d7) | | ![old_pir_expired](https://github.com/user-attachments/assets/db81cc81-82a4-4e86-a635-a3a5b89fb9c6) | ![pir_new_expired](https://github.com/user-attachments/assets/cb13fbab-50a0-43e0-a1cb-3d3cce7da811) | | ![old_pir_activating](https://github.com/user-attachments/assets/fb193871-fd1e-45e6-be2c-806ab81f4063) | ![pir_new_activating](https://github.com/user-attachments/assets/4e847f69-4a90-4440-ac9c-44db516ea45c) | | ![old_pir_no_entitlement](https://github.com/user-attachments/assets/5718eb22-db46-43bc-a810-4572ea7dc1db) | ![pir_new_no_entitlement](https://github.com/user-attachments/assets/69a68ed7-2035-4996-89cc-59bbf1872b25) | | ![old_pir_unsubscribed](https://github.com/user-attachments/assets/91d2fb61-bc49-4735-b83e-c8c6c1744488) | ![pir_unsubscribed](https://github.com/user-attachments/assets/899b1a33-b3c5-4068-ad25-8f5e4e964434) | --- .../impl/pir/PirSubscriptionManager.kt | 60 +++++++ .../settings/plugins/SubsSettingsPlugins.kt | 9 +- .../settings/views/LegacyPirSettingView.kt | 116 +++++++++++++ .../views/LegacyPirSettingViewModel.kt | 76 +++++++++ .../impl/settings/views/PirSettingView.kt | 34 ++-- .../settings/views/PirSettingViewModel.kt | 37 +++- .../res/layout/legacy_view_pir_settings.xml | 26 +++ .../src/main/res/layout/view_pir_settings.xml | 18 +- .../pir/RealPirSubscriptionManagerTest.kt | 161 ++++++++++++++++++ ...st.kt => LegacyPirSettingViewModelTest.kt} | 8 +- 10 files changed, 513 insertions(+), 32 deletions(-) create mode 100644 subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pir/PirSubscriptionManager.kt create mode 100644 subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingView.kt create mode 100644 subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModel.kt create mode 100644 subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_pir_settings.xml create mode 100644 subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt rename subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/{PirSettingViewModelTest.kt => LegacyPirSettingViewModelTest.kt} (87%) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pir/PirSubscriptionManager.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pir/PirSubscriptionManager.kt new file mode 100644 index 000000000000..52d213cc6ef6 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pir/PirSubscriptionManager.kt @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl.pir + +import com.duckduckgo.di.scopes.AppScope +import com.duckduckgo.subscriptions.api.Product.PIR +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus +import com.squareup.anvil.annotations.ContributesBinding +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +interface PirSubscriptionManager { + fun pirStatus(): Flow + + enum class PirStatus { + ACTIVE, + EXPIRED, + SIGNED_OUT, + INACTIVE, + WAITING, + INELIGIBLE, + } +} + +@ContributesBinding(AppScope::class) +class RealPirSubscriptionManager @Inject constructor( + private val subscriptions: Subscriptions, +) : PirSubscriptionManager { + + override fun pirStatus(): Flow = hasPirEntitlement().map { getPirStatusInternal(it) } + + private fun hasPirEntitlement(): Flow = subscriptions.getEntitlementStatus().map { it.contains(PIR) } + + private suspend fun getPirStatusInternal(hasValidEntitlement: Boolean): PirStatus = when { + !hasValidEntitlement -> PirStatus.INELIGIBLE + else -> when (subscriptions.getSubscriptionStatus()) { + SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> PirStatus.EXPIRED + SubscriptionStatus.UNKNOWN -> PirStatus.SIGNED_OUT + SubscriptionStatus.AUTO_RENEWABLE, SubscriptionStatus.NOT_AUTO_RENEWABLE, SubscriptionStatus.GRACE_PERIOD -> PirStatus.ACTIVE + SubscriptionStatus.WAITING -> PirStatus.WAITING + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt index 53c521b7532c..1772be48727b 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt @@ -25,6 +25,7 @@ import com.duckduckgo.settings.api.NewSettingsFeature import com.duckduckgo.settings.api.ProSettingsPlugin import com.duckduckgo.subscriptions.impl.R import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingView +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingView import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingView import com.duckduckgo.subscriptions.impl.settings.views.PirSettingView import com.duckduckgo.subscriptions.impl.settings.views.ProSettingView @@ -55,9 +56,13 @@ class ProSettings @Inject constructor(private val newSettingsFeature: NewSetting @ContributesMultibinding(scope = ActivityScope::class) @PriorityKey(300) -class PIRSettings @Inject constructor() : ProSettingsPlugin { +class PIRSettings @Inject constructor(private val newSettingsFeature: NewSettingsFeature) : ProSettingsPlugin { override fun getView(context: Context): View { - return PirSettingView(context) + return if (newSettingsFeature.self().isEnabled()) { + PirSettingView(context) + } else { + LegacyPirSettingView(context) + } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingView.kt new file mode 100644 index 000000000000..9acc53b3c04f --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingView.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeViewModelStoreOwner +import com.duckduckgo.anvil.annotations.InjectWith +import com.duckduckgo.common.ui.view.gone +import com.duckduckgo.common.ui.view.show +import com.duckduckgo.common.ui.viewbinding.viewBinding +import com.duckduckgo.common.utils.ConflatedJob +import com.duckduckgo.common.utils.ViewViewModelFactory +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.databinding.LegacyViewPirSettingsBinding +import com.duckduckgo.subscriptions.impl.pir.PirActivity.Companion.PirScreenWithEmptyParams +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command.OpenPir +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.ViewState +import dagger.android.support.AndroidSupportInjection +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +@InjectWith(ViewScope::class) +class LegacyPirSettingView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : FrameLayout(context, attrs, defStyle) { + + @Inject + lateinit var viewModelFactory: ViewViewModelFactory + + @Inject + lateinit var globalActivityStarter: GlobalActivityStarter + + private var coroutineScope: CoroutineScope? = null + + private val binding: LegacyViewPirSettingsBinding by viewBinding() + + private val viewModel: LegacyPirSettingViewModel by lazy { + ViewModelProvider(findViewTreeViewModelStoreOwner()!!, viewModelFactory)[LegacyPirSettingViewModel::class.java] + } + + private var job: ConflatedJob = ConflatedJob() + + override fun onAttachedToWindow() { + AndroidSupportInjection.inject(this) + super.onAttachedToWindow() + + findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) + + binding.pirSettings.setClickListener { + viewModel.onPir() + } + + @SuppressLint("NoHardcodedCoroutineDispatcher") + coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + + job += viewModel.commands() + .onEach { processCommands(it) } + .launchIn(coroutineScope!!) + + viewModel.viewState + .onEach { renderView(it) } + .launchIn(coroutineScope!!) + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + findViewTreeLifecycleOwner()?.lifecycle?.removeObserver(viewModel) + coroutineScope?.cancel() + job.cancel() + coroutineScope = null + } + + private fun renderView(viewState: ViewState) { + if (viewState.hasSubscription) { + binding.pirSettings.show() + } else { + binding.pirSettings.gone() + } + } + + private fun processCommands(command: Command) { + when (command) { + is OpenPir -> { + globalActivityStarter.start(context, PirScreenWithEmptyParams) + } + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModel.kt new file mode 100644 index 000000000000..873b9efacbe8 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModel.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.duckduckgo.anvil.annotations.ContributesViewModel +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.subscriptions.api.Product.PIR +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command.OpenPir +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch + +@SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle +@ContributesViewModel(ViewScope::class) +class LegacyPirSettingViewModel @Inject constructor( + private val subscriptions: Subscriptions, + private val pixelSender: SubscriptionPixelSender, +) : ViewModel(), DefaultLifecycleObserver { + + sealed class Command { + data object OpenPir : Command() + } + + private val command = Channel(1, BufferOverflow.DROP_OLDEST) + internal fun commands(): Flow = command.receiveAsFlow() + data class ViewState(val hasSubscription: Boolean = false) + + private val _viewState = MutableStateFlow(ViewState()) + val viewState = _viewState.asStateFlow() + + fun onPir() { + pixelSender.reportAppSettingsPirClick() + sendCommand(OpenPir) + } + + override fun onCreate(owner: LifecycleOwner) { + super.onCreate(owner) + subscriptions.getEntitlementStatus().onEach { + _viewState.emit(viewState.value.copy(hasSubscription = it.contains(PIR))) + }.launchIn(viewModelScope) + } + + private fun sendCommand(newCommand: Command) { + viewModelScope.launch { + command.send(newCommand) + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt index 17c9316993ec..620e7172f5e7 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt @@ -20,22 +20,27 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.widget.FrameLayout +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.common.ui.view.gone -import com.duckduckgo.common.ui.view.show import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.common.utils.ConflatedJob import com.duckduckgo.common.utils.ViewViewModelFactory import com.duckduckgo.di.scopes.ViewScope import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.R import com.duckduckgo.subscriptions.impl.databinding.ViewPirSettingsBinding import com.duckduckgo.subscriptions.impl.pir.PirActivity.Companion.PirScreenWithEmptyParams import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command.OpenPir import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Activating +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Expired +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Hidden +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Subscribed import dagger.android.support.AndroidSupportInjection import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -74,10 +79,6 @@ class PirSettingView @JvmOverloads constructor( findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) - binding.pirSettings.setClickListener { - viewModel.onPir() - } - @SuppressLint("NoHardcodedCoroutineDispatcher") coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) @@ -99,10 +100,23 @@ class PirSettingView @JvmOverloads constructor( } private fun renderView(viewState: ViewState) { - if (viewState.hasSubscription) { - binding.pirSettings.show() - } else { - binding.pirSettings.gone() + with(binding.pirSettings) { + when (viewState.pirState) { + is Subscribed -> { + isVisible = true + setStatus(isOn = true) + setLeadingIconResource(R.drawable.ic_identity_blocked_pir_color_24) + isClickable = true + binding.pirSettings.setClickListener { viewModel.onPir() } + } + Expired, Activating -> { + isVisible = true + isClickable = false + setStatus(isOn = false) + setLeadingIconResource(R.drawable.ic_identity_blocked_pir_grayscale_color_24) + } + Hidden -> isGone = true + } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt index 43ae9e425988..9f2220c295b2 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt @@ -23,10 +23,17 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel import com.duckduckgo.di.scopes.ViewScope -import com.duckduckgo.subscriptions.api.Product.PIR -import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.ACTIVE +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.EXPIRED +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.INACTIVE +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.INELIGIBLE +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.SIGNED_OUT +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.WAITING import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command.OpenPir +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Hidden import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.Channel @@ -36,12 +43,13 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle @ContributesViewModel(ViewScope::class) class PirSettingViewModel @Inject constructor( - private val subscriptions: Subscriptions, + private val pirSubscriptionManager: PirSubscriptionManager, private val pixelSender: SubscriptionPixelSender, ) : ViewModel(), DefaultLifecycleObserver { @@ -51,7 +59,16 @@ class PirSettingViewModel @Inject constructor( private val command = Channel(1, BufferOverflow.DROP_OLDEST) internal fun commands(): Flow = command.receiveAsFlow() - data class ViewState(val hasSubscription: Boolean = false) + data class ViewState(val pirState: PirState = Hidden) { + + sealed class PirState { + + data object Hidden : PirState() + data object Subscribed : PirState() + data object Expired : PirState() + data object Activating : PirState() + } + } private val _viewState = MutableStateFlow(ViewState()) val viewState = _viewState.asStateFlow() @@ -63,8 +80,16 @@ class PirSettingViewModel @Inject constructor( override fun onCreate(owner: LifecycleOwner) { super.onCreate(owner) - subscriptions.getEntitlementStatus().onEach { - _viewState.emit(viewState.value.copy(hasSubscription = it.contains(PIR))) + + pirSubscriptionManager.pirStatus().onEach { status -> + val pirState = when (status) { + ACTIVE -> PirState.Subscribed + INACTIVE, EXPIRED -> PirState.Expired + WAITING -> PirState.Activating + SIGNED_OUT, INELIGIBLE -> PirState.Hidden + } + + _viewState.update { it.copy(pirState = pirState) } }.launchIn(viewModelScope) } diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_pir_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_pir_settings.xml new file mode 100644 index 000000000000..93a12f1a12d0 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_pir_settings.xml @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml index 93a12f1a12d0..3dacac16be47 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml @@ -14,13 +14,11 @@ ~ limitations under the License. --> - \ No newline at end of file + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt new file mode 100644 index 000000000000..4fa282dd96d1 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl.pir + +import android.content.Context +import android.net.Uri +import app.cash.turbine.test +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.subscriptions.api.Product +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class RealPirSubscriptionManagerTest { + + @get:Rule + var coroutineRule = CoroutineTestRule() + + @Test + fun `when user does not have pir entitlement then pir status returns ineligible`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.UNKNOWN) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.INELIGIBLE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has pir entitlement but subscription is inactive then pir status returns expired`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.INACTIVE, listOf(Product.PIR)) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has pir entitlement but subscription is expired then pir status returns expired`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.EXPIRED, listOf(Product.PIR)) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has pir entitlement but subscription is unknown then pir status returns signed out`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.UNKNOWN, listOf(Product.PIR)) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.SIGNED_OUT, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has pir entitlement and subscription is auto renewable then pir status returns active`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.AUTO_RENEWABLE, listOf(Product.PIR)) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has pir entitlement and subscription is not auto renewable then pir status returns active`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.NOT_AUTO_RENEWABLE, listOf(Product.PIR)) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has pir entitlement and subscription is grace period then pir status returns active`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.GRACE_PERIOD, listOf(Product.PIR)) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has pir entitlement and subscription is waiting then pir status returns waiting`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.WAITING, listOf(Product.PIR)) + + val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) + + pirSubscriptionManager.pirStatus().test { + assertEquals(PirStatus.WAITING, awaitItem()) + awaitComplete() + } + } +} + +private class FakeSubscriptions( + private val subscriptionStatus: SubscriptionStatus, + private val entitlements: List = emptyList(), +) : Subscriptions { + + override suspend fun isSignedIn(): Boolean = true + + override suspend fun getAccessToken(): String = "fake_access_token" + + override fun getEntitlementStatus(): Flow> = flowOf(entitlements) + + override suspend fun isEligible(): Boolean = true + + override suspend fun getSubscriptionStatus(): SubscriptionStatus = subscriptionStatus + + override fun shouldLaunchPrivacyProForUrl(url: String): Boolean = false + + override fun launchPrivacyPro( + context: Context, + uri: Uri?, + ) { + // no-op + } + + override fun isPrivacyProUrl(uri: Uri): Boolean = false +} diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModelTest.kt similarity index 87% rename from subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModelTest.kt rename to subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModelTest.kt index ed5b5010d19e..78f7f1d26fc1 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModelTest.kt @@ -5,7 +5,7 @@ import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.subscriptions.api.Product.PIR import com.duckduckgo.subscriptions.api.Subscriptions import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender -import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command.OpenPir +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command.OpenPir import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -18,17 +18,17 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @ExperimentalCoroutinesApi -class PirSettingViewModelTest { +class LegacyPirSettingViewModelTest { @get:Rule val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() private val subscriptions: Subscriptions = mock() private val pixelSender: SubscriptionPixelSender = mock() - private lateinit var viewModel: PirSettingViewModel + private lateinit var viewModel: LegacyPirSettingViewModel @Before fun before() { - viewModel = PirSettingViewModel(subscriptions, pixelSender) + viewModel = LegacyPirSettingViewModel(subscriptions, pixelSender) } @Test From 809502347b46db0dda6a6002727813cc3388afac Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Thu, 19 Dec 2024 17:42:06 +0100 Subject: [PATCH 19/32] Update Settings: Update ITR settings item (#5398) Task/Issue URL: https://app.asana.com/0/1207908166761516/1208966262488273/f ### Description - Refactored subscription status management by introducing a generic `ProductSubscriptionManager` to handle status checks for multiple products - Updated ITR settings UI to show different states (active, expired, activating) with appropriate icons and click behaviors - Added legacy support for ITR settings view to maintain backward compatibility ### Steps to test this PR Prerequisite: Enable `newSettings` feature toggle Prerequisite: Apply the patch in the [Asana task](https://app.asana.com/0/1207908166761516/1208966262488273/f) Note: All PPro items should be seen in this PR, that is VPN, PIR, and ITR. _ITR Subscribed_ - [ ] In `RealSubscriptions` change ln 77 to `return flowOf(listOf(NetP, PIR, ITR))` - [ ] Open New Settings - [ ] Verify ITR item is visible with colored icon and status is on - [ ] Click ITR item - [ ] ITR screen should open though the webpage will not load properly as a result of the hacked setup for subscriptions. I have confirmed it works with a real subscription _Unsubscribed_ - [ ] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.UNKNOWN` - [ ] Open New Settings - [ ] Verify ITR item is not visible _ITR Expired_ - [ ] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.EXPIRED` - [ ] Open New Settings - [ ] Verify ITR item is visible with grey icon and is not clickable, and status is off - [ ] Click ITR item - [ ] Nothing should happen _PPro Activating_ - [ ] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.WAITING` - [ ] Open New Settings - [ ] Verify ITR item is visible with grey icon and status is off - [ ] Click ITR item - [ ] Nothing should happen _No Entitlement_ - [ ] In `SubscriptionManager` change ln 442 to `return SubscriptionStatus.AUTO_RENEWABLE` - [ ] In `RealSubscriptions` change ln 77 to `return flowOf(listOf())` - [ ] Open New Settings - [ ] Verify ITR item is not visible _Legacy Support_ - [ ] Turn off `newSettings` - [ ] Verify old ITR settings works by repeating steps above ### UI changes | Before | After | | --- | --- | | ![old_itr_subscribed](https://github.com/user-attachments/assets/9f6e39ab-d1c5-4a8b-971b-09ce5259818c) | ![new_itr_renewable](https://github.com/user-attachments/assets/aae0533f-7082-4976-98d8-1dc08d0d28c5) | | ![old_itr_expired](https://github.com/user-attachments/assets/fd9e9c63-69f4-432a-b1e2-67420eac517a) | ![new_itr_expired](https://github.com/user-attachments/assets/9a305360-8ad4-4b63-8eb6-5e1e5d977cb8) | | ![old_itr_waiting](https://github.com/user-attachments/assets/1bab7540-b03f-40db-8219-df11b8c2ced5) | ![new_itr_activating](https://github.com/user-attachments/assets/8ead32db-560b-4195-b60d-b63cba1e3b3b) | | ![old_itr_ineligible](https://github.com/user-attachments/assets/0eb9be9e-7fd2-4836-83a3-d9a1acce2933) | ![new_itr_ineligible](https://github.com/user-attachments/assets/dcbb96ed-acc2-4c7c-9337-4450ccf7c546) | | ![old_itr_unsubscribed](https://github.com/user-attachments/assets/6badeae4-3d4f-4de2-b60f-a27001b48951) | ![new_itr_unsubscribed](https://github.com/user-attachments/assets/a42c2601-e2ed-4333-ba91-650a96c2d5c5) | --- ...nager.kt => ProductSubscriptionManager.kt} | 35 ++- .../settings/plugins/SubsSettingsPlugins.kt | 9 +- .../impl/settings/views/ItrSettingView.kt | 33 ++- .../settings/views/ItrSettingViewModel.kt | 37 ++- .../settings/views/LegacyItrSettingView.kt | 122 ++++++++ .../views/LegacyItrSettingViewModel.kt | 77 +++++ .../settings/views/PirSettingViewModel.kt | 22 +- .../res/layout/legacy_view_itr_settings.xml | 26 ++ .../src/main/res/layout/view_itr_settings.xml | 20 +- .../RealProductSubscriptionManagerTest.kt | 278 ++++++++++++++++++ .../pir/RealPirSubscriptionManagerTest.kt | 161 ---------- ...st.kt => LegacyItrSettingViewModelTest.kt} | 8 +- ...st.kt => LegacyProSettingViewModelTest.kt} | 2 +- 13 files changed, 607 insertions(+), 223 deletions(-) rename subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/{pir/PirSubscriptionManager.kt => ProductSubscriptionManager.kt} (53%) create mode 100644 subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingView.kt create mode 100644 subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModel.kt create mode 100644 subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_itr_settings.xml create mode 100644 subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealProductSubscriptionManagerTest.kt delete mode 100644 subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt rename subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/{ItrSettingViewModelTest.kt => LegacyItrSettingViewModelTest.kt} (88%) rename subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/{LegacyLegacyProSettingViewModelTest.kt => LegacyProSettingViewModelTest.kt} (98%) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pir/PirSubscriptionManager.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ProductSubscriptionManager.kt similarity index 53% rename from subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pir/PirSubscriptionManager.kt rename to subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ProductSubscriptionManager.kt index 52d213cc6ef6..cafb99a84e7b 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/pir/PirSubscriptionManager.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ProductSubscriptionManager.kt @@ -14,22 +14,23 @@ * limitations under the License. */ -package com.duckduckgo.subscriptions.impl.pir +package com.duckduckgo.subscriptions.impl import com.duckduckgo.di.scopes.AppScope -import com.duckduckgo.subscriptions.api.Product.PIR +import com.duckduckgo.subscriptions.api.Product import com.duckduckgo.subscriptions.api.SubscriptionStatus import com.duckduckgo.subscriptions.api.Subscriptions -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus import com.squareup.anvil.annotations.ContributesBinding import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -interface PirSubscriptionManager { - fun pirStatus(): Flow +interface ProductSubscriptionManager { - enum class PirStatus { + fun entitlementStatus(vararg products: Product): Flow + + enum class ProductStatus { ACTIVE, EXPIRED, SIGNED_OUT, @@ -40,21 +41,23 @@ interface PirSubscriptionManager { } @ContributesBinding(AppScope::class) -class RealPirSubscriptionManager @Inject constructor( +class RealProductSubscriptionManager @Inject constructor( private val subscriptions: Subscriptions, -) : PirSubscriptionManager { +) : ProductSubscriptionManager { - override fun pirStatus(): Flow = hasPirEntitlement().map { getPirStatusInternal(it) } + override fun entitlementStatus(vararg products: Product): Flow = + hasEntitlement(*products).map { getEntitlementStatusInternal(it) } - private fun hasPirEntitlement(): Flow = subscriptions.getEntitlementStatus().map { it.contains(PIR) } + private fun hasEntitlement(vararg products: Product): Flow = + subscriptions.getEntitlementStatus().map { entitledProducts -> entitledProducts.any { products.contains(it) } } - private suspend fun getPirStatusInternal(hasValidEntitlement: Boolean): PirStatus = when { - !hasValidEntitlement -> PirStatus.INELIGIBLE + private suspend fun getEntitlementStatusInternal(hasValidEntitlement: Boolean): ProductStatus = when { + !hasValidEntitlement -> ProductStatus.INELIGIBLE else -> when (subscriptions.getSubscriptionStatus()) { - SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> PirStatus.EXPIRED - SubscriptionStatus.UNKNOWN -> PirStatus.SIGNED_OUT - SubscriptionStatus.AUTO_RENEWABLE, SubscriptionStatus.NOT_AUTO_RENEWABLE, SubscriptionStatus.GRACE_PERIOD -> PirStatus.ACTIVE - SubscriptionStatus.WAITING -> PirStatus.WAITING + SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> ProductStatus.EXPIRED + SubscriptionStatus.UNKNOWN -> ProductStatus.SIGNED_OUT + SubscriptionStatus.AUTO_RENEWABLE, SubscriptionStatus.NOT_AUTO_RENEWABLE, SubscriptionStatus.GRACE_PERIOD -> ProductStatus.ACTIVE + SubscriptionStatus.WAITING -> ProductStatus.WAITING } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt index 1772be48727b..9e15531d821d 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt @@ -25,6 +25,7 @@ import com.duckduckgo.settings.api.NewSettingsFeature import com.duckduckgo.settings.api.ProSettingsPlugin import com.duckduckgo.subscriptions.impl.R import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingView +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingView import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingView import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingView import com.duckduckgo.subscriptions.impl.settings.views.PirSettingView @@ -68,8 +69,12 @@ class PIRSettings @Inject constructor(private val newSettingsFeature: NewSetting @ContributesMultibinding(scope = ActivityScope::class) @PriorityKey(400) -class ITRSettings @Inject constructor() : ProSettingsPlugin { +class ITRSettings @Inject constructor(private val newSettingsFeature: NewSettingsFeature) : ProSettingsPlugin { override fun getView(context: Context): View { - return ItrSettingView(context) + return if (newSettingsFeature.self().isEnabled()) { + ItrSettingView(context) + } else { + LegacyItrSettingView(context) + } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt index 264ef1afae4e..3029d9c278a0 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 DuckDuckGo + * Copyright (c) 2024 DuckDuckGo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,22 +20,24 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.widget.FrameLayout +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.common.ui.view.gone -import com.duckduckgo.common.ui.view.show import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.common.utils.ConflatedJob import com.duckduckgo.common.utils.ViewViewModelFactory import com.duckduckgo.di.scopes.ViewScope import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.R import com.duckduckgo.subscriptions.impl.SubscriptionsConstants import com.duckduckgo.subscriptions.impl.databinding.ViewItrSettingsBinding import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command.OpenItr import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.ViewState +import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.ViewState.ItrState import com.duckduckgo.subscriptions.impl.ui.SubscriptionsWebViewActivityWithParams import dagger.android.support.AndroidSupportInjection import javax.inject.Inject @@ -75,10 +77,6 @@ class ItrSettingView @JvmOverloads constructor( findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) - binding.itrSettings.setClickListener { - viewModel.onItr() - } - @SuppressLint("NoHardcodedCoroutineDispatcher") coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) @@ -100,10 +98,23 @@ class ItrSettingView @JvmOverloads constructor( } private fun renderView(viewState: ViewState) { - if (viewState.hasSubscription) { - binding.itrSettings.show() - } else { - binding.itrSettings.gone() + with(binding.itrSettings) { + when (viewState.itrState) { + is ItrState.Subscribed -> { + isVisible = true + setStatus(isOn = true) + setLeadingIconResource(R.drawable.ic_identity_theft_restoration_color_24) + isClickable = true + setClickListener { viewModel.onItr() } + } + ItrState.Expired, ItrState.Activating -> { + isVisible = true + isClickable = false + setStatus(isOn = false) + setLeadingIconResource(R.drawable.ic_identity_theft_restoration_grayscale_color_24) + } + ItrState.Hidden -> isGone = true + } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt index c44ce366ee81..ec91328297ca 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 DuckDuckGo + * Copyright (c) 2024 DuckDuckGo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,16 @@ import com.duckduckgo.anvil.annotations.ContributesViewModel import com.duckduckgo.di.scopes.ViewScope import com.duckduckgo.subscriptions.api.Product.ITR import com.duckduckgo.subscriptions.api.Product.ROW_ITR -import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.ACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.EXPIRED +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INELIGIBLE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.SIGNED_OUT +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.WAITING import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command.OpenItr +import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.ViewState.ItrState import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.Channel @@ -37,12 +44,13 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle @ContributesViewModel(ViewScope::class) class ItrSettingViewModel @Inject constructor( - private val subscriptions: Subscriptions, + private val productSubscriptionManager: ProductSubscriptionManager, private val pixelSender: SubscriptionPixelSender, ) : ViewModel(), DefaultLifecycleObserver { @@ -52,7 +60,16 @@ class ItrSettingViewModel @Inject constructor( private val command = Channel(1, BufferOverflow.DROP_OLDEST) internal fun commands(): Flow = command.receiveAsFlow() - data class ViewState(val hasSubscription: Boolean = false) + data class ViewState(val itrState: ItrState = ItrState.Hidden) { + + sealed class ItrState { + + data object Hidden : ItrState() + data object Subscribed : ItrState() + data object Expired : ItrState() + data object Activating : ItrState() + } + } private val _viewState = MutableStateFlow(ViewState()) val viewState = _viewState.asStateFlow() @@ -64,8 +81,16 @@ class ItrSettingViewModel @Inject constructor( override fun onCreate(owner: LifecycleOwner) { super.onCreate(owner) - subscriptions.getEntitlementStatus().onEach { - _viewState.emit(viewState.value.copy(hasSubscription = ITR in it || ROW_ITR in it)) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).onEach { status -> + val itrState = when (status) { + ACTIVE -> ItrState.Subscribed + INACTIVE, EXPIRED -> ItrState.Expired + WAITING -> ItrState.Activating + SIGNED_OUT, INELIGIBLE -> ItrState.Hidden + } + + _viewState.update { it.copy(itrState = itrState) } }.launchIn(viewModelScope) } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingView.kt new file mode 100644 index 000000000000..bb1c9b53b093 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingView.kt @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeViewModelStoreOwner +import com.duckduckgo.anvil.annotations.InjectWith +import com.duckduckgo.common.ui.view.gone +import com.duckduckgo.common.ui.view.show +import com.duckduckgo.common.ui.viewbinding.viewBinding +import com.duckduckgo.common.utils.ConflatedJob +import com.duckduckgo.common.utils.ViewViewModelFactory +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants +import com.duckduckgo.subscriptions.impl.databinding.LegacyViewItrSettingsBinding +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command.OpenItr +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.ViewState +import com.duckduckgo.subscriptions.impl.ui.SubscriptionsWebViewActivityWithParams +import dagger.android.support.AndroidSupportInjection +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +@InjectWith(ViewScope::class) +class LegacyItrSettingView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : FrameLayout(context, attrs, defStyle) { + + @Inject + lateinit var viewModelFactory: ViewViewModelFactory + + @Inject + lateinit var globalActivityStarter: GlobalActivityStarter + + private var coroutineScope: CoroutineScope? = null + + private val binding: LegacyViewItrSettingsBinding by viewBinding() + + private val viewModel: LegacyItrSettingViewModel by lazy { + ViewModelProvider(findViewTreeViewModelStoreOwner()!!, viewModelFactory)[LegacyItrSettingViewModel::class.java] + } + + private var job: ConflatedJob = ConflatedJob() + + override fun onAttachedToWindow() { + AndroidSupportInjection.inject(this) + super.onAttachedToWindow() + + findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) + + binding.itrSettings.setClickListener { + viewModel.onItr() + } + + @SuppressLint("NoHardcodedCoroutineDispatcher") + coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + + job += viewModel.commands() + .onEach { processCommands(it) } + .launchIn(coroutineScope!!) + + viewModel.viewState + .onEach { renderView(it) } + .launchIn(coroutineScope!!) + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + findViewTreeLifecycleOwner()?.lifecycle?.removeObserver(viewModel) + coroutineScope?.cancel() + job.cancel() + coroutineScope = null + } + + private fun renderView(viewState: ViewState) { + if (viewState.hasSubscription) { + binding.itrSettings.show() + } else { + binding.itrSettings.gone() + } + } + + private fun processCommands(command: Command) { + when (command) { + is OpenItr -> { + globalActivityStarter.start( + context, + SubscriptionsWebViewActivityWithParams( + url = SubscriptionsConstants.ITR_URL, + ), + ) + } + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModel.kt new file mode 100644 index 000000000000..4c766866c5ed --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModel.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.duckduckgo.anvil.annotations.ContributesViewModel +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.subscriptions.api.Product.ITR +import com.duckduckgo.subscriptions.api.Product.ROW_ITR +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command.OpenItr +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch + +@SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle +@ContributesViewModel(ViewScope::class) +class LegacyItrSettingViewModel @Inject constructor( + private val subscriptions: Subscriptions, + private val pixelSender: SubscriptionPixelSender, +) : ViewModel(), DefaultLifecycleObserver { + + sealed class Command { + data object OpenItr : Command() + } + + private val command = Channel(1, BufferOverflow.DROP_OLDEST) + internal fun commands(): Flow = command.receiveAsFlow() + data class ViewState(val hasSubscription: Boolean = false) + + private val _viewState = MutableStateFlow(ViewState()) + val viewState = _viewState.asStateFlow() + + fun onItr() { + pixelSender.reportAppSettingsIdtrClick() + sendCommand(OpenItr) + } + + override fun onCreate(owner: LifecycleOwner) { + super.onCreate(owner) + subscriptions.getEntitlementStatus().onEach { + _viewState.emit(viewState.value.copy(hasSubscription = ITR in it || ROW_ITR in it)) + }.launchIn(viewModelScope) + } + + private fun sendCommand(newCommand: Command) { + viewModelScope.launch { + command.send(newCommand) + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt index 9f2220c295b2..ab54d099eba8 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt @@ -23,17 +23,17 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel import com.duckduckgo.di.scopes.ViewScope -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.ACTIVE -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.EXPIRED -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.INACTIVE -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.INELIGIBLE -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.SIGNED_OUT -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus.WAITING +import com.duckduckgo.subscriptions.api.Product.PIR +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.ACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.EXPIRED +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INELIGIBLE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.SIGNED_OUT +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.WAITING import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command.OpenPir import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState -import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Hidden import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.Channel @@ -49,7 +49,7 @@ import kotlinx.coroutines.launch @SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle @ContributesViewModel(ViewScope::class) class PirSettingViewModel @Inject constructor( - private val pirSubscriptionManager: PirSubscriptionManager, + private val productSubscriptionManager: ProductSubscriptionManager, private val pixelSender: SubscriptionPixelSender, ) : ViewModel(), DefaultLifecycleObserver { @@ -59,7 +59,7 @@ class PirSettingViewModel @Inject constructor( private val command = Channel(1, BufferOverflow.DROP_OLDEST) internal fun commands(): Flow = command.receiveAsFlow() - data class ViewState(val pirState: PirState = Hidden) { + data class ViewState(val pirState: PirState = PirState.Hidden) { sealed class PirState { @@ -81,7 +81,7 @@ class PirSettingViewModel @Inject constructor( override fun onCreate(owner: LifecycleOwner) { super.onCreate(owner) - pirSubscriptionManager.pirStatus().onEach { status -> + productSubscriptionManager.entitlementStatus(PIR).onEach { status -> val pirState = when (status) { ACTIVE -> PirState.Subscribed INACTIVE, EXPIRED -> PirState.Expired diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_itr_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_itr_settings.xml new file mode 100644 index 000000000000..bc64f3a43aa1 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_itr_settings.xml @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml index bc64f3a43aa1..7f61756c4bd0 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml @@ -1,5 +1,5 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealProductSubscriptionManagerTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealProductSubscriptionManagerTest.kt new file mode 100644 index 000000000000..82bacb20f2dc --- /dev/null +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealProductSubscriptionManagerTest.kt @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * 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. + */ + +package com.duckduckgo.subscriptions.impl + +import android.content.Context +import android.net.Uri +import app.cash.turbine.test +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.subscriptions.api.Product +import com.duckduckgo.subscriptions.api.Product.* +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import com.duckduckgo.subscriptions.api.SubscriptionStatus.* +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.ACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.EXPIRED +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INELIGIBLE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.SIGNED_OUT +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.WAITING +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class RealProductSubscriptionManagerTest { + + @get:Rule + var coroutineRule = CoroutineTestRule() + + @Test + fun `when user does not have entitlement then status returns ineligible`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(INELIGIBLE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and is not entitled then returns ineligible`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(INELIGIBLE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement but subscription is inactive then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(INACTIVE, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status inactive then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(INACTIVE, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement but subscription is expired then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.EXPIRED, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status expired then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.EXPIRED, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement but subscription is unknown then status returns signed out`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(SIGNED_OUT, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status unknown then status returns signed out`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(SIGNED_OUT, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(AUTO_RENEWABLE, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(AUTO_RENEWABLE, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is not auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(NOT_AUTO_RENEWABLE, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status not auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(NOT_AUTO_RENEWABLE, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is grace period then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(GRACE_PERIOD, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status grace period then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(GRACE_PERIOD, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is waiting then status returns waiting`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.WAITING, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(WAITING, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status waiting then status returns waiting`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.WAITING, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(WAITING, awaitItem()) + awaitComplete() + } + } +} + +private class FakeSubscriptions( + private val subscriptionStatus: SubscriptionStatus, + private val entitlements: List = emptyList(), +) : Subscriptions { + + override suspend fun isSignedIn(): Boolean = true + + override suspend fun getAccessToken(): String = "fake_access_token" + + override fun getEntitlementStatus(): Flow> = flowOf(entitlements) + + override suspend fun isEligible(): Boolean = true + + override suspend fun getSubscriptionStatus(): SubscriptionStatus = subscriptionStatus + + override fun shouldLaunchPrivacyProForUrl(url: String): Boolean = false + + override fun launchPrivacyPro( + context: Context, + uri: Uri?, + ) { + // no-op + } + + override fun isPrivacyProUrl(uri: Uri): Boolean = false +} diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt deleted file mode 100644 index 4fa282dd96d1..000000000000 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/pir/RealPirSubscriptionManagerTest.kt +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 2024 DuckDuckGo - * - * 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. - */ - -package com.duckduckgo.subscriptions.impl.pir - -import android.content.Context -import android.net.Uri -import app.cash.turbine.test -import com.duckduckgo.common.test.CoroutineTestRule -import com.duckduckgo.subscriptions.api.Product -import com.duckduckgo.subscriptions.api.SubscriptionStatus -import com.duckduckgo.subscriptions.api.Subscriptions -import com.duckduckgo.subscriptions.impl.pir.PirSubscriptionManager.PirStatus -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.test.runTest -import org.junit.Assert.assertEquals -import org.junit.Rule -import org.junit.Test - -class RealPirSubscriptionManagerTest { - - @get:Rule - var coroutineRule = CoroutineTestRule() - - @Test - fun `when user does not have pir entitlement then pir status returns ineligible`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.UNKNOWN) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.INELIGIBLE, awaitItem()) - awaitComplete() - } - } - - @Test - fun `when user has pir entitlement but subscription is inactive then pir status returns expired`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.INACTIVE, listOf(Product.PIR)) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.EXPIRED, awaitItem()) - awaitComplete() - } - } - - @Test - fun `when user has pir entitlement but subscription is expired then pir status returns expired`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.EXPIRED, listOf(Product.PIR)) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.EXPIRED, awaitItem()) - awaitComplete() - } - } - - @Test - fun `when user has pir entitlement but subscription is unknown then pir status returns signed out`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.UNKNOWN, listOf(Product.PIR)) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.SIGNED_OUT, awaitItem()) - awaitComplete() - } - } - - @Test - fun `when user has pir entitlement and subscription is auto renewable then pir status returns active`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.AUTO_RENEWABLE, listOf(Product.PIR)) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.ACTIVE, awaitItem()) - awaitComplete() - } - } - - @Test - fun `when user has pir entitlement and subscription is not auto renewable then pir status returns active`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.NOT_AUTO_RENEWABLE, listOf(Product.PIR)) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.ACTIVE, awaitItem()) - awaitComplete() - } - } - - @Test - fun `when user has pir entitlement and subscription is grace period then pir status returns active`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.GRACE_PERIOD, listOf(Product.PIR)) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.ACTIVE, awaitItem()) - awaitComplete() - } - } - - @Test - fun `when user has pir entitlement and subscription is waiting then pir status returns waiting`() = runTest { - val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.WAITING, listOf(Product.PIR)) - - val pirSubscriptionManager = RealPirSubscriptionManager(subscriptions) - - pirSubscriptionManager.pirStatus().test { - assertEquals(PirStatus.WAITING, awaitItem()) - awaitComplete() - } - } -} - -private class FakeSubscriptions( - private val subscriptionStatus: SubscriptionStatus, - private val entitlements: List = emptyList(), -) : Subscriptions { - - override suspend fun isSignedIn(): Boolean = true - - override suspend fun getAccessToken(): String = "fake_access_token" - - override fun getEntitlementStatus(): Flow> = flowOf(entitlements) - - override suspend fun isEligible(): Boolean = true - - override suspend fun getSubscriptionStatus(): SubscriptionStatus = subscriptionStatus - - override fun shouldLaunchPrivacyProForUrl(url: String): Boolean = false - - override fun launchPrivacyPro( - context: Context, - uri: Uri?, - ) { - // no-op - } - - override fun isPrivacyProUrl(uri: Uri): Boolean = false -} diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModelTest.kt similarity index 88% rename from subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModelTest.kt rename to subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModelTest.kt index e738cb4971f6..bd3a2c83cfe4 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModelTest.kt @@ -5,7 +5,7 @@ import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.subscriptions.api.Product.ITR import com.duckduckgo.subscriptions.api.Subscriptions import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender -import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command.OpenItr +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command.OpenItr import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -18,17 +18,17 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @ExperimentalCoroutinesApi -class ItrSettingViewModelTest { +class LegacyItrSettingViewModelTest { @get:Rule val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() private val subscriptions: Subscriptions = mock() private val pixelSender: SubscriptionPixelSender = mock() - private lateinit var viewModel: ItrSettingViewModel + private lateinit var viewModel: LegacyItrSettingViewModel @Before fun before() { - viewModel = ItrSettingViewModel(subscriptions, pixelSender) + viewModel = LegacyItrSettingViewModel(subscriptions, pixelSender) } @Test diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt similarity index 98% rename from subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt rename to subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt index f1587dca900b..5cac8f322433 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt @@ -19,7 +19,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever -class LegacyLegacyProSettingViewModelTest { +class LegacyProSettingViewModelTest { @get:Rule val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() From f9a50765d0c87a83d77b36a16a9bbf1ed8601987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Gonz=C3=A1lez?= Date: Fri, 20 Dec 2024 10:47:37 +0100 Subject: [PATCH 20/32] GHA: Update Notifications PR (#5421) Task/Issue URL: https://app.asana.com/0/1174433894299346/1208848095612597/f ### Description Update PR Workflow to latest version --- .github/workflows/pr-review-notifications.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-review-notifications.yaml b/.github/workflows/pr-review-notifications.yaml index 406495034b5b..e39c117c962f 100644 --- a/.github/workflows/pr-review-notifications.yaml +++ b/.github/workflows/pr-review-notifications.yaml @@ -7,7 +7,7 @@ on: jobs: pr-reviewed: name: Add PR reviewed comment - uses: duckduckgo/native-github-asana-sync/.github/workflows/pr-review-notifications.yml@v1.4 + uses: duckduckgo/native-github-asana-sync/.github/workflows/pr-review-notifications.yml@v1.4.1 with: trigger-phrase: "Task/Issue URL:" secrets: From 381fdc94e10842aea738ff3090bdecb6e0a8ca0a Mon Sep 17 00:00:00 2001 From: Cristian Monforte Date: Fri, 20 Dec 2024 11:08:30 +0100 Subject: [PATCH 21/32] move out of main cta viewmodel checks (#5414) Task/Issue URL: https://app.asana.com/0/1202552961248957/1208737359937198/f ### Description Moves to io main threads db access detected in CtaViewmodel ### Steps to test this PR _Feature 1_ - [x] Smoke tests onboarding - [ ] ### UI changes | Before | After | | ------ | ----- | !(Upload before screenshot)|(Upload after screenshot)| --- .../com/duckduckgo/app/cta/ui/CtaViewModel.kt | 69 ++++++++++--------- .../app/cta/ui/OnboardingDaxDialogTests.kt | 10 ++- 2 files changed, 43 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt b/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt index 429c4902c5c2..54c6c7c5e661 100644 --- a/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt @@ -139,40 +139,41 @@ class CtaViewModel @Inject constructor( } suspend fun onCtaShown(cta: Cta) { - cta.shownPixel?.let { - val canSendPixel = when (cta) { - is DaxCta -> cta.canSendShownPixel() - else -> true + withContext(dispatchers.io()) { + cta.shownPixel?.let { + val canSendPixel = when (cta) { + is DaxCta -> cta.canSendShownPixel() + else -> true + } + if (canSendPixel) { + pixel.fire(it, cta.pixelShownParameters()) + } } - if (canSendPixel) { - pixel.fire(it, cta.pixelShownParameters()) + if (cta is OnboardingDaxDialogCta && cta.markAsReadOnShow) { + dismissedCtaDao.insert(DismissedCta(cta.ctaId)) } - } - if (cta is OnboardingDaxDialogCta && cta.markAsReadOnShow) { - dismissedCtaDao.insert(DismissedCta(cta.ctaId)) - } - if (cta is BrokenSitePromptDialogCta) { - brokenSitePrompt.ctaShown() - } - withContext(dispatchers.io()) { + if (cta is BrokenSitePromptDialogCta) { + brokenSitePrompt.ctaShown() + } + if (cta is DaxBubbleCta.DaxPrivacyProCta || cta is DaxBubbleCta.DaxExperimentPrivacyProCta) { extendedOnboardingPixelsPlugin.testPrivacyProOnboardingShownMetricPixel()?.getPixelDefinitions()?.forEach { pixel.fire(it.pixelName, it.params) } } - } - // Temporary pixel - val isVisitSiteSuggestionsCta = - cta is DaxBubbleCta.DaxIntroVisitSiteOptionsCta || cta is DaxBubbleCta.DaxExperimentIntroVisitSiteOptionsCta || - cta is OnboardingDaxDialogCta.DaxSiteSuggestionsCta || cta is OnboardingDaxDialogCta.DaxExperimentSiteSuggestionsCta - if (isVisitSiteSuggestionsCta) { - if (userBrowserProperties.daysSinceInstalled() <= MIN_DAYS_TO_COUNT_ONBOARDING_CTA_SHOWN) { - val count = onboardingStore.visitSiteCtaDisplayCount ?: 0 - pixel.fire(AppPixelName.ONBOARDING_VISIT_SITE_CTA_SHOWN, mapOf("count" to count.toString())) - onboardingStore.visitSiteCtaDisplayCount = count + 1 - } else { - onboardingStore.clearVisitSiteCtaDisplayCount() + // Temporary pixel + val isVisitSiteSuggestionsCta = + cta is DaxBubbleCta.DaxIntroVisitSiteOptionsCta || cta is DaxBubbleCta.DaxExperimentIntroVisitSiteOptionsCta || + cta is OnboardingDaxDialogCta.DaxSiteSuggestionsCta || cta is OnboardingDaxDialogCta.DaxExperimentSiteSuggestionsCta + if (isVisitSiteSuggestionsCta) { + if (userBrowserProperties.daysSinceInstalled() <= MIN_DAYS_TO_COUNT_ONBOARDING_CTA_SHOWN) { + val count = onboardingStore.visitSiteCtaDisplayCount ?: 0 + pixel.fire(AppPixelName.ONBOARDING_VISIT_SITE_CTA_SHOWN, mapOf("count" to count.toString())) + onboardingStore.visitSiteCtaDisplayCount = count + 1 + } else { + onboardingStore.clearVisitSiteCtaDisplayCount() + } } } } @@ -250,8 +251,8 @@ class CtaViewModel @Inject constructor( } suspend fun getFireDialogCta(): OnboardingDaxDialogCta? { - if (!daxOnboardingActive() || daxDialogFireEducationShown()) return null return withContext(dispatchers.io()) { + if (!daxOnboardingActive() || daxDialogFireEducationShown()) return@withContext null if (highlightsOnboardingExperimentManager.isHighlightsEnabled()) { return@withContext OnboardingDaxDialogCta.DaxExperimentFireButtonCta(onboardingStore, appInstallStore) } else { @@ -261,8 +262,8 @@ class CtaViewModel @Inject constructor( } suspend fun getSiteSuggestionsDialogCta(): OnboardingDaxDialogCta? { - if (!daxOnboardingActive() || !canShowDaxIntroVisitSiteCta()) return null return withContext(dispatchers.io()) { + if (!daxOnboardingActive() || !canShowDaxIntroVisitSiteCta()) return@withContext null if (highlightsOnboardingExperimentManager.isHighlightsEnabled()) { return@withContext OnboardingDaxDialogCta.DaxExperimentSiteSuggestionsCta(onboardingStore, appInstallStore) } else { @@ -272,8 +273,8 @@ class CtaViewModel @Inject constructor( } suspend fun getEndStaticDialogCta(): OnboardingDaxDialogCta.DaxExperimentEndStaticCta? { - if (!daxOnboardingActive() && daxDialogEndShown()) return null return withContext(dispatchers.io()) { + if (!daxOnboardingActive() && daxDialogEndShown()) return@withContext null return@withContext OnboardingDaxDialogCta.DaxExperimentEndStaticCta(onboardingStore, appInstallStore) } } @@ -473,7 +474,7 @@ class CtaViewModel @Inject constructor( } } - private suspend fun isSiteNotAllowedForOnboarding(site: Site): Boolean { + private fun isSiteNotAllowedForOnboarding(site: Site): Boolean { val uri = site.url.toUri() if (subscriptions.isPrivacyProUrl(uri)) return true @@ -502,9 +503,11 @@ class CtaViewModel @Inject constructor( // We only want to show New Tab when the Home CTAs from Onboarding has finished // https://app.asana.com/0/1157893581871903/1207769731595075/f suspend fun areBubbleDaxDialogsCompleted(): Boolean { - val noBrowserCtaExperiment = extendedOnboardingFeatureToggles.noBrowserCtas().isEnabled() - val bubbleCtasShown = daxDialogEndShown() && (daxDialogNetworkShown() || daxDialogOtherShown() || daxDialogTrackersFoundShown()) - return noBrowserCtaExperiment || bubbleCtasShown || hideTips() || !userStageStore.daxOnboardingActive() + return withContext(dispatchers.io()) { + val noBrowserCtaExperiment = extendedOnboardingFeatureToggles.noBrowserCtas().isEnabled() + val bubbleCtasShown = daxDialogEndShown() && (daxDialogNetworkShown() || daxDialogOtherShown() || daxDialogTrackersFoundShown()) + noBrowserCtaExperiment || bubbleCtasShown || hideTips() || !userStageStore.daxOnboardingActive() + } } private fun daxDialogSerpShown(): Boolean = dismissedCtaDao.exists(CtaId.DAX_DIALOG_SERP) diff --git a/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt b/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt index 2bdf27b047be..020ded0aeaa5 100644 --- a/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt +++ b/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt @@ -38,7 +38,6 @@ import com.duckduckgo.app.widget.ui.WidgetCapabilities import com.duckduckgo.brokensite.api.BrokenSitePrompt import com.duckduckgo.browser.api.UserBrowserProperties import com.duckduckgo.common.test.CoroutineTestRule -import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.duckplayer.api.DuckPlayer import com.duckduckgo.feature.toggles.api.Toggle import kotlinx.coroutines.test.runTest @@ -72,7 +71,6 @@ class OnboardingDaxDialogTests { private val onboardingStore: OnboardingStore = mock() private val userStageStore: UserStageStore = mock() private val tabRepository: TabRepository = mock() - private val dispatchers: DispatcherProvider = mock() private val duckDuckGoUrlDetector: DuckDuckGoUrlDetector = mock() private val extendedOnboardingFeatureToggles: ExtendedOnboardingFeatureToggles = mock() private val mockDuckPlayer: DuckPlayer = mock() @@ -95,7 +93,13 @@ class OnboardingDaxDialogTests { widgetCapabilities, dismissedCtaDao, userAllowListRepository, - settingsDataStore, onboardingStore, userStageStore, tabRepository, dispatchers, duckDuckGoUrlDetector, extendedOnboardingFeatureToggles, + settingsDataStore, + onboardingStore, + userStageStore, + tabRepository, + coroutineRule.testDispatcherProvider, + duckDuckGoUrlDetector, + extendedOnboardingFeatureToggles, subscriptions = mock(), mockDuckPlayer, mockHighlightsOnboardingExperimentManager, From b7cf1ca87144fde15e9a5403b4ed876b45f5d2fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Paczos?= Date: Fri, 20 Dec 2024 11:37:13 +0100 Subject: [PATCH 22/32] add default browser selection overflow menu item (#5391) Task/Issue URL: https://app.asana.com/0/72649045549333/1208944504536342/f --- app/lint-baseline.xml | 11 +++++ .../app/browser/BrowserTabFragment.kt | 3 ++ .../app/browser/BrowserTabViewModel.kt | 4 ++ .../app/browser/menu/BrowserPopupMenu.kt | 9 ++++ .../app/browser/viewstate/BrowserViewState.kt | 1 + .../background_default_browser_menu_item.xml | 20 +++++++++ .../res/layout/popup_window_browser_menu.xml | 4 ++ .../popup_window_browser_menu_bottom.xml | 4 ++ .../layout/view_menu_item_default_browser.xml | 41 +++++++++++++++++++ .../ic_default_browser_mobile_color_16.xml | 21 ++++++++++ 10 files changed, 118 insertions(+) create mode 100644 app/src/main/res/drawable/background_default_browser_menu_item.xml create mode 100644 app/src/main/res/layout/view_menu_item_default_browser.xml create mode 100644 common/common-ui/src/main/res/drawable/ic_default_browser_mobile_color_16.xml diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml index 734ba3cc6bc5..32ea3646c177 100644 --- a/app/lint-baseline.xml +++ b/app/lint-baseline.xml @@ -7679,4 +7679,15 @@ column="9"/> + + + + diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index 8e374db5e616..6bd769638a08 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -1042,6 +1042,9 @@ class BrowserTabFragment : onMenuItemClicked(changeBrowserModeMenuItem) { viewModel.onChangeBrowserModeClicked() } + onMenuItemClicked(defaultBrowserMenuItem) { + viewModel.onSetDefaultBrowserSelected() + } onMenuItemClicked(sharePageMenuItem) { pixel.fire(AppPixelName.MENU_ACTION_SHARE_PRESSED) viewModel.onShareSelected() diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt index 4a0e7b4d7797..9a95f9fe31fd 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt @@ -2524,6 +2524,10 @@ class BrowserTabViewModel @Inject constructor( } } + fun onSetDefaultBrowserSelected() { + // no-op, to be implemented + } + fun onShareSelected() { url?.let { viewModelScope.launch(dispatchers.io()) { diff --git a/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt b/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt index b955233543cb..d62cf953ca03 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt @@ -87,6 +87,13 @@ class BrowserPopupMenu( } } + internal val defaultBrowserMenuItem: View by lazy { + when (omnibarPosition) { + TOP -> topBinding.includeDefaultBrowserMenuItem.defaultBrowserMenuItem + BOTTOM -> bottomBinding.includeDefaultBrowserMenuItem.defaultBrowserMenuItem + } + } + internal val sharePageMenuItem: View by lazy { when (omnibarPosition) { TOP -> topBinding.sharePageMenuItem @@ -240,6 +247,8 @@ class BrowserPopupMenu( newTabMenuItem.isVisible = browserShowing && !displayedInCustomTabScreen sharePageMenuItem.isVisible = viewState.canSharePage + defaultBrowserMenuItem.isVisible = viewState.showSelectDefaultBrowserMenuItem + bookmarksMenuItem.isVisible = !displayedInCustomTabScreen downloadsMenuItem.isVisible = !displayedInCustomTabScreen settingsMenuItem.isVisible = !displayedInCustomTabScreen diff --git a/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt b/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt index 66dd8df17782..bfb487f1e751 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt @@ -34,6 +34,7 @@ data class BrowserViewState( val showTabsButton: Boolean = true, val fireButton: HighlightableButton = HighlightableButton.Visible(), val showMenuButton: HighlightableButton = HighlightableButton.Visible(), + val showSelectDefaultBrowserMenuItem: Boolean = false, val canSharePage: Boolean = false, val canSaveSite: Boolean = false, val bookmark: SavedSite.Bookmark? = null, diff --git a/app/src/main/res/drawable/background_default_browser_menu_item.xml b/app/src/main/res/drawable/background_default_browser_menu_item.xml new file mode 100644 index 000000000000..2b7583e3949c --- /dev/null +++ b/app/src/main/res/drawable/background_default_browser_menu_item.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/popup_window_browser_menu.xml b/app/src/main/res/layout/popup_window_browser_menu.xml index 255f393c7760..98a6a4907ce5 100644 --- a/app/src/main/res/layout/popup_window_browser_menu.xml +++ b/app/src/main/res/layout/popup_window_browser_menu.xml @@ -97,6 +97,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common/common-ui/src/main/res/drawable/ic_default_browser_mobile_color_16.xml b/common/common-ui/src/main/res/drawable/ic_default_browser_mobile_color_16.xml new file mode 100644 index 000000000000..8e8bd4b949ff --- /dev/null +++ b/common/common-ui/src/main/res/drawable/ic_default_browser_mobile_color_16.xml @@ -0,0 +1,21 @@ + + + + + + + + From d0456108a4817ba6c778b112e9f606853e95a7ac Mon Sep 17 00:00:00 2001 From: Lukasz Macionczyk Date: Fri, 20 Dec 2024 12:57:24 +0100 Subject: [PATCH 23/32] Fix trying to get non-existent subscription (#5418) Task/Issue URL: https://app.asana.com/0/1205648422731273/1209011223549610/f ### Description In certain scenarios, the app makes unnecessary requests to api/subscriptions endpoint - this PR addresses that. More context in the linked task. ### Steps to test this PR See task. ### No UI changes --- subscriptions/subscriptions-impl/build.gradle | 1 + .../impl/SubscriptionsChecker.kt | 12 +- .../impl/RealSubscriptionsCheckerTest.kt | 99 +++++++++++++++ .../impl/SubscriptionsCheckWorkerTest.kt | 119 ++++++++++++++++++ 4 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsCheckerTest.kt create mode 100644 subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/SubscriptionsCheckWorkerTest.kt diff --git a/subscriptions/subscriptions-impl/build.gradle b/subscriptions/subscriptions-impl/build.gradle index ea120b157bc6..c91340bc7f2f 100644 --- a/subscriptions/subscriptions-impl/build.gradle +++ b/subscriptions/subscriptions-impl/build.gradle @@ -102,6 +102,7 @@ dependencies { // conflicts with mockito due to direct inclusion of byte buddy exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug" } + testImplementation AndroidX.work.testing coreLibraryDesugaring Android.tools.desugarJdkLibs } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsChecker.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsChecker.kt index 61b5c52eebdc..fc18fa190c5a 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsChecker.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsChecker.kt @@ -67,7 +67,7 @@ class RealSubscriptionsChecker @Inject constructor( } override suspend fun runChecker() { - if (!subscriptionsManager.isSignedIn()) return + if (!subscriptionsManager.canRefreshSubscription()) return workManager.enqueueUniquePeriodicWork( TAG_WORKER_SUBSCRIPTION_CHECK, @@ -94,7 +94,7 @@ class SubscriptionsCheckWorker( override suspend fun doWork(): Result { return try { - if (subscriptionsManager.isSignedIn()) { + if (subscriptionsManager.canRefreshSubscription()) { if (subscriptionsManager.isSignedInV2()) { subscriptionsManager.refreshSubscriptionData() val subscription = subscriptionsManager.getSubscription() @@ -112,10 +112,6 @@ class SubscriptionsCheckWorker( } } else { subscriptionsManager.fetchAndStoreAllData() - val subscription = subscriptionsManager.getSubscription() - if (subscription?.status == null || subscription.status == UNKNOWN) { - workManager.cancelUniqueWork(TAG_WORKER_SUBSCRIPTION_CHECK) - } } } else { workManager.cancelUniqueWork(TAG_WORKER_SUBSCRIPTION_CHECK) @@ -139,3 +135,7 @@ private fun buildSubscriptionCheckPeriodicWorkRequest(nextScheduleTimeOverride: } } .build() + +private suspend fun SubscriptionsManager.canRefreshSubscription(): Boolean { + return isSignedIn() && subscriptionStatus() != UNKNOWN +} diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsCheckerTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsCheckerTest.kt new file mode 100644 index 000000000000..8be115262c45 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsCheckerTest.kt @@ -0,0 +1,99 @@ +package com.duckduckgo.subscriptions.impl + +import android.content.Context +import androidx.lifecycle.Lifecycle.State.INITIALIZED +import androidx.lifecycle.Lifecycle.State.STARTED +import androidx.lifecycle.testing.TestLifecycleOwner +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.work.WorkInfo +import androidx.work.WorkManager +import androidx.work.testing.TestDriver +import androidx.work.testing.WorkManagerTestInitHelper +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +@RunWith(AndroidJUnit4::class) +class RealSubscriptionsCheckerTest { + + @get:Rule + var coroutineRule = CoroutineTestRule() + + private val processLifecycleOwner = TestLifecycleOwner(initialState = INITIALIZED) + private val subscriptionsManager: SubscriptionsManager = mock() + private lateinit var workManager: WorkManager + private lateinit var testDriver: TestDriver + private lateinit var subscriptionsChecker: RealSubscriptionsChecker + + @Before + fun setUp() { + val context: Context = ApplicationProvider.getApplicationContext() + WorkManagerTestInitHelper.initializeTestWorkManager(context) + workManager = WorkManager.getInstance(context) + testDriver = WorkManagerTestInitHelper.getTestDriver(context)!! + + subscriptionsChecker = RealSubscriptionsChecker( + workManager = workManager, + subscriptionsManager = subscriptionsManager, + appCoroutineScope = coroutineRule.testScope, + dispatcherProvider = coroutineRule.testDispatcherProvider, + ) + + processLifecycleOwner.lifecycle.addObserver(subscriptionsChecker) + } + + @Test + fun `when app started and has active subscription then enqueues checker worker`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.AUTO_RENEWABLE) + + processLifecycleOwner.currentState = STARTED + + val workInfos = workManager.getWorkInfosForUniqueWork(RealSubscriptionsChecker.TAG_WORKER_SUBSCRIPTION_CHECK).get() + assertEquals(1, workInfos.size) + assertEquals(WorkInfo.State.ENQUEUED, workInfos.single().state) + } + + @Test + fun `when user is not signed in then does not enqueue checker worker`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(false) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.UNKNOWN) + + subscriptionsChecker.runChecker() + + val workInfos = workManager.getWorkInfosForUniqueWork(RealSubscriptionsChecker.TAG_WORKER_SUBSCRIPTION_CHECK).get() + assertTrue(workInfos.isEmpty()) + } + + @Test + fun `when user is signed in and subscription has UNKNOWN status then does not enqueue checker worker`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.UNKNOWN) + + subscriptionsChecker.runChecker() + + val workInfos = workManager.getWorkInfosForUniqueWork(RealSubscriptionsChecker.TAG_WORKER_SUBSCRIPTION_CHECK).get() + assertTrue(workInfos.isEmpty()) + } + + @Test + fun `when user is signed in and subscription has WAITING status then enqueues checker worker`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.WAITING) + + subscriptionsChecker.runChecker() + + val workInfos = workManager.getWorkInfosForUniqueWork(RealSubscriptionsChecker.TAG_WORKER_SUBSCRIPTION_CHECK).get() + assertEquals(1, workInfos.size) + assertEquals(WorkInfo.State.ENQUEUED, workInfos.single().state) + } +} diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/SubscriptionsCheckWorkerTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/SubscriptionsCheckWorkerTest.kt new file mode 100644 index 000000000000..e324b7b1a7d6 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/SubscriptionsCheckWorkerTest.kt @@ -0,0 +1,119 @@ +package com.duckduckgo.subscriptions.impl + +import androidx.test.core.app.ApplicationProvider +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.work.WorkManager +import androidx.work.testing.TestWorkerBuilder +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +@RunWith(AndroidJUnit4::class) +class SubscriptionsCheckWorkerTest { + + @get:Rule + var coroutineRule = CoroutineTestRule() + + private val subscriptionsManager: SubscriptionsManager = mock() + private val workManager: WorkManager = mock() + + private val subscriptionCheckWorker: SubscriptionsCheckWorker = TestWorkerBuilder + .from( + ApplicationProvider.getApplicationContext(), + SubscriptionsCheckWorker::class.java, + ) + .build() + .also { worker -> + worker.workManager = workManager + worker.subscriptionsManager = subscriptionsManager + } + + @Test + fun `when user is signed in using auth v1 and subscription is active then refreshes subscription data`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.isSignedInV2()).thenReturn(false) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.AUTO_RENEWABLE) + + subscriptionCheckWorker.doWork() + + verify(subscriptionsManager).fetchAndStoreAllData() + } + + @Test + fun `when user is signed in using auth v2 and subscription is active then refreshes subscription data`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.isSignedInV2()).thenReturn(true) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.AUTO_RENEWABLE) + + subscriptionCheckWorker.doWork() + + verify(subscriptionsManager).refreshSubscriptionData() + } + + @Test + fun `when user is signed in using auth v1 and subscription has WAITING status then refreshes subscription data`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.isSignedInV2()).thenReturn(false) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.WAITING) + + subscriptionCheckWorker.doWork() + + verify(subscriptionsManager).fetchAndStoreAllData() + } + + @Test + fun `when user is signed in using auth v2 and subscription has WAITING status then refreshes subscription data`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.isSignedInV2()).thenReturn(true) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.WAITING) + + subscriptionCheckWorker.doWork() + + verify(subscriptionsManager).refreshSubscriptionData() + } + + @Test + fun `when user is not signed in then cancels work`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(false) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.UNKNOWN) + + subscriptionCheckWorker.doWork() + + verify(subscriptionsManager, never()).refreshSubscriptionData() + verify(subscriptionsManager, never()).fetchAndStoreAllData() + verify(workManager).cancelUniqueWork(RealSubscriptionsChecker.TAG_WORKER_SUBSCRIPTION_CHECK) + } + + @Test + fun `when user is signed using auth v1 and subscription has UNKNOWN status then cancels work`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.isSignedInV2()).thenReturn(false) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.UNKNOWN) + + subscriptionCheckWorker.doWork() + + verify(subscriptionsManager, never()).refreshSubscriptionData() + verify(subscriptionsManager, never()).fetchAndStoreAllData() + verify(workManager).cancelUniqueWork(RealSubscriptionsChecker.TAG_WORKER_SUBSCRIPTION_CHECK) + } + + @Test + fun `when user is signed using auth v2 and subscription has UNKNOWN status then cancels work`() = runTest { + whenever(subscriptionsManager.isSignedIn()).thenReturn(true) + whenever(subscriptionsManager.isSignedInV2()).thenReturn(true) + whenever(subscriptionsManager.subscriptionStatus()).thenReturn(SubscriptionStatus.UNKNOWN) + + subscriptionCheckWorker.doWork() + + verify(subscriptionsManager, never()).refreshSubscriptionData() + verify(subscriptionsManager, never()).fetchAndStoreAllData() + verify(workManager).cancelUniqueWork(RealSubscriptionsChecker.TAG_WORKER_SUBSCRIPTION_CHECK) + } +} From f5097983a487f37c0445008d314874729674d69b Mon Sep 17 00:00:00 2001 From: Shane Osbourne Date: Fri, 20 Dec 2024 14:30:07 +0000 Subject: [PATCH 24/32] bump privacy dashboard to 7.3.1 (#5419) Task/Issue URL: https://app.asana.com/0/414730916066338/1209003600291441/f Re: https://app.asana.com/0/414730916066338/1209021936559905/f ### Description The assets for the dashboard were removed by mistake, this PR adds them back. Please see the link above for more details. ### Steps to test this PR - The dashboard loads correctly _Feature 1_ - [ ] - [ ] ### UI changes | Before | After | | ------ | ----- | !(Upload before screenshot)|(Upload after screenshot)| --- .../build/app/html/android.html | 32 + .../build/app/html/browser.html | 32 + .../build/app/html/iframe.html | 13 + .../privacy-dashboard/build/app/html/ios.html | 32 + .../build/app/html/macos.html | 32 + .../build/app/html/popup.html | 32 + .../build/app/html/windows.html | 32 + .../build/app/img/arrow--large.svg | 1 + .../build/app/img/arrow@2x.png | Bin 0 -> 227 bytes .../build/app/img/arrow@3x.png | Bin 0 -> 301 bytes .../build/app/img/blocking--off.svg | 1 + .../build/app/img/blocking--on.svg | 1 + .../build/app/img/broken-bicycle.svg | 87 + .../privacy-dashboard/build/app/img/check.svg | 1 + .../privacy-dashboard/build/app/img/close.svg | 12 + .../build/app/img/ddg-icon@2x.png | Bin 0 -> 1419 bytes .../build/app/img/ddg-logo-simple@2x.png | Bin 0 -> 1972 bytes .../privacy-dashboard/build/app/img/error.svg | 1 + .../build/app/img/fire-button-header.svg | 26 + .../app/img/hero-on-major-networks-big.svg | 1 + .../build/app/img/hero-on-major-networks.svg | 15 + .../build/app/img/hero-ribbon__bad.svg | 11 + .../build/app/img/hero-ribbon__good.svg | 11 + .../build/app/img/hero-ribbon__mixed.svg | 10 + .../app/img/hero-warning-major-networks.svg | 1 + .../build/app/img/https--off.svg | 1 + .../build/app/img/https--on.svg | 1 + .../build/app/img/icon_128.png | Bin 0 -> 7905 bytes .../build/app/img/icon_16.png | Bin 0 -> 823 bytes .../build/app/img/icon_19.png | Bin 0 -> 892 bytes .../build/app/img/icon_38.png | Bin 0 -> 4706 bytes .../build/app/img/icon_48.png | Bin 0 -> 2813 bytes .../build/app/img/logo-horizontal.png | Bin 0 -> 4314 bytes .../build/app/img/logo-horizontal@2x.png | Bin 0 -> 9187 bytes .../build/app/img/logo-horizontal@3x.png | Bin 0 -> 14223 bytes .../build/app/img/logo-small-new.svg | 16 + .../build/app/img/logo-small.svg | 16 + .../privacy-dashboard/build/app/img/loupe.svg | 4 + .../build/app/img/privacy--bad.svg | 1 + .../build/app/img/privacy--good.svg | 1 + .../build/app/img/privacy--mixed.svg | 1 + .../img/refresh-assets/Block-Allowed-96.svg | 13 + .../img/refresh-assets/Block-Disabled-128.svg | 1 + .../app/img/refresh-assets/Block-Info-128.svg | 22 + .../app/img/refresh-assets/Breakage-128.svg | 25 + .../app/img/refresh-assets/Breakage-96.svg | 1 + .../app/img/refresh-assets/Check-Color-16.svg | 1 + .../img/refresh-assets/Cookies-Hidden-128.svg | 29 + .../refresh-assets/Cookies-Managed-128.svg | 21 + .../app/img/refresh-assets/Counter-128.svg | 1 + .../app/img/refresh-assets/Error-Color-16.svg | 1 + .../app/img/refresh-assets/Locked-128.svg | 15 + .../app/img/refresh-assets/Locked-96.svg | 1 + .../app/img/refresh-assets/Network-128.svg | 1 + .../app/img/refresh-assets/Phishing-128.svg | 20 + .../app/img/refresh-assets/Shield-128.svg | 1 + .../app/img/refresh-assets/Stop-Grey-16.svg | 1 + .../app/img/refresh-assets/Unlocked-128.svg | 1 + .../app/img/refresh-assets/Unlocked-96.svg | 1 + .../img/refresh-assets/back-arrow--light.svg | 1 + .../back-arrow-android--light.svg | 3 + .../img/refresh-assets/back-arrow-android.svg | 3 + .../app/img/refresh-assets/back-arrow.svg | 1 + .../back-chevron-ios--light.svg | 3 + .../img/refresh-assets/back-chevron-ios.svg | 3 + .../app/img/refresh-assets/breakage-sent.svg | 6 + .../img/refresh-assets/chat-private-128.svg | 18 + .../app/img/refresh-assets/chevron--light.svg | 3 + .../build/app/img/refresh-assets/chevron.svg | 3 + .../permissions-camera-light.svg | 1 + .../img/refresh-assets/permissions-camera.svg | 1 + .../permissions-externalScheme-light.svg | 4 + .../permissions-externalScheme.svg | 4 + .../permissions-location-light.svg | 1 + .../refresh-assets/permissions-location.svg | 1 + .../permissions-microphone-light.svg | 1 + .../refresh-assets/permissions-microphone.svg | 1 + .../permissions-notification-light.svg | 1 + .../permissions-notification.svg | 1 + .../permissions-popups-light.svg | 4 + .../img/refresh-assets/permissions-popups.svg | 4 + .../img/refresh-assets/switch-shield-128.svg | 15 + .../tracker-icons/letters/A.svg | 1 + .../tracker-icons/letters/B.svg | 1 + .../tracker-icons/letters/C.svg | 1 + .../tracker-icons/letters/D.svg | 1 + .../tracker-icons/letters/E.svg | 1 + .../tracker-icons/letters/F.svg | 1 + .../tracker-icons/letters/G.svg | 1 + .../tracker-icons/letters/H.svg | 1 + .../tracker-icons/letters/I.svg | 1 + .../tracker-icons/letters/J.svg | 1 + .../tracker-icons/letters/K.svg | 1 + .../tracker-icons/letters/L.svg | 1 + .../tracker-icons/letters/M.svg | 1 + .../tracker-icons/letters/N.svg | 1 + .../tracker-icons/letters/O.svg | 1 + .../tracker-icons/letters/P.svg | 1 + .../tracker-icons/letters/Q.svg | 1 + .../tracker-icons/letters/R.svg | 1 + .../tracker-icons/letters/S.svg | 1 + .../tracker-icons/letters/T.svg | 1 + .../tracker-icons/letters/U.svg | 1 + .../tracker-icons/letters/V.svg | 1 + .../tracker-icons/letters/W.svg | 1 + .../tracker-icons/letters/X.svg | 1 + .../tracker-icons/letters/Y.svg | 1 + .../tracker-icons/letters/Z.svg | 1 + .../tracker-icons/logos/adjust.svg | 5 + .../tracker-icons/logos/adobe.svg | 7 + .../tracker-icons/logos/amazon.svg | 7 + .../tracker-icons/logos/amplitude.svg | 5 + .../tracker-icons/logos/appnexus.svg | 5 + .../tracker-icons/logos/appsflyer.svg | 8 + .../tracker-icons/logos/beeswax.svg | 10 + .../tracker-icons/logos/branchmetrics.svg | 5 + .../tracker-icons/logos/braze.svg | 5 + .../tracker-icons/logos/bugsnag.svg | 5 + .../tracker-icons/logos/chartbeat.svg | 8 + .../tracker-icons/logos/comscore.svg | 6 + .../tracker-icons/logos/criteo.svg | 5 + .../tracker-icons/logos/facebook.svg | 5 + .../tracker-icons/logos/google.svg | 8 + .../tracker-icons/logos/googleadsgoogle.svg | 14 + .../logos/googleanalyticsgoogle.svg | 14 + .../tracker-icons/logos/indexexchange.svg | 5 + .../tracker-icons/logos/instagramfacebook.svg | 24 + .../tracker-icons/logos/iponweb.svg | 5 + .../tracker-icons/logos/kochava.svg | 5 + .../tracker-icons/logos/linkedin.svg | 5 + .../tracker-icons/logos/liveramp.svg | 8 + .../tracker-icons/logos/magnite.svg | 7 + .../tracker-icons/logos/mediamath.svg | 5 + .../tracker-icons/logos/microsoft.svg | 8 + .../tracker-icons/logos/mixpanel.svg | 5 + .../tracker-icons/logos/neustar.svg | 5 + .../tracker-icons/logos/newrelic.svg | 6 + .../tracker-icons/logos/openx.svg | 8 + .../tracker-icons/logos/oracle.svg | 5 + .../tracker-icons/logos/outbrain.svg | 5 + .../tracker-icons/logos/pinterest.svg | 5 + .../tracker-icons/logos/pubmatic.svg | 5 + .../tracker-icons/logos/quantcast.svg | 5 + .../tracker-icons/logos/rythmone.svg | 10 + .../tracker-icons/logos/salesforce.svg | 5 + .../tracker-icons/logos/sharetrough.svg | 7 + .../tracker-icons/logos/smaato.svg | 5 + .../tracker-icons/logos/spotx.svg | 8 + .../tracker-icons/logos/taboola.svg | 6 + .../tracker-icons/logos/tapad.svg | 12 + .../tracker-icons/logos/thenielsencompany.svg | 13 + .../tracker-icons/logos/thetradedesk.svg | 7 + .../tracker-icons/logos/twitter.svg | 5 + .../tracker-icons/logos/urbanairship.svg | 6 + .../tracker-icons/logos/verizonmedia.svg | 5 + .../tracker-icons/logos/warnermedia.svg | 5 + .../tracker-icons/logos/xaxis.svg | 376 + .../tracker-icons/logos/yahoojapan.svg | 5 + .../tracker-icons/logos/yandex.svg | 5 + .../tracker-icons/logos/youtubegoogle.svg | 12 + .../tracker-icons/logos/zeotap.svg | 14 + .../build/app/img/settings-gear@2x.png | Bin 0 -> 1268 bytes .../build/app/img/shield.svg | 1 + .../build/app/img/social/blocked_comment.svg | 10 + .../app/img/social/blocked_facebook_logo.svg | 12 + .../build/app/img/social/blocked_group.svg | 20 + .../build/app/img/social/blocked_page.svg | 16 + .../build/app/img/social/blocked_post.svg | 16 + .../build/app/img/social/blocked_video.svg | 9 + .../build/app/img/social/dax.png | Bin 0 -> 18151 bytes .../build/app/img/social/loading_dark.svg | 22 + .../build/app/img/social/loading_light.svg | 22 + .../build/app/img/spinner.svg | 1 + .../build/app/img/status--bad.svg | 5 + .../build/app/img/status--good.svg | 4 + .../build/app/img/status--info.svg | 3 + .../build/app/img/status--mixed.svg | 4 + .../privacy-dashboard/build/app/img/wand.svg | 1 + .../privacy-dashboard/build/app/index.html | 18 + .../build/app/public/css/android.css | 148 + .../build/app/public/css/base.css | 765 + .../build/app/public/css/popup.css | 4095 ++++ .../app/public/js/android-breakage-dialog.js | 5042 +++++ .../build/app/public/js/base.js | 18209 ++++++++++++++++ .../build/app/public/js/polyfill-loader.js | 21 + .../build/app/public/js/polyfills.js | 6801 ++++++ package-lock.json | 4 +- package.json | 2 +- 188 files changed, 36687 insertions(+), 3 deletions(-) create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/iframe.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-logo-simple@2x.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/error.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg create mode 100755 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_38.png create mode 100755 node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small-new.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/shield.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/index.html create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/base.js create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js create mode 100644 node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html new file mode 100644 index 000000000000..7c9b0a2f8b0a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html @@ -0,0 +1,32 @@ + + + + + + + DuckDuckGo + + + + + + +
    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html new file mode 100644 index 000000000000..1da908bbb756 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html @@ -0,0 +1,32 @@ + + + + + + + DuckDuckGo + + + + + + +
    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/iframe.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/iframe.html new file mode 100644 index 000000000000..d9775b4af4d8 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/iframe.html @@ -0,0 +1,13 @@ + + + + + Debug + + + + +
    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html new file mode 100644 index 000000000000..c20561b583fd --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html @@ -0,0 +1,32 @@ + + + + + + + DuckDuckGo + + + + + + +
    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html new file mode 100644 index 000000000000..4f83c6830c37 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html @@ -0,0 +1,32 @@ + + + + + + + DuckDuckGo + + + + + + +
    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html new file mode 100644 index 000000000000..cba0171ac1df --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html @@ -0,0 +1,32 @@ + + + + + + + DuckDuckGo + + + + + + +
    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html new file mode 100644 index 000000000000..1c4578fe6407 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html @@ -0,0 +1,32 @@ + + + + + + + DuckDuckGo + + + + + + +
    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg new file mode 100644 index 000000000000..b0fac34d7f5f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..028fe33a282a0dd62f4dbe1dd1ad6b86d0946467 GIT binary patch literal 227 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJRh}-6Ar*{ouQ9SYIf}GC^yp_7 z5{wFQSiSOs6%&Vqi&KX5MY&rJ56XBr4n8zL|M-!7!{@{TbwR@nP6>Vm#-&r1R;}o_ zTD{No!GcH2cfX2e`leOG!XB|gy>~@_W5mUdUmrN+4=C3#^nYN~NqWW{ab%ll!rHic z25G(r{qa|)F#dRKe)Z%03G(ZCE#tDS`R*|Pv*57!^;jq2dH?2yox4_Sw_2&UK4}q) b$^&l2&NI7q@YFQ{UCrR>>gTe~DWM4fmb6!5 literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..83d8e275fe8940371e9e51a3b255debe12e72691 GIT binary patch literal 301 zcmV+|0n+}7P)f*Y1+;-sKoL@aGPiSqK%v9wa)1yeE_Uw z0K)hO>hS@*@%Jz9|6G5GMdQ8D<2~(oLfY|!wBreB#}f)Yp7l|GA&i#+riAfQz=SYf z3TUE(YCP)_caT3Pv_s?ky`BI;35Zz&5|Drw_)fpujP(3N00000NkvXXu0mjf9LjR{ literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg new file mode 100644 index 000000000000..0ab2130baa2d --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg @@ -0,0 +1 @@ +Icon OFF- Networks Blocked \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg new file mode 100644 index 000000000000..de51d5669252 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg @@ -0,0 +1 @@ +Icon ON- Networks Blocked \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg new file mode 100644 index 000000000000..c6c6e9024e8a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg @@ -0,0 +1,87 @@ + + + + Group 73 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg new file mode 100644 index 000000000000..415122ee30d6 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg new file mode 100644 index 000000000000..163acb0e33c3 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg @@ -0,0 +1,12 @@ + +Union +Created using Figma + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..41ca76607be49e48e303daebd0d99122dc39bedb GIT binary patch literal 1419 zcmV;61$6p}P) z>{%4Y?~EavAQ=@6W)X=7jfP@p3V*uw^lVGDn-B#OGn$nk`!p!`q4rin)>6FLf-NW> zHFiQnMM1LhchBeUoXLH^xr4VS`Q`WT{?7M%&iUSR?=NKDXz_SFT3lS*`}FkmT__Z4 zl}9l-qS@Eia%7&LpFbBB6{YX)?$*=k^z~c(hF%-c)6)~XzrRlk==Tobt0rWA6~d{l zt*wmtKLm(45{XR8JAtA5d?d<~Gi zl&r6>&zzs1b3}ziPh(@_x&(2ZM}V5kfWH85Z*Mo_l6B{VoVXrIXp`xa4#xnZ7jrtSG(jWbx;aj73a#g<}v5gXW4(1@w}2cX!)EK`5!~ml@#@ibh^@=*!AWrVEzNnnJxn z4FdG#C?EOi_Zk6!CMPFtrrhPZkOeY*jRrDYks8{nkASZ0$}KtO?F-DVfJd0 ziVr-XRg$7$H={g-bP&`H-)i>^g5w(uj7=-p;VhH)oJl3oj*gDz&4@x-pgA#?89*bN zo13!@$Ti-REuzFv&I?xC(95NOWE-fwPgv#QiroK39 zX~6+$QrJh&~?IHFSyoygNQlzPQT$yM(~AB7z+ki>La%$V~XA43OpDK)E8q2RufH#B#IAQ zd=QC=nt%wXToUM(1RkUY5P_6ix6+HalwP;p8$160nVH?0-JO};s$cSF&Y80_=bQg} z&RGMD6Fkos;AJIB70NsmmnaejP%fi*Q9LNE27|#18NvV=0*SftvIE5}-HZB%Av!t& z5nqqux2Ez6;H-J_TOO1HNc3y?uL&j+3tayV{B0g~4RzjBea`4`f@S8DV6AaOPK{f- z?M3+@9iqAfMN<;7Ez}=rJr08>zSSh9MK-tg1;|@ikL@yv=prrC8+6FI@X~_fB2D@B zHYb^JJRqV44I3d3$%5dk8<6CWkO@H~S0$1w=s&z41`h34jB`1HZ$(FkVZ0!1+8Z`W z+9Z=VLplUS&0QjLq%|_D9L!X!-v;}FC9F^84td+5|L~U?Yna|uwtb&Oax0SjOp~D8 ztf|NmC_0O`?gWFq1dK)_a2yvK8$$o=M{Q@K*#wg0lO8RCM9$rJa2K0Q?S+wW7$DmU zP*x5T>efQ(j5&-ffi!x5*Si^MlRlbAVp{TIcRrFN-vlm!-0MV+w5CRmz$PB>0dKKF z&eT~@SoXL=i!|A!-N!_&I3XR-N0G0CknF#b?i*y}XrKirclCa>S^MiPIbd1a1diJ0 zV_H)KnY#DGO=+hk`Y6lHYHBi5%QZ-4%cbk+NG|{VeNeV|g)TV)Mf+n-pT?qI526+c zJJ|EGu|^`6Dk$X0TJa_nO{-+>5q}W$aOzw;oVhU!T?TG{G zusguM_$Aidxz~e}--IjI)wMk`8iHr5U9fcFbjYf07>^d+l8uNUD`8sTr_6%v>}>eU zHw^09Lf z!X57e$@$ZQzpa%nE>2twR0Y$Cvg{m1_XnJK(|d>Dd|QX=Bj?+^u;<_f<_=~|Kj|XW z+0L${!76scoB8VGRBJojM|0EUYM5GH#3a{hPCF+OBEDXBB_Ax1-_S!e8jU68B?~Ly zG?J^TRG*k!Vc#dKVtrPH#5Bg40c>b>QwjP%#%JJO{5eU3F@kBK-v^OM1WYEu`5Wry zGD$)N>u?A^_)$VV#(wS$bpF}sEt8R$BRz@ zQpa{wmP-9nWazk_T7wdt8v*7V11PG8h(B(2(v~Ddj?CYGAvHPTA;yGvJ z%hwc8G1uHr1pKV(M4e8>Dp~=P6Z{Wq;qN`inF%QoOP~nW^TpiSda2ngpW$;_4&~Ra z0bS^65yAU~k0c_bElDW7Xr>jcG~#}_g*NnZg0$TuE$Xk^L_gGm!J7IVw@Nt}GpU~! z6s_APHCZD@P>kkgB3HDo2{b214f_3l&EI4vEUmf<4Y0e;3|}lagJ)J&%4ck7J@Nd8 z4w!`ete6-#&FG6OaL4ZsVzE|TT%sRFZe4*0`XQ|kkKFwZEMlhTuQWO)vf~g0t=(cL45>=p29y@mqKn6u53B7_ zFdvc@Z8jU6?)nM3f}I$a0B3qmfa$6k0x$;LL^4nogt0stqdXWm!L$$a3`yk5w(q4C zG>_dk_`jq?(H-3$oc_=Wb7#j&ID}NShIUJ7HaJdf}O9XOa zTG=K)RY*xtBuVyPgyJQVc0u(@^mamMXn>WyC-SEyJ`bUw5UM^FESI- zk;n`zA9IVUq1WF7Ry-l8`2H7gjB;?JH~@dzq7W=BV1X#6w0==@2U79?9f*4t`m*)Z zr+u@ux#t%w2ivQSV9qze%AfHB)o6va6>q^S6|X7YaqpcM*@~TxgKf)JGh(8@c_6{( z#tqs;qjc~h#;&#T4^AKAySuwt|6JD@emFG5r-J`t3;X?}5jGx0d5E$F{tt*mkMNlx zD#}@uM$sy1A>&hi8Bv \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg new file mode 100644 index 000000000000..1151a5e558d1 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg new file mode 100644 index 000000000000..4f5e241b570f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg new file mode 100644 index 000000000000..8c6a43371303 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg new file mode 100644 index 000000000000..2f5a1aceef19 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg new file mode 100644 index 000000000000..4527a8f0e3c3 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg new file mode 100644 index 000000000000..1801055f44d3 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg new file mode 100644 index 000000000000..8ee83ae4dbdd --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg new file mode 100644 index 000000000000..03e4ef15071b --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg @@ -0,0 +1 @@ +Icon OFF- Connection \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg new file mode 100644 index 000000000000..534f54444e7d --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg @@ -0,0 +1 @@ +Icon ON- Connection \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png new file mode 100755 index 0000000000000000000000000000000000000000..e661553ef4523f8e786ee4775c19512ed7efd984 GIT binary patch literal 7905 zcmV<79v*F*d`D-Ku&T;oP*%-G$hC4j>HZrusKtyT#ui5TFv&%&g{;t zMtoIMyPDmVR{j6||KI=UZbqL%w64A=9E*=O=pmXDi&4GKs8ZYxbK>E|J6Kr#Ngg3i z-HfsBxOn75ZMsga(Ky=|im~qcpYLv=PZ=0ZaY$j)NF#C9pb@{EG!_;@tRg?agmQ3d ziE-K|{zkK|#aimOwnS(OW6CK&>#Bw-Dh@ToIA5hPezo;%&J#Fq5f-B*O6=+RTlX~6 z6vLEJfY#N^8^vhf${DTlZHDKHgoW51i_=TxrT_x10IfG)&_MCn)ts^Qffc$n zB4TixiDH|A>?Q)K0GRE9ux%7i8z~2bX4Fw(cmZjpW{mw75|CxDe0 zIhcXN}boq>UQ}x;CFGNiKs2EB6SO>~;L+zdQ~4Pw?W#t%Y=NmdCt z8%RYE3IR(5&f!)m+$e%bDm_yF+@5a?t0?Oe8E)+rJ5MnFx!3}&@fYzIq-71PIkJu%0-1vCR^qyCqqk-Mc zImhQ-0XYU(ERa(t?h1;~e*ao~vWQ|7=bPrf@b)9*BYahW)*F{TY-jReS|NB0UM66M zpWOC%-eza*RR4zs@c+f5l~ z3PORR|($2ME9GnTKp6284^JhGVz;5hZx80Mg&{&@YMc2CMhL z&u5zT5P0XKo7^T?0tcsx(EZ}$(!$xm7hd400%Rh47>t=4ekfVA6{d=*cMJT_GdFCu zwRjG=f#*u#nF3@IK1@D@Z^iII?jZP6JD;OZGhq3q35#Gg4iNsa&G*_7Tu+t269vd5 ze2}8kh1s{lr^Vbm1uS9p+KskEvFn-5c9X#~CCFI;G6^5rUL}~m6*ByzpK4%SFg{ku zzzaN4f}9i}$@br&EQIgC)X6Zh_6Lt8)3fDiW)m4d{2pZd22r9Fi6InYrV?NcYVUi@ zk{j460p~3}!|@flL#}mz3edWG=|)k_TdR7_PWXuFk3DdgW5Mu~pHTGOw`lNa8;yKs z0hLu&AzyC$87M{B1&M?Vx`0O74hC8g@ZEY}+a?vdc>dzF*KL(RSl{)FXIE``@91wR z3uL7Ltv4@Q$2ogI^_rdVVaiSjpYIkje7yNCnzmq3M&X-*?x3ln2!s3Hl1{lqK@Kx0 z!A0vA*F}US*henmS^*NIPuq&`WPS|;J?*Bul%Ip};m_Oxzq979f2D%iVaf$i1SDhN zR)!C~M?rjYNkE*$N-l1PaAN z1vEN3N&^D}@){Z%lGn({hs$ftc<2jo90*oG^?|kHYUsvW$-1ZYVR)AzD&+Dq!&iK&|rSN-1 ze4mZacZK?Mi7#y=!X*GDz~uyeyIvLvs3rz;%Qn<9~xRJ7`N&Rej?(0-_hMk?7(hf-JcMhbsh~xWAb)MNlC_!qLBm9Lh-ys zvP~>{yq$suR0+{%U=9)Svz05;L>1PlE6~UZinVp5NcN!itz!H}k|$r__2&_v6{b*m zB~?~dQgLyy99Q=vP#J*;N!Y9DC^Abe~U&x`IVIIec2NX4`saAfpRN zrg~e=_wD@t;k&=;dtM(xr-jR@r+l3lK>Lbnu>IzK`OLilu_|4fxpDDg}Stom6_&tu$ll#exIQl;$2p z&?_JzgRG)W+?{vCdb*^L5e1||E^{j^Qn~_0T0^ERp{)ftw0h}n8nGwM_c8lnF3rG< zX}^CB`GRTH#ILgw_)d;n_`ss$4d3NXePYcs5>ilM}kJ4;w90A@cah#y+Ft>S&p z{eE$2V%A@?mOe9ofg@(`2cQJgZTcDV3E5h%s1Cv^s0b_<5y3&Zw}Kj)^$Y6RKkd3T z$}i=4O&`L)qlqe4TrFq4mp(oloR(ay5(HqZRpx&Bt$(jv_HJhdl%tx|n6UZ2)$I2p z4J1m=AGRGAfAcN+`nqT7I8_A33aAtj zJVli&V4ST>dvEFwhi+H~4GEjyq%tY+KYq-9lyy~jX4_ucw)0);9~hRiaaMJ?6w0f+ z-luC;E~ZPC*OON`CY0*CYZ__Ex#@&&-~OZW?=BN#5(Fz?Z~?Qxkr!y+Z?f8qsz3%) z6GId2tVXNMe?a!vDF|eb$6+5|c!A9J!Tg)C<{w@ZgWg3;7S_@&*DhBI#!FnXJZ$;e z_}{LVgC2x>0V0Chb0;R}@ZG=%%ryc*25%*~eO&?*T!6;tYV$8IUbxhJOU``H^Zn;u zK!t^cX}*8kD}NAXzK=Hl<5jfzzOVW&d^aey&adPZax)A?c2G$MIjwpJn{^~HrT{Wd zRIK4gQN)b?J-f(r2nA4O`d;1jfe`#vffBp{kS|rpH5pJ@WR>NH8z?UhjYR|6_s4TMK2FzeQKIZDj6hPyAN!l+^n13XF zye5CVsygu<6zSgbvLXsHg5m}e8(F3&1gciAK|e?jYWxC4 zMZp%f3T4YLr=XzU!U`x5PA2>kQ9vxNH>heYSgvG-FU=m)tSvwg@QYX8rEMZ7aO`+5 z%@ytlVJ8wo0Nf<5AgpXwHLsLdtU!*D)+ipHk|WL-Z#2I_wG|pd3SYvWl2XbBNDM(J zc=QWK;t78TShBE=-rN(B`2YjO3xlzNr79XQ_Bu=hCu#Ae1z?P&`+tSzsCm@|7GepK7K#jolO0JiU$;_EI^!v@u0~Hks|(AeJBVGlK-o8|mm-Gsf>1%?U;*2&me}u`V(VA|C)Es73XVasx+IeCwMF zZ~>KoVW#1ykuFZ1nO@+UFE3KwzvbF-Gn?g}N7XqFaA3oQw0EZ!iUS_)L8!Psco zPeh~9tjfT!3I@tcy$vO=UHMu0J71NR$39tvGS?%F4W@&z&M>hVcJBnG#CKCgD)DH% zK16X*{WCR(tFlMF&VDTG5}}|I9)R%c)iV^;!obX&RXsW87<(AGMe!L#r>`J7 z<69yZcCUE+rVvyO<&0rPi=Jvy>x@-~7)vLBs>VlOEx=H}e1HpZg72si7I!_dmMDkNJl|DkE5?(2?@13tuPEaMKEO-${8wI6(|&dO9fyo%>t;*1(r|yhVFy{IB@|%1^h0AjadwV z7mDn5$(e~qH|XPr$l2HIIUyDM$B2MnwA*{}> zaUpsDFNELyCV2vt1<)-TR|25`k^_JU7MIcB;Gkt=XigXqB=+OY2?YokycE7$1VaIU z6G92<${a@muF&-|QKX52hGi#$OpIp&oC^=-QkBQ2#60Qgg$U+a%a35P=E-TA^}y%=eGi|_HiPZ zZA~BzeS7U0zE1#?hrmZfhI<(F=Fj4JC*=*Qq>n|%QpE8nYh~_JovzT{Hue-&0GmGL z4ETPR!0g0K9XTe1XlgVH*?1-h9Pc--$%HDA7gL0W#CW&T0;sgbcNc&t0MURb3VD_f z7&k$szwpcsYl~N3(PO5GD*s=60gx7kq@u{PFuump*we5g8?FDxk8onQDt)D#3LGM z(gjQaPTMvkAAN7Eb^qA&;b9LPX@&D{-H?Zo=VU|K(4%w#6w!E$Ma(b2T&UWM^AZXs zOT*X}K4(-lI(}=V(3Q|>H02@Xq#%K+ZG7UI)}rZJtVQ*UR6fJWdAK>FJt7}Gvj7gQ z04jO4H%@&eP|bd;J)A}15{lld1-(CDB%W>5%h!ygf|MO=*)7#4WK)x z`pe#Q=1d0E>p9Y0I!-6A|9MMGA`cMf5%b!>1P_?Fun^0Q{XXN5iAaFc_3}BaK+c;( z7S<6hc#PXaLq!CA=K&yre&hq71ZO`= zG(GptogiRb=3+)tbJ1RrKvU%ejzS#f~1EL3%fd>xy zUm;X&5^c4YW0cs~DI#ME5E_cM@Djb-yiyp;jm-*x4T-zAxjzfg6~F_80vJ5N@7+TX z-Wt1~KxnCjArL&Ud?GMN0j(#1^mhfSRlwp$lAeb zFGrQ-7WO|<|LmR#RzA(KifCYq`Cfudq|cCw%hLCt^AyQ^fM<098wBMf5VxqhR()`% zYBx7VEbV6ccJZuCVns{;{+ZCejoD z6(UO6P1*oVimIu=*CSL?cz`GU0X9%=iWPKN&Hg?Gp%t~BX4NU8%GfGKEKO73BUKv` z`^p9K$OCdMbPW_T+IfBf{rlC$)K%{IQ1+~WWSpDXA63W{P%1$3K!IlSeZ(lYk7dQt(wLx{D#$` zg}xBN6dvHG1pu6E{oZ_Dh#p*3BxkuDU>*Db##q(#*?#|8<@@bsKVZ8w3|8Qy)yta6 zbdDe_00^Nu17)}Z&)de(Cn)Ly-~iwPI9f)9rw=?zZ*=~aJ{dkHe?F^XKGhV@qQ$45 zPm88C$e-;HSv;HGK2N8QPuIoFPTZT{5u?RzaVi-h`mZk*W)!>uScVhAQk>q$$t!?s zsgpkHYkPcr#m1df37JJ$}sJG`eNNm`3Url_R>pjFVK#|FH(QBkLbdQ zzZ<5!`MiV>Pq<|F2Zgd+crZp@K$`yR)TZCc_iHS64`o0`JGJG#j_$h`)ruMdYfQb* zM@OWPRc8v7F8RD{MDQ%VIwW!c7yhLfg+gR1l?z9o{NqokWB7>es$vMZwf7Lcc62Ab z*1nUXBT;&4|4-?6U9Zt-+)YEY102~iZ7BW-$b|X6;R;k=c;<#5l4k%9XpbbGTBLwnzh{01J;hN6#<12|Ful!{}d-L87= z#50?fn@A#2QN6Z_Jj4FoV^38{q4vHbX;0tv=+NAsph>IsmfQ6&Ub%VXV>D;2Cu)_6>hRbmC z8C}kX$xq zgoCM=Ra)m-IA}8isdNg1WB9EEcEZOPDCGdtm9Y^`!EJf>|@Rr@j_tN&=;*0-Os;sYQi zc1i$JlP%bRaUy8W3f7jnw*W@SIO4F^Ae!9Ec%ZM}6&G*{kY+pKTaiA5d~;veG*1!I9RQJwM$*a;spn7egP6J?3q_F@~1 z-A+ZC^3+k|3#-gN!kXIq9+gbi^?{2B2bVU=r?3J>QV1@fyr4n~qo_FZ#=Uso;J~2# z3~~skdU_*_47tDU&CS0~qkseTDaT{ecemw^2c%bv+(4bx80B2!GzRbLht_o)iRfHk}yiqOQSC zSvx2TmDAkHv#Fuxb9CvSb-M1&Q*`CQ5LFH{p#Y5L^k{U^5nbMcV&Lb(I3qn8r;`OS zip65mO5E~}PF2I!3V{C~!nZnXB9rhz`s!b7>7X3oNvaCRk8#3kQx;ae4zq9P`=KbE zk8W~i4T{T%-}j_^ikTJ;hsR!e;r*Yv=rHRJ}zOB3#3#(;WwVe(Pcv+JY++qW*NC54{_=`+K#-la@Rkjd1cZgBF&#~oD? z`F9?a`w9cKwY6h=2*8xD{Ke;~T)2f$!MJyW;D-i>P29CvqyAY>w#lPWXUlMQap|)-Rg*l9fA%^>oPs5h{qPf1VW-i6YX)vd<0w zJl=1K>e)nRCQ7?-1Er;jvxf`yB5LW}O-D}sSulKE`uQPY>J7q(S^saB{+Q-hokMPb z!q?!wwv-U98)frW_<-l#i;DW@7{IEY`#xyvn0AvUIjxx@~oBW(vK4t`2` z7&E(Au>OK%nYLC$13*Xr5t=7vI?O$UZ`{uYuuiZ7ZpbQTeARVp#H`P)Y zA%_CC{axlvD+G`JNGGlG_@hJ={u$Zud@9;Z8|U`<8W&mOYq z-c5z~WX}qDQ2+xU-ni@$;m_7(dY@ZG$S1(iLo;e!ofr#8jYPA4Jhf-+mC_$j7Gu)jag@JG(_XPDx~ox@fg($ z*D;5q7{z&&_>Zfs`Gm3RiHTf1MdCPEQK!~el-hKypk=BHTZR7z*nnV;bY>*300000 LNkvXXu0mjfi^T7> literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png new file mode 100644 index 0000000000000000000000000000000000000000..d2f71339abe3a404868b1841a571df06cd6727b5 GIT binary patch literal 823 zcmV-71IYY|P)QDY_`!b$o6>{(VwV{XiP7wwCknwVzhR!VORu9%C69Pd= z^8=wMq^9nqR@g1mC{J8W?I6aAs%mM)9X~XbSHrs_!a2X8`I)9v*rx=I$V6i#8%wXY z8+db0O*8>O4F+(r#HKs4NF&{N&=$o3Ws9$*)mH)W7qkhb6x*x@V#-WHjtYw?xKu?) zPLt=_5O9h(Iy@$ERR_=uiQ1pY>mI?7TX=dk&w{?-&2&12AnCN)q5h@jofcwRQ4aSU zB)shU$VfafWyuLymUX9c4B?&A-UF@#04l7g+vy-GN9>Z|M*0cJrhwqC4?#Jgxj|zE zRs;@jGE$)GgV6+~i%c0dl#S0!{)xp#3kF8|7%{SM1Cbxocy5`-wzLIr(FRCo8aTq? z_V*)ASWJzZBLkzQ?;Qfq5FeN2f0NdhZd&g47sQUD2#X@NOYpkcy=b6X)) zTk3GO^FI7k%GmMW8(r{5k{*+q#t)gBTl{{X83LZ;_p-?9Jz002ovPDHLkV1nAL BYzhDX literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png new file mode 100644 index 0000000000000000000000000000000000000000..149582f90ba915d8da96f095440ff59c54ebcb77 GIT binary patch literal 892 zcmV-?1B3jDP)71GS&6zVZ2S^}ElJsQFWbgf! zrG?)cYZ5ckG+95HDbaUa0#LK)a&*|<4C$TYuMyZ>Q;cg$N+Fb=g|4F3Ox>#-$1Ns= z5$K_9Y^Y^-xL5A;sXB;mhivguXXPQc?a8h>JHL{EGYS}i+N~qK9e+WoXD%SU{uA+4|J>q2_8)D5lo_cCaL9`>X$oi;X`wOS(i~XM3Prb5!Sb!I%57I`b;#kE1a{33f(}#{ z0{-9>496%UA7FVAj?U$fVM~ZpV9Nqg6v6X+$T4>V0UI%AqjUTlwB?l$kcrpoz-G^A zj+QE5+`=q89#7Pflm}iD`q=rI5dl3F_Q^4UPk;weqWmpExNF-f(Eo-{vq^NZI zPQ#T}#RSjSDLHSy+!nY3P9zzNuq|+y&*5>eP6JO87mg|)X*HJ?D5$6M3t-XF`tT0MJmt9)Fe@n8PM@8zsBQxTE3Rl`jR%ywsQb-K&lhwR`RoXwH0*00% Sh<>I300007Xf`GRjG~Na}wCfzI7~}1Uv#iB%F@tf? z`4D4lJkDXjyaO0(heCk!ejV5e&REaV z!>{(jJfNtA4Q_640noN#gB}EwA}B6~ura*=@m;Nl`-h-NC<3x2t!sdi>z095UV+<<;<$>~$VKr#a^bAljt-rLC~oWFknQht4m~rU1tn}Q zq5?OphO%4MLHU|>f~b5zq(z6`gwToSVdjlK%WIMncW)sjt{{X7BVM9)3Dq+}l2mcq zCxsLh10;Dfr~6>+*(XyHsRA4MRH0NgZ^F+1#p+JY1K%{;C?cx*(_av3X9ayKB&38? zEqdWi+@BQtW@u$WL9`#$mQ!H4r}cV$Q%x+nX_r(?Tr&e0{wi7@K@ICx&f%@%o#j5QIp z;EpYZYe|yAXnR91J)bv8b|CVCw{3)qj!$NsyL#-9kT_E(fjw$`eJ(2Mny|sYY;Whf z=l?(=afaqX^U-+rYZ zT)-7!f-H`brP!-Vl&G4mI}O*_sl$B1j<|7@w6SNONFU%Z9@Dk;Zb)-Xm=#%dJGvpL zJQNW`L={W*+=8C1deeOd$tM*ZJ-8=*kxSAX5oRWf>{Y`*eM9tC5=0V-y{dlnrpwlJ z7@Sc$PtIrT%J95MAU#9v)`vs~AwjA+{K$RjXLUi^oP?PTycJm_<|OVJ2$Vr!)otLv z`;MSef`d_0jsTtXfz73 zSPXPs2ahN7XZV8WbX0}_Tf=yq2 zCUrim8ahFB9q_;E0)KroG&eU}UP1&{K)3X_L}5DEG;3$#92yvfYsb?Fhv^Cl)k!ww(il`p<1Yx)xSq0IWbCD1 zB1dCffg~&$@=S)K@bHdxt_gAq8i^_-M68M94g~WHVM&ezVN6j+@^>UiL|q|JZb;UV z%_$aH1RB08G(w8&r1r+>6$y?sG5Vv_I+Q4>o3P7)W8Tn`vR%ah8UN3I@fp~;`>3#E zBn4`!sSr?u{_-^)=@Xo_{|dR%VpK(wgm{3K!~>8KEOe@w8hqbZjzHI*y56p#lhGm%s6QUbB|9)ZCGuQW z7&x7FO9%9dQW5Z#g%v0YwP0$V@5N^Iv_qhSTL?dtcVbhUXgz0#IG znRY01%CTcQ+Kw>Q_!D{c3oD@BWry&{L!S^5T8}C7#k6!MIw>>+>0$pmG;PCYugD}wMQj2e?`Pl|R6V4irSMME2O}_pS=I9La#yzrQbsUia2Y>w z=h97{x4&+VuST*i_c*s<*-&`GE)79!>5cC0iC_nFc88FdLSqsKgGO;UM~^^3P%9dfYvx_lX#8C5D;!Z0MA#4{GZn(n=j+#?9V6Gm&hTe|q-(s__OyD>VK$=S_2gTnm&kDh+T1kNxk2PR&1A1iOd_6N%#* zWBPJYq@$^S^OrzCNl?iqLKu-av9bWQ8`(yTBZNR(Jm z4veIX;xn0|%_%3A^!TGu7sG5)%7(26Hb~m&;}%4o8^S0>FY8FmQ*{vTJj7}DNq)&ljhpQ?F8PM@POlgHJxv{l`^ zW1!)up3<=$lklU#ZRtu7hySCa?s{ud(}}(WQS@=!%a$v7e09VOn;`}`gde6etq1Lx zC=-w=S~?~+?7!jkpry>efjVnUUJ-a2;$Bm}Z!gj}V} z=>W&M#hUo!icIM;Ot1NlTDx!fl{l~zlV&MXi|ZU?cqnDZa=~1+6ThxuaNv#-__qxu z@Lzx8hiQLqvl)%j^{T;s#TnbDUTYvMSQQ|Dw6ZHRBil_NJx__z2r+o4kHGTSGP=RcY)L z6;;5OwuzonozO5a+6PD9Jp!+d{sP9MABbbsCB_kg5+w=NZI5zW>xEL+QDt48L{v>U}u!Cj2sU zr7?*s)wDYX)#QKqKcKd@HdSOdIU9n`@2-Q=@-oAvi%J*6%Ice8%SS#BFJJ0~!-G%5 zR4koxDvffO@^H{R*7l0d|MRz;t3SL)bNt6Hl%SFvt5C}wl7}tzkNOU%qeGB&j9?eZ5K=8GMyAN9sv-3_qbz!bSvr=+_16Z7N*@65#3PFj)4GSraBqG>>B@Ih?r$LCrxYEH+6y444N zuNhMtd^7F_$fcmJm!|2_d_w|t1SOcEr73i_bAhTB0l#Jm1Ofr@`Fz6gUkJaQIZKyF z!4BfqhV^jn${8dj0yCKLsMczr_53*8^O^?t4*1|2Y*zVX3_FGhT;|g-8=Zv(V^R3j zY2){4WeZ^O-yJXn){?B$vob!$G<`$sq5d;42V6{&zoi|Gv0;)tttL>Z#F-R-jU9Q? za>^dR;TC|;Jq*>=)#7t(um|>@d=vu70%DS&nHeO;QwxvXdH|MGe^j_1p=byi$`fIk zVTzuDu#dwP^iUR}#+S{qRMQg6Lv$HJEUIC>^0=aPL>5EIdZypeBzecK@&1z+FQKFz zmy$-urUza&Ox7d^kf!WeO-E*vn27I46l+tSzaiKJJ?9QXjL)KUM1@q{b^T`8wf1YU zxV%YR=f}i+g+CpD6BS{LLS>)MpfbY5e}Z>W6VyNSuVOY!ddV3sX2Xpg{`d5aF3BRe ziX~E{as77uH6dyA#wi^{Dk>k2<~nA~nje1h&WmspI;(&G z`;S8BlDh>-cA)R2-r6qG(8?D;)t%c!-0N#98!ix)PF)X)W4gglm#(Oy)S z-=m0tjB2GtDu`y2kV`V%a6JG`+EToJx1eQV3^PD5Bnfg54511=y(K$ri4yiokF(E{Lk@YM zFbl3FragD#<~H*=xeiY0iq%D_cqWqcN$gF3{JiK8EPBzrrAkGCm-G|F(G=))R_Eoi zRbtV!oJZEV_@mU*6pl;Skd(X-dNC>bNFmokEXtyhH1o^L_?Iw(>9o5>&N@+7o+Fr3 z;WXq&i*wNb#KMuoiJ?II$?`=ZN}?!)Nu*VkcbIKlfx*#6jdQLY&>;5IZ{4z_Rv@X< zIPYZnFMO*8i@hkt13F{h`JGt!)(+&7(4;W0#@jIO){3r4o0wpsK?@Esn-<9BVhs&O kWmz1Pni>pzm`f}F26|_bQXmwY1^@s607*qoM6N<$f+5BXsQ>@~ literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png new file mode 100755 index 0000000000000000000000000000000000000000..3346cbf3f62b179695ff8d31b1d89fdb79616073 GIT binary patch literal 2813 zcmV^5!G2Gb-^r%CDnjWAM4^P>%l5+I?E{3yj%R3&Ol z1@sTZsz{M2Pz5Cwkw_D%wTUQgFkr$ivk0mlmFr=aVQfWBO&h)g*&V=Vu^viwM(}d33oo&NX2V@O3sCi z33EZP5%CNGV8YY=0eO!dF%YD-*Bm_EK^Y<=2Kv@ERI94}J%VjB@*jPQ34bw4l;ZP{ z=hz1n9JtIxofeW#21i6YxlPTK!%XY%WB%y7okm93U&6~X(MDPZ`q~iBr+ zhHX)aLxQ7+-xlLcfZr)zJ*`17;(lX;CIFSj6qR16{p+dsX{HPalOd@c=S3}TLX zc?I`PcswAOimiL18X4KQo$ehy5Fyaqq->M{@g?iGkc(|ya%77iANkXp!p7mewxS2b zXmm)cz`KHA7AH(AxBd|!S^p&nNNV0(S3x_^yStOUn^Xf=pKENDWqJ?ir5oBQf7w$) ztwY;?#&-U>Hp!VsxlgPSTFK7N7Ps(hlC=V2Qu#qTz)#AyY!}+_vV#xrZr2Ev=*Kk& zPW?H4eu4(zu#zkv1&OfF!YA9JwmEgHe|lnQiVDB^IOWWLh{HMSioalUm5}qRi-oyO zOVAp^<0CZD(@lBo=b%#?vmbya70CSmI1Ka z07swE4-e7!nd9UMsU(+_MYVyCXYrhgo-VQqn3T>$PW`vUb>QlGCujQRofq7DQZfL$ zXJxg5xboNkDDJu6crjM;hL0#iH;KlEiAIMhJ1?JPBr+bM4Zu-7UueToSMeJ4KVd*1SmbrsUC^X@Kvo-|E7$9l5$;e7V4Bfv$ksv*i6=VM?+-F-*30j7U--9v?I%zM`63 zTRW-Z`|HvY4~S6t>pfz$0t5sQ50lJ)^l6CPRp^vA>(2!PkUpP0k8@;L0Ct}e#iitW z`8QNNcL7-e!YvY^RlpK7+I}KNNtHI8K}|*x2ErsaW7MS&j?KcLZADv@_~SkOboj$_ zbbHv`zRzB~Mf(o-Q1>wVNYe_k0=@Wy_C(e;XhAR_tF#GY!Lp}gI8F+de$nzDh*J=r zpX;EN-u1ocb7Q-#fD}oGcl!YfB1;% zAJn4IDlQqUBG`XfjL0u^j1W>AWKKHuxS1XK!L(}4$&I%$&;aqfjUmy+jn+ziSf6vZbjKwyf z(f}H`$8}U?3McfON+2Fm^|v+vR$~Jv&=RMj+j@f{u@NYM>StDLr#3X z#!X>+4KK~EuWjr?b*HaUvry5y7XykKQO@9oloex=Ss}9iElIsLP2=fB0K%IHJi@O(OOdamJ!0uoo%TYnMfH#R;anBe7a$Gn3* z?fRS;{mnagx*hvgV#6Wg&}CbGpE^6UANa>cNKq8>2Jgi@x-)s3KKkN_(29;pheW}+ zLhx=uazDT~(c}ft5!WgOwckj50t0{~DbK=`&`=uZL+jn|PR<1T0lE7{I0Y0X9P?O~ zZ3*|{0j81>ukRN?kXq|q9g|2|9zQpM0XT=Es;}bwE_04OES(8QvUM!iMeu|2yei6( za}yp1`~eDc!ovaS&m9br&*K&6xR>pZWf0%ciATuPyMsztdLh}CQ&JD&=4tQ7x+=72 zn?-k-PtYkwqcy&5j_aw1zD+Kdi$1-5obHDHEACJ6qGze=VR~)JujniG2k5cN7JBkO z9$I;Ph@QA2(bsM&R5&_C3%&?Z?WiV4G=gC^@I7cB8z}(nzV^_m-N|S*4aC>hHnCHy zq8F$)S%LVLySjBRRn*i{&)pN$aq{P^i9C8~@oUsl(;D-8APQQIhjF(Py`QMrM2L^K z`-~X?#BPm^_UfB_#=R`DSH>!yT==l))|Hf$&?kfcpe3`uPWf4h^$$vb8?QVQZL`O3 z)8hArcXw!lVVhS}+pDz)PrhSDU*_AaB>$7ASK}I6PQ|OIw^>otVVRkimzVap5X-|8 zUMk=|EKEhbFQQ(jA#vbybyjnwd;ItpBTl zwh_`!k#;IZ@~;Ni5T7{NJ-uTSAzb!{cGN^RF8*%}7#TrdRdlu`sexvOE_TxH znGmjH#taytGb7>OZMa*;MqI7?i}n>2osThYWA<{=9#FZK$3kkRL>uux1ab#XH~;8W P00000NkvXXu0mjfbm&y0 literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..259aaa6d9c8f79ab677747917f221b7b669f2e64 GIT binary patch literal 4314 zcmV<05GC)4P)Gqo)BLmgWr zp&yF+fncY?P|;9r(RNxE$5Eyb2vuN|#%zithJe|S_ha|=|2uo`a(DOcayN*bZuU2G zbMKye?m6e4^Sl4oIrm1P>p)9IiNl{}bCE(Wg{V+bv=UMj2WjLG85HtSK=Ue!;`3{C ziqk!|VZW!Sp~*)njB6+~2DGdycWI<;<*Q3VBx9(V*sZ~ z+cSHAV*{lyE|C!N{=KTSQYB?8A3E{desck3E?7(xi_0kE&N5ObWt(0X=T&hmWJdm+S|B?QW#gTM7)+&B~FcOyZO+C-&yx9qwK{GQw9^x2oNmL-z)b$ zA?X)MND#04FMFx?-8c0luR{JMMf;k(l)|{cHHp` z4V-OcNp^x&Yny2qAYhvFb|&n@LONbm#ckB}+RGsVY5{H2toO8j6D|^2iOX@QHf7Ck^V zCgmX8d{zOXg0Of5VE;i4<9a6Z!i~k#yLX;$KT0Vi9m0qg^j_75NYb_ca($R2n^54S z{>z>8#e0XSr?Z2G^9pF<#EE3f$`N+k1ioI7DFMLF)5!-C_kHj;()xQB{;2qtcYb@O z?Q=>YsSrlI>bqu~<_M{8S8&e*;A&{wGdR>yM#kx1t93<-)|Sk zxeu)t*NZq}3P}Y)JV-m0i>>QHkfn>G&6TyCo4)EltNO#?hn{X zR29=$i$y|TydZET0)^9mLuN>f@aN%7Esaw4*x+G??R}wEj54e+e zmE4&wu zKC4EXIIkOvdU^AJblhf)hv-)jlM;ZP3z&z4w8G%v4tqbgd@)GZ+#&k4$C!jhDDmu z80e?b(b3S)MQp$I_777>XKW&6Wv0;|cCHZ{pf5Jikuj4fr;Jto>=;#^2~NLZNfys+ z%%d@YJIlxFq@Fuy2~-Ow?FJd?I@^fF!eop>|4} z!j&@J)ACup&*9^o;Hl0-=9ffBM<-ne&~ZGFRosz>SprsaQZ3X7|E@9XShI5&3|2ev zu-A@^j5s(Cl09sfRmHN)IL}%x$IXZJJV=(7d~tbht_Rma;&`Nubr_2$n3#3Oy!tub zYM2NIBiql{IOT6I@7%F$GFi?W;vE^kf4S5Wkj!p8yp#Z>y^XfJ40WTQHlZxRAS_`A zuzENy2E!#D5JkFn4ukkSf@I{6mV|lbQAyNun&W+^$rM=oC)yYxDaQ(Ke-jU=Pd72R zb0+Hp6N$)kl5~eD_yE*F{qXr*3@!$Y)8`SwUcs)p{q#4Buxy zpQo=3vP01kPD&6wFm7DO9l0dJhBO@*opij_@!%yKhm>BUBT>U$N}C#!dh1bEJkps+ zes5&?lGGKEZRNU_$hM+R*sseCSsM5{I3>FwneE~gM5~5jS0@d0T_(!UH$NXix>%$d z<>1EX6|w|46@XB=8hu%>MdE(DDRDpocp}3jW@<=!ixs@z#`)beHaKMY-bBd91hPmXC-$)Cm>6OCnTV~N?t*h*e7IypAQTl~lK@0pEbA@->G{6BX7$N3 zOH?MhxG^!XWPyBbt<=}oXMQekS?CZ>#N#%1mQ9EqbyZ)WL0SkfuQhOb|gXb|w>vDaP$1E)zDf zm#1kpvD_#uY!L^_*?-2i^JZ=)nsRko%)!K)xsGTC-_G=vtf9Xh+;EKa!XF2ZV*#Xt zQvo$A-o;SHB&7r}2+}q|=ho@cfIFf|?xO)s*5 z7-H~cdwsfOF~aD8$lnceZ^^Ed;TsUV-bg-3HnaiuBKKX)vbdf?{aAmXnXJ{3`D7p9 z-kR(IQav`(whp%x%A(Bqv#lYss}E;TR#VTjq~C&8(X>4ySNiiK~>36 zfYVqmLMBY2lOPi3MHIhP&QzdmEi%|EZL=i^bx87s*-%hRT({fMPLu_2+a*c2JR*Oc zZ0Bxx$vn7T76Kqj7%4y)&f}4J3z1j!UmyU|R+t5XK|UE80{KFoEFK;i#@QjgTzKfM zvOV);-B7jL~r=V_k6m#%-4J5El1uHn<;aFi_}+M zh&{V7*hi!1PEp{NTg>e|AiIo42d7i}_C~U2^^iUHs>%%v1)U3!4#)9;m&Spfci+No zdgttG^pG`F!p?|*hqrpO(14+H5o8YKm+CU4W+aj3Gl}qWdp)EX0F}zun}$lv$fuv< z@?me581w68!7+$*TG$4|YzD}Qa785#CXxj~Wtb-fghV(E&IP9CDrK@ylF(EgnvqX$ zzx3!qa+iMJvb}g{EBOK5V<@MFJ!>EO&d^TLr`%Q%?-Zlcyt1^GFRsRW7MPUpdhMmq zvLrKT4^>ir#ahbFjy>;+l_l-ZuBWjAQ+P9;dsQ5t-}ngmJKO4uuJOtv)M-XWMwDGM zI5_CD5&*??l{CzKm_g9XJ9_k}*Q72dKgmu#ukjpaG$QNN%hJ=$W<9L7)2wc@I`w)v zFARPk6ToXcueTxc{$i!;W$E+KOva|jdpFCEV@N$?d4hQ7R+YP0-5v(%Kt4#j^G`k! zca=)krtKV6$&Xd1u*ohwy(TKXKTQ#pP8`-K9&X;?7Hjc(kGv^f_U7O~QR)*H$pfJ) zp>BESft1qMz{OoV*B-~Sm4L)Du0#Rh4$YrH+a60N&sEnm-IppEY0kgkJu5C;jO^f22=)&WW_X(Ox<>FPF(? zr+?jQqvtEq#qj_W&@(sovUzy2(eHiuQ(qNGGK5*+%`3~;)}v~?-iX%|G3Xbbe%w^$ zYWIJa@*dkjxw*Nt`Mq`Y$-vprxx5Maf_Q`4fcPEo2S|h!>{lh7d;cKa)EljCbvqMv z!?xoFUemTq;r|a|ZmBwiFoWj(;+5?}<%&1Ne(|E|;!Vuk#!|N({q58P^N;$46iXAsiAS-!r?S$QQWKOalW0bX(3GeA`Z>VL!p2MoXqXNLl_Ix?8=2 z?myZ~n>kQ??}=WT(cDWDJNl^LvR~v!nFyPJbdYo)Jfv+vvu#Q_6v>O2pDB}{o!t#$ zO#R7kLhn7`eOuiD(H1>K*{hzUiH;1a__Ir>)Z(0bXv>0UY1*V2p|U{W!86ex@_`+R zFGXSXv+-+GJVQ}6d*88oN+D?xGp@1oqxPmJiwjO^16LOI{QY%@{y`nsVA(=C^^$h+ zGa8zEFHOmt%IbD1Ex&CwRn7e&Wu=9$3;?_J7k6MUW`Ao1P1*P>nzZNv@u>@tvg3uH z(nx!Y&rj-74(~Kj3Q3J?e~LEv1u346QJj!|`5U%|eft;=2EG&(bNWo8^LOshXUO#T zJH)4GIZlTlF=2{|!zL;9IzC|etMARL%H3@2uLS`?Jbces5Ar4oNI1N|%k#q&7`Woo z{OYz@`;XUB3gZTri3iB9zq{GGTdYgKjN($txU-zn*#QZ?{~7@}C|Lc1rB_h7A}FkA zJc+E|}L#>eCTyYuCMR~q`hJUcaWFt*!QdDZ7e*c~n;l?k< zM7&5~k%3*+<^=-UWF}*w@f=52y0L)MrrMgQf5e+2TMEE`0e=8rR-}B(@&Et;07*qo IM6N<$g0=TMB>(^b literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..10487147fb3ede0c62d67a387ab160dc50e43f9e GIT binary patch literal 9187 zcmV<9BOKg`P)n!exnKmVTncTdku&!hJN z|4%XObWcyeru*B!$N&HP8#IAvzhPdBx=GK@;H_^*mVon%>^ z1{u+q#qSMkuN5=eLY5h=`}K=$q|sg4h1p#cM2!no|iKL~d&1HB`Z2Jcu2vxIzQr>)QFW5I=}v3bgQP zG-n9~7d*u1EV9;93fHxC{$i^7^et4%mfTp?Q!D?@5$ncZ zxWb6}!7WY))^YOjpQaQ(gRJJdt$Q|*Mx#07D2U*-uc{AQ6xzXW!|u)33fUX?Y0Usb?Rh)4zK(Z%Zy);0Bjo+CWv;ds~~Gk3UE!w>_9NU%R*( z&6z{af_G?D!@~v{P3k;|%IrISD6+09<0*7rAfD(Ye5tHG!$7;eUF%4r(M)P`5 z3wxSlcBz2%Hge!)Dy}|<%FdsUWI)m~5XFk65t_kSURZ&HhYyUI)d#U1K7K@Wce8=Z zi@kLA%{3xxKTsRpw69|?X*8NiLq@@iH!3!_^4n5-o?GmYg?;A-w+mM`9T2nHyIQDX z!BS7Lb5k6?LU!f4oqFpH>KfqpeFHQ&I7p^x zdb+p(f-{A`pGi;)#n6!`4IJFZF}-UY`!I66W3&{Nfd_!OvgyLvTORn^JN=~5XeK;q z%`A7^4x%;pKYrn8dIC4Ld*@S>GgUQ2b(fNLddt*J_9B=EOAQ9FaKN8Ah_c&upiFn`h{QrXEQUi&M5*FGiwP7(0!8bX!r@HWb62qLp(Dn2*nhB1lOM7rt zLz79y!}c^>&GR-tnfN?qhkL)2mXmeG$Eobf>#1_iTq-LoqkK5=$ldu{nrT4)U|6?m z$*cxxBbK0%6ghnroE+a0~<&g{mKP=G~Oa?1ufC-QNs zI%hUbnKFg)rF`M#fo5{yzT$Y*BnFZw-OoLpm^R2*)^ySA2Xq2MqnWrQ2_CFFwd)wN zvg(ZvS2kB`%DUoXG~<@_G&_8LL4-~PSyZ^T$gTzfdV)aoOE3C>n1%%ut)#uhxb#*lb1I?`w~6Ou#=-}W2o>n+2mx2L_VyIeqn;;Qp6 zb~GmL?irvz?vB#YV_j5HQ9@TN4%4|c*$>nB4uAhAKl>9p^V8JwVlfTAebZ{9=kjO_ zod(;=tCC&o;+2#aCo;AcQRKj?C6SA^j#0M|jYi{}gbIy>LTgoXPi=FDn>?qwcBK_$ zE?7p>rj3f(!NVu$j=P?s3+K(Gg_p8RSXNAb+!dv(mS0R$D@rI^{`J;I$M+znV$+HU z6&hH1u>ss;4J)>i|Fn`uqnS`71dqk8F)h$bbf~eMuD{H8@xHvI+#gZ_MC8)049Z)P!)XqEBk%)7`B39cc zniPvro^I{p#fw*3mX)!Yi(wd@cnuE^w=rj2xvKj5`bv%gi}*4hV?E6 zWzT|h8s>8v#(O@-C?8{#3e1uvOCo&zF2v@@Ic7D6K;6r~MeD9zV;k!hf@fIH%%VD$ zY+iA&+Hk=e7^ecUyF+iB5bqbxk6Vysmo@|@cmM;4+iooi8@SxsM#`Ui`KAl|S&%Ov z3WY)t$tX{@j*N_K2;w3h4;N7zY8npw3R1Y_?+%MQ_d-$ zhh{!LgkErdF=Rmt6#)5AS;OmJo94FXQ&PI7W*|)Q>lNoV@VK`r;&;~Q&bdWmFq&hZ z*~)V=F7umbU#9E6*g`A6)FQ;nZdQ^lXoGiDes|&gxgryMD0*BZUxJL|xzCMbJYJ6D z$=GN?;HM$nfM}YRm)j*Sq@_!jj+gjOXfmA7sK-~rxS9FJd`Uk@oX7`(qYu8kCR-_< z!22YhyA^ohJ-;@&&N0sIz3c|(UxFzOMI%NitTsnct&|`~5ras<8UwRuO{1^ebUEF} z(;M!%in67rH&L68Mf9)YFPgc4A~7yTFvoy%1JSe386FmD9B(9KLTGY|H+isW&z?Qa z=@x*n@kO*U7K^P`T;VWJL-ba>_~MI&+Lto|xN@0dNHPx9#BW#I^Z4A><3Ylrx9Cia z?_~?bPFi&;oA|nGPIG>?^SOl(uHfY!vaeTuAE5v-4byTw{in)?^WcejRG;J=JSDnZN7tgzdf@DCc8dIWLcwmg(S_m57z|Aa- zb$kJ-qpDT%h4cjCE2PN^2;%PDyPG)1RL8=nJ}|;8dcNa?d&GPYkd0JfiXo*+P?H$D`Z%hx3_7ai61j z*{HbiT81^Qu``Gs-;nry?LN{g@kAc$rT|_nTed80zklI{7os#tU`uZ;TOE#3SUR0?n9<)sYqSeEe?6b?@k_z zuOk-o{1{f*FE)Rce!ufIVc}h1hG^;&-Q+FvIXeNs#d?}XW!-WO}sDS_qESyA)6=h zdhoDJv|YrYRlHxnm6M5LBS=8-aW>N!z(R{ZO}sCw`IzzGsZ{nC*AlM77B9=Y2-!s2 z_f)GIgS;&~7QMk4>AkwE8iS3ofuiYby|VRI#Jf_)LRb2}WRbHOKEJWJoizdz!- zS)U7;d2P0*VZqsAhb*;X<&sCzqTnDz!>r(Q^AI^3GOO6q(ik$eLbG4s>%&ae%F-krbBapd!#%W~7^{>W)y=E#!+>KT*eHlot-cGsa)= z0N)rbise%YaTqJt!+p~L*<2xto(ytUMEMvuX_&HTTtz@Rg*fl!b%2Z<#eHOYS4^q(dze#lLne4@Gk`bj* zHz07!Q@T8fUJ1A8Q_bjEmSwqONJ|L!jH0NrKhNtSx9VI}$c;g!K0s7gpKyS3C`8URf{-Au0<|_@nOw#%0 zdAKfG`0Y*>#6Q@g$LoL_d}Ue{QZtS@Arlv=GPP+r@l>E<2aB%j750=5#sx1|)FP>q zh`4?7y%U)I)k`(UG2aggBosLiUzroYTC=eV;42#C(=JSJ$ z>)4Y~3K;d~WLgU8@_2|{N=qjw#=2{nY&0IRrwg4V2vY3wfv;O!v{_$EXxk?fOL#^2 zWw20QS0r!BxZw4;Gmd#CG5ULil{ZjYn%(!1a2QN)S)SsMUgz`vn~wxV(JW_E8i(K+ z6G!mWAU0cHQ3@V4Xztsk$^@SDQtZNV)|iVOKxrj4lNxlT50uAJw^zu<&S);A#s&R| zoy(04QwEUPUbbvmU8>Iq2M1U1Iv;Y+m&d$NKCCVN`&;sf760;+c5;dTE@Z*ujG27$ z4c0U1&4Y)<#mosc99(`P(?4PGkgvh9Z~U@O;*Z^>T6PdRDO{&PB)&Y<+R+^ zuw?}QcvVsG?GpIFGx_0u(%Y4F3jx}ixe6n+jJ4>wyHxSbUJ#c(UE^(~%_1mh z(n)sQkIKogtOOHI_Z|7rj4JC0a(L3H@;>Kd$HUU(kf7tH91xx1;}nMr&x+z1cUWwDQpPYtCngrd~$lPP*zcd?UO>8^&QXG!kKm24{q&wcclCn-Nb6H=0(0l zG;>9~Uo5(hnQ2CPw7ZyL+39SURbC!{zry62dU+7}9R-7l5ZQSJNd$O@I9>|UMs`$0ttowCao0?5@yJhMPoij%ci#T3i zUtd;V6K?GVKa7iC3LtzlSiEMl?$6~@G4E?cb$9aLud*245`SSDFTBSxShkvP>#ED+ zuNgTur*c=9>3>z}4Z_)Pac;)}T%>&S@8FB0$)1M`8HEJAmbbek$@i->J=xt>ju$RB z4;}39B_Cu{v(HQPf-1od(Q=C&vx&2%sodGbIaNw@r9`^Pk#x)OdNwKV*ZL9CY|dx4 zqKD80FYB(mxFeef4}^&=V$>S^j@ReV4Rnp9QDLp~Qx%!7KUjlUXBgA6xWSfq+SD5T zabTsWna1)0j5cVz`j_~+v$gU-WrXOG`&pr`&FX6?4giZTQ>+gSkkQK`7p68k_er&m z4THu^>~K+|+!AgY2pz^1Am!#!dO3Iod|ek*Wx9*p%gXUWx_OQpG~E~*I0oMTdwJbi zl}~qzo-Dzhx9H(~LQqin0OwRzM+w`X!<9vm%T(WY32`LdK0zQ*-kdT3i%JnA>_ggd zAmqqoS&hSyt?0=f5u21*5Lj5-4`&i&y9fgMyOLAv_bU4X@jB@i`&7pS0hJJwGj8R)#n@0&Kw9P|< z`NFYB>~-_G%2+oKW&C-)i#*obMDm=f4Xsu&%tU3vc9=OxUqm2#gp z%GVlli5+j}B(5nhu>*X}7QaybeT!?|P5gR7xkj;WPq70+@GjcQ3a7;Jx_3Hn-a@#w zImhulfFK{++DgY+u-<-zwUonrZ*PfLJAsI~Uzq>qgDi4CCOXQ`*VDW6@1c>-o#me| zIv(*mb(APR*L4tqZ2FdBc|7ec?-9FfTBSAT2w0~A+lN44y_9BPa=Gsq_+=5_)Gd?) zL5QB*FNnn_F;+-6JshOqFCwSQm$ZKS!9+eA6hn;UxFze-{Z`pN^t`qsMbEyL?E#@Y zMGxm6V$5&1WVnXB_VIjqO{Llwyx`h4`M5?ws~lUyA)tvK{p^Bm;RS?AitbUkfo;of zTH`g;`S^o*RX|1@&${Ac!pbWvE2Dhy8fzobH#Uz#0DghhTd|}uF%1D$i!5+>pp^;$ z{~kB{T&|O!zMX|Al`dVI7G>0UxF2vk(f)0(>b9c5CdY`x&CG%4Hb3i?ZY6G*dA$BA zxH(uanq8!cF}Ct{R@ldyZaZ=;k5+q{twnWtF~AJ@pit*j9@APr?u|HZSyl?v8@ zWxHMV1Mw$&|1upXkOHw$y18Mc$3&F3)s}9QI$jpmU<=;6n!LF8Kg#>H0$tnec|$`( zo#~b*StLNYhVb36vKW>@IAc4u?N#+86{v>7wD2*vV7+|Yjq*Ce^@LUt(cOZn zVZS-BinCCZC|fPW4zWC&lPq|h+w!PhQm8l{bL_qi)cxF3G+s@KbKQGPD|vCN+u9t-`HUTn<=KYOjkKAG_g! zWvtkp%_}pj(P)ChA$VqAti_$YD5RBVx5q<$ynM)}%iEtX3egX)E2W?RQ!(WWVs~k+ zJ0vR}J$uI})o3O<4#BJ2E?Q0}GD=8NoZL1V$Aj2aecI=UI9_zbds^k2srA$4?ZCMv zZN9pMe!)WbcC|r&Vd2BPe5kzsmh{%$7>wMc(P(lfNde6M*haUNr)EXr*5=$UPsZ_J z;pH30OSKQZ#RmQ6gHz~7A1k4QbDW3w^1Kk`yuJC0MYh^TTX!1GKX2)s*-9dHj~}a*WY`E+WPhj5qoc%L1nxv?@cv?(7pOTZ(%!KZcyZv?1znn zD?9s+yB)v(`Y6*DTfjpA!9>` ztcX30hR0>>*4fol(EFl_h2UhiZS!P(ye`wE>gwvmYzST`FDaw=XqRVMf7QK5MXUPW|v#Uo%r*>sEn#n~*{|@e2 z%(5I62N1(jMGtM_AbP&t+xGp!wN;y^TvRnbqu_-?AsQY^pJjyw7#m5w9wax?0XKHe zcOGzLWO1zSxScg(YFAdHnPm8Cn6`OeN89ZS=E8o8*z-i&JR{yj#RgU$>?cR5^HiM2 z$&Z@3iRLNAp%VJ}{{QyO(k5W78j!s-iuikC77H9=e?uG(?Cb3lf_5_2FN9IV1o@vC z8rAg=9vG(Cr@TcE35uDko#SYDiXF%8E_iI$_erDCOe%c0#NE8_NbA=Y)Yciwi1J>d zhjxI=;QBffT?{}|1K||({J@~GJ;h`bw>F%cbnx*vCsW&(| z(Jx*Qz);s9&3`LKH@y_1&%Zo{7I%bb_GzNt*bsGEgVZ(H$AUN{MDbI9HK=^Zxo%jf z=iL51n)c7vJLY?d9qa3+3m@D44bo^dla9;*Ef)t@Ep9QL<-*~xn6>$(AJEfpJ?^mbV8QkG_fb`-n!fdq|4xg}SxVhQU3B2&-{{xzzxIig0{g}ci;k7YcsYaSA9s53B3}39=A;TNo?=I|<-)DIn@FS4OiHru zYsK#Eb}vhB`1ldgPR}Tg_ntru3^Bcw)?R-vQA32R(sEHF53Vh&yl2|CQ!%@^5IR_I zy`0$i(Cp=OcjE&zZ+d)~11vX3iXGk?Q%Y#$)Cn3mxX*K+XABrr+ig-!@2I}Rs+)P^ z*J#!kzv+nAq3Ox-hrUmzpLx`=4lQ;X&EzMi&ZQ8&+b^rFV$XA#JrBb>_WbF8seMN-CELUG?SjJV|Z>3{Y%4IBV?>+Wl%>75(0!0 z@m|%5;WqZ}YNf8f?4Z7n-z>_%&zUo)AY)yqLnQ*l=*l6s%dc@*p6YiHuS<$G8dhh_ z3az_vYi+wEi!lT>cZ~Nrm|I6b^Wa=%d!s-4-5Ad$qQs_^QGgv zalwPg!M#qoT~4Z?o}IJAlZ_Qcqhj68PNO-qD2U+M99p%c*&xevSiDTaH&#IC;J%{A zh*wq@%}zoCBhBb#LK=?RCX*8NMkb(=I z&B0X-O(xO$RKkZCU+JX{qAOR<6_nF}IHAZKvwo$r<^&w8LpQMtezi*vzN68c;RGgl zHkpLa2BL=qLrM5zDwBtzeas*!9nN-qkm7|(*r_hnVZc1;f>mT)o9KR z0v9|RA$%6CA;YNm`yDY@4`)`i8_)yroMBowH<9Mp_M%wo~uO7A+XP4GnvDjM9gf?cf`U(cDxtOsfW*FObj83CDdl_@VQ-S!gt=4G8XeEnMJy}L2 z6#^DGURRq%#?Ba9bXw#z8Vwj%!E*xv92t&<4b!SO4P&7t8Z%pA-pk4)F%+Uk;$;{{ tTg;+UmSMGp%urk1FJEjUjYgw!@&Dp&$iQlJH2nYo002ovPDHLkV1inGDXRbg literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..8d88fd63053eb7ff973dc8101e04012365c0b9ff GIT binary patch literal 14223 zcmXY&bzB?G)4(akU5ZP97PkTgiaQjFySux)ySo*);u_qocyTAVyAveHOP}BSM=r^I zZgy{WW@qMZzZ)ShD}jnchy(=%g(~?&R1pg5!^->bU!iG#|F_T=*(YLyPuNG7!o{%?PcSc7!T#@|0R@vXxJ9IsAMaHUk=jH3!E*n$b{xN zvk16_5lPxE(w5GHb(9q>W+aCnOLb!53|f$^h5DFURY7?syYY6~d~FHNTw7lIwWe|P z`nR^?*YfhON7t^m`>qX0XRZ)idKWvM_;y4D*dC{GaA(dGqcIf4l4B(L%l%i1C%Ft3 zD|&*uV9AeE)35gFPuoe)mZ63=Z`X>-ec?iUL9wRKk zgrU=8Znc?IB3`22utFFxBsla9J{6$MoyPom1J=|`xGJiojIxeD(n+2oW(S%YM;swb5Xema^=92*ShdYqvi|h_Ggh~ zeA0$>YH>J=YyIv!PF?B^9zjwJHk4y5dNmA~t$vZs;3o9|)Ok*Yv*jp8p{kw5j0Lum zKaJ{x_uYd9UjDIzx`lO}dGyB#d%J^J)%zkLc3s^7c+OZ8P)tF%X0-AZ#Z@9DRK zr8?G~wDKBs9Z6iLR6mcK`gUf`rQ-){oZfe3(pzDK%^?fU*25C|^_7O1l$NR^9RY1-qsrzT?U zA(%_a_yoWwjk@o?)KTBN@Q}Oe)fI-^NIV~SzTG}!SA+4~fd910-xY4Zh>B7R>vQ&F z;&hPGH@iu!nG%wpcJuu7QUcN2}$=avL8_f0OO;XR@ zt}F;)Xq|_?v*Qjd$P4}l28>YYcPWYnAFGwmR3W*A#6EQ~V@$tOE2`bjC_?klE>4?7 zE99-_>Ax~HgHO>cHC=yMO^^5gCT64Q64oAhcaD^>3t^Dk-L{oX!T7TF07jVyr?ow$ zygf3&_lcbQ+73NMM?1UcZjM=FBK48Inh@3AsoQC2vA#V?hVZMfbA3zVyC>5j>xC>3 zHi?Lnce6rDINuA7Q|;z>9T3L$c#3i6stEUf#G z@AKBnlZ9@W(HRy;r5e8UZYmhO$zYDO;Wk9~z&j-Rg#r9of)D423=pa&$LwJO8cIWY zgg^{)UQA6+iuO&Sd+xTM1_K2Ej?4;Ys-&^D@nt*u|E^H)z+9=o6WC9d#q5=(UUdyC z9Bw06VNF3&=q&zG`e;mOuCPy6~s*$^v?!gX?~bjtqzF0H#1ckHg$=ITfcE; z!%`4E7Fqla%?!p6BF|JKJ8>b?Da7m+bo`7QNS2)25u!?2v?P;(2n~#|W`Pb9eHp6i zoSz+8Un}B4ffiexUD~R9fW?YnKnRrA?MtTS%Fqfzu8W(hu*by4&I}JDprWB^)`X!0itFlF2mt`<*>AMOXrKA=D|Y%=t9ML{ z571bt2Wd-tWTKs{HC<^5*z1dJMEXBE?V$0!6`dE3yUcH`Fn04^qWp{5CZCz3IJCMe zl?F=;R|oXLPXcxPJg$d)1tRbzcG?)^Nq8_)3S-{%bglXMy)Lz%{2#jShPv?{@`aXH zhnHD@P-5La&iXFZXa93|;HIW|{WxvZ77c!C!AB!wWK{3bsMtN@>gPbp7L4UqrvuG` z6F7uNEkAEmSQ3~Y1{824u?nlJdR`Ca9WvU(@AtFU+j#O|b-=V@ZBB(G2-tqEc@YcM z!p=i?zI@{orp)&fAYgtbf&>%MTqP)3xVxuYT3S|8;%)7>sv6~kZ{rda_$u^IKz3AU ze;CHvU!S8`o3>WN{GR;S7@dMF%|b)~oe;Gb0kZdqoWI)wG_P-smTQ9`+T@`nDtN~; zl6MWIkKaU0=nCgM3CK2@IlNivkg&6}?@2r6e>~sKCy|>WyZ3=(;a;XK6XO`;l^u+n zZBFTHd=J-TMLSaF8`||Pao?DXN+dz#vfZs$j@Q{Mo~%3tsVy8?kd4y1x&+hl43+qn zV}#=+t)c=^zbac+59u1tytv}nY+zMM%)enwOjI(@1`70=c+ac}j4lCs{Tf)AxUda}w6ea0`IUiWxHykCcmf{ebrYn&WhX{w*qr&HuWz{%9E ze9{!WcK}j$!yml~^OJGne>35J{2QnFQuF)EukYKWC+swvx}VePNun`rwOuv#;ZZDe zbcou1{ipI4O+&4z$4+CL4WpV)ZXFX>$*J2g`V_jAw+S}m;X^RH^^hE=0|yxpUpI(< zCeOcPy5-(gv-&9#%)4CPX>orHHvJbVqyh^KX{|Uu!U!G}M6)Ch#rbNqL{@Y;fA-nE zWnp5RYP)wX?o>&b*wD>9Q6`z7YHE=7)BO0~An$fh zs|ByLI*$d#f)qW3tl?tw*5fw+*7$bTg{|j5 z)rdKWu_TfEO38OU$6SmE5WSckn<#2j^R&`AUmi=Xu$U><5)dnCn)p2!y88#w?$j?A zJg{Cb>ONbQ+eDEN#ESW$as}3GgU5y>aEYu7ERLDx@<~X6wLb2BNc^O+HDQE~xNWj2 zVtkG=O{`SYq74C2pirLNd^a>SAZ)uolje;0nHh5tcC1}PQ}@j}hR67$w>N_;S(`e4 z=d<*Q-D<9)Y+gKSIPKv4iV~Y47IgN#fvZeuk{(CWdk>q)v%wsq;-MgXA8&iUl`G1b zmNVj$dE4=>@ol7p5JWh)D%oen1yinC?RxYLy!6}X%Wn-!R9^mKQNV^=BN}6U{4|8B z_lD%832N<$l1#gnpD4!~0k<7?xXujCtApSlM)VKiV&HWc^nroySI(zbci#1}Kc&LosT$xK zL7d#JB0dg8%;qvV@`BjPyU@^ZCbiY@qm ziuL5iUG?MbG<&%(kE4TPr977c`?d!boP4l1CT~ymO(_!8kM3TQf#|ru8N4`4HzblL z4^|=~5a&e3ZHxI(!}{l@r>Dmt=bIaS`+0A;3@RrOVXyWwNkxSk2ll6J4!H4~set(tm1*|5L3|2>*UPip zdC3(>AhxO~MV1%*gg+0SJq`k4MMR#J#9RYY01ccTt*OE2*b0fj8k!Xls7||w;*ps7 zUMYa0!T=W87Vw64ey}4!qfev4RzN_MoH-q97eR1*oV1ZyGWB{ef&apX3`kYB6crFW z9st}VZYzyV74J#4}Z_4%jA$!Z42<8g3(I= z)&xRnF~x$3i<{G*TnV`LgGI9P{NVNSrOV4$C$6 z?e$fOXUZv+)zg$FfUnAam4(B?`pZeJVzBI7#X);E?!91JhM%bnLV{|_cQ@iT?VLBB zw@I+V<{}8eGd5GLLUE~Nxfi>;#uGmJ<9#MsXn~2cF~oA+^W6KMpfFkcOhuc8%%-0*qPNTy&8exV9M4ze^$K;+ z>jou4=PCz-q|IIiGyo`M9~YbYOVW*@Q1=kEN^V< zouKU1+#MEx&QRg!g(#xMD~qZjEw+bKk5;|*7YbJZ1Qw`lGN!CjDMqw?zD}2dZ1Su_ zmoXCbc!iqX6eD)KGl+~6GARLtn@pN5={&IQJmDKEp2Xe#>468cLWiKAeyv!Xu z>+q>a_OZ}tbEef@Y1MXi_;l|@3#6TSvgi9u7&Ei9gwJp@hi^<@HWS6%l|E^Jfnw5N zS~=GeV=(??IUP&MsL6z{*8Vn)O3$EHw-$qPe-3z_j4Dm^Z<#RYZvhwWCT_nRgvWk5 zs%jpU!S;wAOx7_MF%~TqmaMVIbQrFffgDh1Bf2SuOe!WLA(U5D+3dqv!1&e1qtxQj zfDLdH8-U%yN?=B9aIIx~X<%6c@Bk?I@tz9eiA%4Zok`QPscV!@t7#!3B7(7iKak(A>ss>)L{S9|t9ySQT(~bmrFjzN4?&@K4 z;<5uR+SJodeGdQ(at)fPbzdwQ(_ zDPhcevc$qzlfd}~n4Ja?a(~Q_q3#{H%=s}W6?1~GnoxuC<)z3r1Xs|SyfTHN8e^_4 ziIq`}nhHIMy2sH48`Vb9q%C$eI7P}J2#i&usqc&-pDpZk zATws;tHE{SBZV6UGFqo#&e!}a@nlDQtiDUhTsd|(@FlMTW?7j2@=|vceQ$KW^>IFe zbdFw1L3P#eCzl@*_f!J6M8lsQRT}oBq;kAqJ+jEV_LiG6FA#BlQ}ERDAll|dNHfpp~@9B zTt>|h%5e|gYr^(wJ(CpTZESmo?5o~g*1LQ8>x(O2%TmIk&>DqlL1XGT`Lc*9lmI`0 zwNb*XKtO@Yr%m4#YaGoFdB77xK2bmngc=2B z>6c86k&z6OsRoI!qg?-z>kZlZ*4m9LD%@SW*c>b}@yp^-!s6lnsbcQDol&KWm%`Q{ zT1&R}E)rap2z2k_8tsZ3^X-fRN?cBl7g6}Mo^oE9A%WLFX@V{JulDEU)4#Qid{jOS zwAv(4(NUX~UtH{4yvGJcFyunWU$Z#slaHTbuYfrHgZ4D*_X=GbHcdu(#NZqL%&TAe zib&ck0Ok`nCAH&K4#3h(vF}uBj6WmWLDd}8 znB-FVP|LnJQUluBrjrmOf=Pxv)D}a^;=4HYu3ApX8`j>P(&gfF#%5KA2v17sc19#^ zvn?=!S9?$*mUx=OR&jCYo>!bpzJJuy<89zs3xcS318b34#j=`=l1PYJ~ zIdd=cq3podUY<+`x^WGxeVcP~z{Z(2s|xPs@yT{1kWhAZ;5O}AOydZJ7|H;%%2-xc z!V7`p{5P%)k1up&qinIH2+703+F`yUD{mjcjL$kVDp@oRwT&13je$S&=(M6!cEi}D zex)G7_0^PMB^4H|#W;th&;W&C?gKZ9Mri3A} zSB={JDk}DzHM7Jw;=DVx=0>05&1aQ&SuVekmA~;Q%VO~Hf~~rWgGL%6f4icG5o#ak z#ZIFH`aM)-%m+9URiJQJe5-D%GQs**66uPkd6p6%Ak`YpmRMu|kzf8G7AaScn>}+> z1w8b4IDnwZnl)zQm-!5#agSzx3RrfDyINfP=7YjQ2v(>%Q8$}THCD}dRcECsZ|Vj4 zm)_^*c}v#bd)hN2@AUrtgNaW~RL%!>n?EfQ%K%Cl)NQjpw4;bPvm#gpg0McbZ4~Sw z6)ZF93)K(KJ-%n9Kz1+Al$<$hiG$HG}xJi?}u; zSj65vqfNB|pU<9G33!QO_j{*wYPS-FOq<<)2;p%a2ZeRI#4OO9*8nvO*( zLt;+_za38i9pqb}A~@kzAkrCc=#*YrzQCvx{?K7Y97jw~4mWjICJ8x#K zR<{0CySJWQuV2+h>SB}xdKJ(G_9DEPpz`PaFp_7=ahgg;CoW0R!0R{^6bg*5D8FiJ z4qSL>++kR-76R!d)TwahAGTRJP7z<`p9<&|nI)}^VX>IJz6>taKo@BzQE?E&ur*QL z@TB`SB*tCZ*{n47+mIH>o1XN0peenr4T*2m6t8=+{w)cGr1qZ^AsqT;OU^aq0Q$o> ze+p$^=LOekRVLpcB*=JVNMC+SlicRv>wCREFM7L>aM1DVv_woWnL5k9@kFO$AA?an zDf&we;#^MWccZo7+3!aYBZhS0c~gVvkK-A4T3P&gRsqLP4%c4*&H4;4=-;=p0f|&CtdhIZ7E)`85NzfW?X5C!l&c?GGyj86tf>m4N6!ahe%AFvr z4k1@NbwfIKlU-vD#x$+3v3{1i4tv|QW6qj`9CqxqC)+Cg0lIC&?Thn+ww+b z8!Z#&Og%^e^&9v5tYEV4fkdnY{EeWI*h+o6@(fD zWy%I?)FBJQ(ZjPE4dMFpDyum`J$(E1XQ{#a}Yy zEcv)KqJJ__H`X&Ig_nb(0=Cy_zYZ-*dGX(eAOoN5N%3^u$#EhH4_4GFm*^^*;^OKQ z>bcmhWHa$lk+j)j`wyZ$$r7#n=3D0BtoC?#FnXNyw6v^B6VNb0ZU#TR|6*yf)vK7q z)X!-&%BD0Qyw{p|a@6>Ow^te))ERO7pgw5YEmc{K0!D@+CpBX1+1q!m`6xRcw96nq zE~E%B!WQ+y1nbg9DoFAPn*s8wr`*2g8((||%qbD6-HdtNy;mV?{O;~c@2eM=wR$}` zGjNWQnkII5TD&c)V*-GaW9;0A;633Iijc42hM8EHDqQ`Z54;;Z(hp@fr0S1>PB9-Q z_7&`jY+`_FInhnfWBfbK5~Igs65;aTprD`!YtYQ^pJnnLSX%S(ONIiW&>F+~<2qXA zc_hB*55(2KH1cEd>ds8Lv(l;qu=gmL>jt=Lhl?FmH!R+4b(;z7D!&nsv(>E?UFv{? zP%ci3xzeQ3zmywAxo%=!=XO5lHD@PXmzA)3y7x;qJ7ltr%6>j?Bk+qFjbRsCSK8%5 z{aHY8GH6tD?3NRqW|Ebk32016l~8C6qe#wjy3+(%6CCOP7!kR!k5;DOX^eJ>rTF0G_6IRd^wN3x@}C>t zUuY&1j7}VJW+JoG%j9OH>{B1zR27_(TekY@sZSpGi?5`BH{^~9X}Mywlhb6pvst9T zWoF}KDQ&v!^E$z4OkL-V89G-y--~#dU(ZMa8^=K=gH(fO5zkW>VV@oxgVJ?=5h#24ey4BWTc0Y7hsOapdlrW|`_PJ3v zi@$p&bEDG^<*Fp`w&oLX*K#3Ja0>*NuI!QV5a1; znhEq+5Xd98m|Ip^=(=8=xw$e*I$+mmSW$U})3H(CBxAqG)8?Y|NfC^pu~xJu`+YU; z6N_#)lgmbZvJXcZ%Y?=6S&Yv$qon6I4ZfCtshn7%&d+ZhN19KS*q)XKR1IFbE;D5C z=iOYd4-9^r-C#NIXg;P-o`iNPtlV8cR_^ZzX&0gm33IvJ)Dd?Q9{=)N*urPgZFBdK z_qj;^UPS2UjdteE#CZd1%(!`mx|u6JKVo5<7X1#s?V`NhGvH>2sQ(?@OPfh3A*Ike z+7Mvx?O9q%_Y>y12kx>?jTb;_Mi#LUm|(zD$gktON?xh!np1b3PVDlyR;nr))jBrE zY#Pls=)^dGaTtJW$?&vefdXEw;?nU%I80J=RHdhvo7d=b8JnKJq~vYw#=&hd{ICo? z7?dr)$Y|QUX3C!Y;pRO4%rrGxB^Cv7m>A>=i$PT&U~AuKRk;*0faq@;ax!lm>dP-i z+el2%6^w<(=()s3%lA&yD=?G7Ey)IHXkj3q^_exYEgDzhW_sgc5m7uC98G zrXpXxRt7C?K-7w=3+cjFmav*ALxt8rrNxXK6Qp}Cm(Jy$7KP(JdJsDj(#* zVJ*_O26eRR#!BwwP4>Ol;In7fIBxM^pjI=%B9b;o183Wn`L4pbxpI}O6X|GT=hC_j z3;UIqyR^WBz533X|7Gfzi#jRogyRxM*h6NYli09B5?kzxw~go5fFdhAwkJVimRyG7 zDW`9qd&BJ{*l~HH_?^nqe_`eTm<Kg8@&Fv(sd&7ZC%+m&4q`O@#=#dDczSd)n#8- z``@?zY4u}8bf21-HXTp4;mxX|7Me{Iu6#2U`v$9l{mCAk)zx|tHk|i1`NGG_B5H~u zmd0H0z+4HmYbNv<7i>uovBCl>At4Ls-dzJsQ*`#shYnYDnlgnVAF!Co9Y&xGCg@4| zI}}ji-7a-$ZFCB1BgO0FEvxhFO0Ng6yV&*}uz2sINmFBy9!Io) zOIy5YN$k@~{W;KO!t4caCGl>ycnd$Jf*hfs+-QPw(YTUm% zJp98A3rd*#)c~H+E*tGwB5ZwBVv?kU2N$|Wxa8eP8IqqsH@~glu=1to(_KazgW$4Y z$RF!HBz<~HdY~%~#+=lUDOtpoqk3xv!0j_{xg1uCHp9#F@Nb+P)vf9|lRn9}&+HNh zD726tD_r^Lq%W>K-*6ZxG)q!CMZhc)rozhy+-Q`O0xyJ^9-Z222jTg@7<9*@gP-u-I6j?l25%C+(`-5YRY#?Q%f3TK^-r1=7g|aH#07%Mw`hCs2MVN9uyy(@`$SSWn za9>>3EJN&MmtPzpIIVTO06nNEW|9)yDZw8$~eKtR&207SF71 zN_84u2CkERG4I^z8GStvqH7k>pD`~c|4y3yEUJ6wk1PDRPjm)Og2RW)f8>_2;|lij9!(k4)0b;V+hp zvM)Y~NQ=AjPgei5qgIv>u#uvZ5En14mKCUyeY@0hmbjpLI(w+GaCZzREGIk)ZiD^S z4Hj*)fAuT*F>B#0HG6beGUrQL@H~1-zTzXB?(3zU&Nx$~(smdG!}vD;g+#zu^QAh@ zwJ@z|Po3)xbj@{{)E2u)hyO8dQEKA57I9mbifq2u zH>qADIn93LRr3b$yl#$Dhd%pLa4$nYOsn^L>}90PdA^pHn{@6gOaukn+|^~baQd$< zE7+%e$3rl#hg1#>vThN3S<3vG5dCCM2sA%1Wf0HqqspMnbOopZBN^P?Zf%}M0!j|$ z+}1_)UgMZ&*dTtQeyvU)U&z3MstK^&e6ftHTbNB~H`wEga)0%*veVna996@zU652G zsO0F(e;f*WbujL70g8wK*Z0-rwz|f{io1?(4hinTMf6VLN9gI7vFv6o!xK0wL(^Bz zRI}TgLk7EGToDiFdmNLgw*$R--$5jQ&(fj#R@!$Lfw^x%4Zx^{1V$$$3%ZC^>!!M3;|cR9qlb}&2*J6yQb_I7G$55BW5 zdz5x;^v<7bf3$pN>y6JHabsIcOI`Ba0hC&H!5e}AnVwMw{72tZsY_ad8h@duEA!`0 z=H)IR5P0~>k#FX3MKA>BW`$noMfXVznEa#vY_D-OTjEirDxHsO&fac_8VsY91ERX_ zIt$i@2gio6)RrI?a@Oj93_+q-BhL&n>ZKUt-j$j`9Z?jn(D#|w~1`Ml0Q=kf0>nRcb_QfOZCx6q?w8U`ycCK zq>1T19&A!HgXLQx?(XxgPj_ z-Tj=xwLo#Mi_!PNhw$Z5uI#GsO-Ova(gGBHtnrT=WAL&+-6N$7-+vUP&b93n(^s@P zt2;UbcXfw>Nqkc*O~)O5zN?q)tZpDrS5{Zot@d$an4nmB7`y+$(p2v~q|V9u5!q=F zOf2BFUbEx;1UeTbD8s=NHSKmIqXlwK{Rv11*HaM?$t^F`{|DL%$}3~7xBGeILEhQH z=-P$`P_qfPmVd{vLDPb`-z&wQj1t@Q^3SSfjP~MUBUQb(%MVW)Z+`MN+3l_G1b4rP z$bv(yw6wJP3C1Cem4~5s;9|_|(qTG#{)fsXwsp#<(Q3h^0#3h}jU9*;G;+8nAL;l=yt39w7ut;uh-Buv?9#cP`kfcNX8F#$bBtzQxe!+x$qYKX z^z2Nf4eSr%%%-nCPc#z=$x*L9+0a*{g0)pPlahuh@_)R8=4$^ya|{|@%$2VBv+@1P zsd{aYULGjtr*&1?J!#jZ14Aj=%@|Qj{R8pIONYlzu|{JW?-OE1Wrlu*s=yUgu#2^I za%?QgZ`jom2wr!6h^*CPX(Q_L?{!kiNJi+2se|@BgM3PRyO%5W-O&5vq&|o)-#Yc- zZa?|cZcTO;JY0L^;&)j$cpx0V2A=UbN37K4JAEaLab^74#8}h8=X!HQ{p{a2SfXLg zCTvVz^qG&R^t_PdlPwqj&dp(SmB1TCc}}zcpkJq4<_t>^HmLZ?A_3HrpKo9}3vYDc zq<1#i_|kx())I;Nwb6Qd;FfdjqVCVPfz`I1G8fm(M#11r%fxLw+Z?MqS~=3w674xT z{04g((Gn7*X^)H0vb$RTeFl>Oj+gTk&3kTq$h_=NM!YM)qMa)lbr7@H^}U5t#B z$PSOD3O7dfr2HoEqx8uCQ`y>ktnG3z4R>RJ(5-$Jto_nNI|v4=2l9ZW&>31RKr;}F zgTKE-oDL?kSDGMeX@|uJ3tDVvg8HBXMiXRkg>&!oZ)KFjpQQHbqP@S0dYZKFaOhXK ziGGxY=TQ&6s#6Iy+%?$no&1N9^L7<;dK!%02i-5#*N~PCN{?$#nIoq;8CUw zUdQycp^fYnQ#Sxa%(Y^nwjk`l+caj6!Y%TPEc^#K_=~mV`A9L%fnb8J_uFT-q5Q`e z8(s<+FwZs@^BF20YP_~JSwq;Fx|6FwCys4NNSV#Xw|n2?@qJ8Gzgg^~**_Z{&12PkTR>YV$S{#;NneFB|7zoh>fyDTMU( zKn?dVhwrRlJ}d37sp4Ag5z*!YpzW4yXh`NKZPCNjXJtNW^Z=Q*$elsYzaOOE!e}ZIO;63U=H8v^b?;ZF$Z4q1kGI9N zaN)I>5iR$LDMszC_u}ZN*9?Dgc{s9B)dTYU?fM?FklSTr_8&&d7AQzFPo#I+vWzet z)4DoB`?bdAWo9o`Yx$T6HTW=tp*m>cYtdE?$+w0b$@>V#B^m3C{C1P2*nitxK7XY$ z=sMs1grO5|^Rm77t>O-)JR(bhVvD`%Egs_DQj#g|dY*T+Wc6qgqXOaizVAPhj%5A~7#SxYk8Z}8zj~>eIUH-R zythZhOO925d7pw?A|m=cT;wgQdIaMo=$u61hT^^k2oA?M`iVjIIy-Z|*cY8Pow8kN z(xe}RWSHPfe@NpleZW+I?-?Br2ea>gTXXsw7QR_DYO2uY57E}Q@W>8QAv(Up%nz3e z3PvWe8m)txuWaS2@Mna@f94UUcfMiy30A88Yl0ak6PALq?Va>l{Wk8prwjMHtGK8Z zsI~Mp=FEXL7d?)$DXQiDSq&lYdX|y)saj)&RPGOGc|}LI*n^)yyxk_vux6e^B6rye zUz|C_9G$WpU + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg new file mode 100644 index 000000000000..4f4179f7a888 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg new file mode 100644 index 000000000000..595f4092e713 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg new file mode 100644 index 000000000000..3f1ac0baf712 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg new file mode 100644 index 000000000000..b749e73b61a1 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg new file mode 100644 index 000000000000..aa7a3cc20844 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg new file mode 100644 index 000000000000..3bdc8437306b --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg new file mode 100644 index 000000000000..7feac82df076 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg new file mode 100644 index 000000000000..ab30f2c6854f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg new file mode 100644 index 000000000000..9743f903c955 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg new file mode 100644 index 000000000000..26b2b27cc47e --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg new file mode 100644 index 000000000000..fbc0e1800214 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg new file mode 100644 index 000000000000..3c7720d7c1fb --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg new file mode 100644 index 000000000000..0b97dd242cb6 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg new file mode 100644 index 000000000000..acc7e592179a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg new file mode 100644 index 000000000000..9d536db9607f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg new file mode 100644 index 000000000000..aa650f927a0c --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg new file mode 100644 index 000000000000..8120be1fde02 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg new file mode 100644 index 000000000000..9393f7e9c04f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg new file mode 100644 index 000000000000..bac34c4036c7 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg new file mode 100644 index 000000000000..da13b75c79c6 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg new file mode 100644 index 000000000000..5d644c8cc65a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg new file mode 100644 index 000000000000..9eb63ce5bb61 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg new file mode 100644 index 000000000000..a97be77f652e --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg new file mode 100644 index 000000000000..1553bd9eceba --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg new file mode 100644 index 000000000000..bb9ce40066db --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg @@ -0,0 +1,3 @@ + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg new file mode 100644 index 000000000000..284e3274ecb9 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg @@ -0,0 +1,3 @@ + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg new file mode 100644 index 000000000000..72e560547da0 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg new file mode 100644 index 000000000000..b901366815ec --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg new file mode 100644 index 000000000000..4fd2d0704d74 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg new file mode 100644 index 000000000000..8ae55c2b93e8 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg new file mode 100644 index 000000000000..8efa014dec0c --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg new file mode 100644 index 000000000000..5bb6f1dbe0b6 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg @@ -0,0 +1,3 @@ + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg new file mode 100644 index 000000000000..7ab5fb3393a8 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg @@ -0,0 +1,3 @@ + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg new file mode 100644 index 000000000000..c8277654d710 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg new file mode 100644 index 000000000000..8850b78a635a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg new file mode 100644 index 000000000000..8233dd2c9344 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg new file mode 100644 index 000000000000..0eb789d68a08 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg new file mode 100644 index 000000000000..6724f6ae8f4a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg new file mode 100644 index 000000000000..12a8ece441cc --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg new file mode 100644 index 000000000000..9a39aad5e9fc --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg new file mode 100644 index 000000000000..1c99013109e3 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg new file mode 100644 index 000000000000..3fa19cfa016f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg new file mode 100644 index 000000000000..a25af02d7840 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg new file mode 100644 index 000000000000..beb4a7c968e2 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg new file mode 100644 index 000000000000..51fd6569d4f5 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg new file mode 100644 index 000000000000..503c722ce911 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg new file mode 100644 index 000000000000..41de0c0e7517 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg new file mode 100644 index 000000000000..2f60d2dce0c3 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg new file mode 100644 index 000000000000..90eaf7b9afde --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg new file mode 100644 index 000000000000..db24c455872c --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg new file mode 100644 index 000000000000..ad198885039b --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg new file mode 100644 index 000000000000..48e96aec6201 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg new file mode 100644 index 000000000000..7699a554bae4 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg new file mode 100644 index 000000000000..54966438d6da --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg new file mode 100644 index 000000000000..217710ed392a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg new file mode 100644 index 000000000000..557f383ef140 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg new file mode 100644 index 000000000000..9a607d3be398 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg new file mode 100644 index 000000000000..27a4e261430d --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg new file mode 100644 index 000000000000..6ab437376ac9 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg new file mode 100644 index 000000000000..a07fd9d3343c --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg new file mode 100644 index 000000000000..ebd1150930fc --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg new file mode 100644 index 000000000000..a82731fd0f6f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg new file mode 100644 index 000000000000..efbc7e7d2bc1 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg new file mode 100644 index 000000000000..fd18ad222138 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg new file mode 100644 index 000000000000..71d9a7283602 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg new file mode 100644 index 000000000000..691de321114d --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg new file mode 100644 index 000000000000..2eede0c86d82 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg new file mode 100644 index 000000000000..1a9f05da238e --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg new file mode 100644 index 000000000000..3c67bb2432c3 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg new file mode 100644 index 000000000000..5a018ca116c5 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg new file mode 100644 index 000000000000..9df9996b2519 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg new file mode 100644 index 000000000000..e5b1f3601112 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg new file mode 100644 index 000000000000..73061f624a4d --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg new file mode 100644 index 000000000000..6c55271db543 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg new file mode 100644 index 000000000000..078b7f3ca596 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg new file mode 100644 index 000000000000..7c2201d756a9 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg new file mode 100644 index 000000000000..78b3fc219c7f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg new file mode 100644 index 000000000000..ec5fb508fb54 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg new file mode 100644 index 000000000000..ebaef38672e7 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg new file mode 100644 index 000000000000..a2ecd8951fc5 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg new file mode 100644 index 000000000000..2886bd063bf0 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg new file mode 100644 index 000000000000..a159993eb801 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg new file mode 100644 index 000000000000..44ef561b9d82 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg new file mode 100644 index 000000000000..9fbe6cc2d396 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg new file mode 100644 index 000000000000..ef918b151f48 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg new file mode 100644 index 000000000000..74f82edf6f51 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg new file mode 100644 index 000000000000..e0bf2621cec7 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg new file mode 100644 index 000000000000..22335b2d6445 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg new file mode 100644 index 000000000000..b228eb881dc4 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg new file mode 100644 index 000000000000..95588eee0ad9 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg new file mode 100644 index 000000000000..84f0a83a41d6 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg new file mode 100644 index 000000000000..0f5f6bd37818 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg new file mode 100644 index 000000000000..88ec01584b52 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg new file mode 100644 index 000000000000..9c83f7776d96 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg new file mode 100644 index 000000000000..cb9c6419ab41 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg new file mode 100644 index 000000000000..82f881f1ef58 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg new file mode 100644 index 000000000000..90952097ed49 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg new file mode 100644 index 000000000000..42306cc6f258 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg new file mode 100644 index 000000000000..ca839565481c --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg new file mode 100644 index 000000000000..4a172fc9cfd8 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg new file mode 100644 index 000000000000..b249a46bdc68 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg new file mode 100644 index 000000000000..cc9a12fba995 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg new file mode 100644 index 000000000000..710faa0ac489 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg new file mode 100644 index 000000000000..1ae3cb6236ac --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg new file mode 100644 index 000000000000..1861c6fda86f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg new file mode 100644 index 000000000000..24dfbe3c552c --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg new file mode 100644 index 000000000000..1e7b7bc1d08f --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg new file mode 100644 index 000000000000..cd1c24272388 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg new file mode 100644 index 000000000000..7ea9317db840 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg new file mode 100644 index 000000000000..3e9f9a865c4d --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg new file mode 100644 index 000000000000..bce4703b7311 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg new file mode 100644 index 000000000000..8c511ae16ada --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg new file mode 100644 index 000000000000..fb4b829cb20b --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg new file mode 100644 index 000000000000..1ac1ff7989f5 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg new file mode 100644 index 000000000000..6de712e80d55 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg new file mode 100644 index 000000000000..c364b6bc78ac --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg new file mode 100644 index 000000000000..1d28fca2dcb1 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg new file mode 100644 index 000000000000..95e5854c3e08 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg new file mode 100644 index 000000000000..d2388f83ab79 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg new file mode 100644 index 000000000000..8be72004993c --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg new file mode 100644 index 000000000000..622c53da79f6 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg new file mode 100644 index 000000000000..f30bfa642c27 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg new file mode 100644 index 000000000000..94cdab1a79a0 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg new file mode 100644 index 000000000000..559e5b863820 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg new file mode 100644 index 000000000000..5bbdbd28280e --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..73706c82f1efa0aa4a5d9ef5013f84db1fd05cd0 GIT binary patch literal 1268 zcmV#`d(gKZuGAh^z?EfGMZWWDpfU|ux;D6 zDv>>V_H6ceJYS`zrhc80l9IZ9{rZEdV%#c$^ZWhh0A?j8CtGp^&;sy=Is>?U`}POY z($WO%KM_d0S+C9j;;rUhuU7%ZlX7fR?SOdVbSHxVHy$Vj6z^HPckiC!MAzr@o#6^_ z@7}%Z0sNi(ni$In;eAtcPXW>Y%z@{J^6nq#?{N&cW5qvMt~GhL(Igio&3V-;N3%cZ_cG=pnVMAZ(kM=ZKwQAMVt^rrCUY!{V zg)|&8`?p+xnc*&C9DAQEbOlKMtrG7^h!v19HL5J&%9SghBtB6Ju=6>H@xK!|g(OOHd>e1h#72a# zXe6@Ev{)3XLV!qh(%h5yC6EWYmd29pRRzdci(}c-@Fy7L(PUc{0xpVWPjX*sK-`_I zfLi(zYUoYZ7gQA>V<&}M_Uw5nH9$>dChXd^E0L2M3H5U*c4iAViv<0cm&_vhZOxiB zhgJb#B6hyEk1s{Sy{{;ed0cnlyk35O{!QJxcRx7nAS`2tvtn!w1Nls40oSfw`;fiO z$Z_4eb*bDxF78GRP_ft%TuWL?Dj=)JC zo9*N}*MQ_pCxD_g(hNf05FWzrp{I|6*+g%{2!E-n@Y1=M`|iF?C2-izFUwB%WC6yqA+a`f8#uX7JFnEPKz z57hC+mb4#MlyjYU@Ng8848z$Z^H~u-z3njnz>8s7EhrFggnoFEd`>YwePrOxBOK=- zv)qgF-zY9{&_>?Jh}qD;j-|(Y(|G?MYz1Ub5O) \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg new file mode 100644 index 000000000000..4d5c03f44e62 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg new file mode 100644 index 000000000000..85492e752622 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg new file mode 100644 index 000000000000..06ef74dbea90 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg new file mode 100644 index 000000000000..a719dfda7cac --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg new file mode 100644 index 000000000000..729c1332ae7e --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg new file mode 100644 index 000000000000..0223061416e7 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png new file mode 100644 index 0000000000000000000000000000000000000000..d869911213051d7fe9fc78c4b7aed508c96bf0a4 GIT binary patch literal 18151 zcmV);K!(4GP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+O3>vk{mgbrT^m;bp-6oaR3D%GB@bs_xE5y=2ksZ zEi%buGBU#HZU(5nMO9(${MY}v?qC1z@4No+AjJ zi{$(9`+oSj5I4^EMIF8U`BK-<8`-Zb?tlEwzc1_iL;vso@{PtS?ZOA87*7hxzyId% z3X*<@H2E{}-;f%w^J(yPNzuJ;#h*80LH=@kzy9?8&kOXIMgH}b`}^wu{_1awALq~a z)8E#z{;UyS{M#Rd^0)7&-yakI{K4t>6~({)AcVO8aXUZ1@7?|0^WELdl@+Z&5%m^3 z{CXQ+xLES^{#xZ%<9Fff_I?e1bw9na<=dNI{IW1YWLK^WIqWdQ4d?x7!MMa6Ph?MG zjK)Ukd!0QR(by$+QNO~CjUC&mvzHc+V=Hrtzpo{{&mHgcEOb732VNQjZ^rKa&%fON z?T7!HU+!LeOYHmawc@&>B8$t=&gs9riVX?(XWz)qY*x;N_-VNlL$jokODVOq(p?#4 z)>LyXwboVzaaCm^u&+FS2^^f}^4U|<<_w9&^Hb4EA$pvikpUO)NH ziYu+W%BriazQ&qH_*k}L)tYr1Hh0`<0~5RMw)-A?p5P8haq=mro_6{fXI^6MrkiiM z^|ssZxbyd}{p{*Le*G_YE&S|Sd^@GrwcoqOcU^10-XaK2iuQ~hi#f34O*=q9N9~#K zA?K)_)1LVeNs1D=$fCV*J7~w)!hAw3H~ikaKX&dv+BaAFf3$D$|Fv^YTlfEC=Nw!2 z&wcwhySBx1_IB*cLanJ!WFJ32eY)7ENNxW6KS%cQ5z>eah%EKgQCQ5)$7FtzV`T?G z>+9^WiO1jRV;b|^mFH!*SeNQ!8R_g4>-A^EJbeW&FL&5dDOO5iE$XpzEmc=mIqR?* z@f^FUZC1x`7AUPju!L$x+~!s5Pk=4%bho@`YsPCTD_QH#E}p)Z89_S-h>zlpXG0kvnyJ%3SR(AGtS-KuCS6EwIHSm@@M)qad zTBGN(ZLB_SB8g@TXFw4v$IYb`l6H?`v)En*bZ;s1CKGa4{qDM83WArN)F$6}{2t@p zaR$M+*J4u%xyg@QIz;BZAWE3M1S4*DBVb!HaG!T+E#JkB@e!p>R{DCbF|mJnov{+X z`8&rgc4Tp9XEiXqZ9*ObDWxs0qwZeHE_WN@y~CK7_0~nqwpw0eaPNT};iv8dF0rN* z_A$$MlB+oxiFjb7R4pz7^qgdUp2b?Q6ldGo#;-nYq}*FHD{ip-tn^F`E*@~?nYLI{ zvLn=y2%&u*H@?LMzPWZ1oBNn|G*Tk>sZDa{67{8zwoa(KkW1+h8w6Rq#Feq0(ELfg z6MaWez}nR{Sv$V002Q~o8O-; zCaJ(%kThehbk`;hw|08hnFw@3^3K%xgEt&!R~xm1ZDs96a(c4&`hFbvqYnYV$Br4j z-MO!Vq~LOWAU|7)FF(gD>?_O=!T|FoR{)=FX^hNHyMh2UL@r+!{~!HXwnyW$Y=Qe6 zEryf*4Q`Kk_x%!`K#2of&!^4`N+XU8B;>Y6iDQ>BJDjjrVwt(+dT!~<1f(T9Tj5NC z@9aVxo!o=*s++m-dwV<^t;OZD@!p_-7Gm2+P#I%obLs|pZ}i<6*wX5)0qoD2yjiKo zeVa^zO)d(UB7h=UZiK>F#Seb4N{@MjwYUJH^cH6z1(8ewud#EpMXEMZbjK5jec-4S zyDTe-9?D|P0sI7TYyt~B@-WK=qFlZ=@MB;+u|<_+1DtDE#Q?!Bx*>K2`Zo4mp(yMM z^su1`au%HRWr5m`dmt7Ao2QTj7Wp8nh*1u|iubiygzULbq{F%~pzq3@S# zqvydvdiSa%G9zBI;qhCO`-< zCmF+%Bi*KvxvUIZ1KQ^XRlvug)&w#^M*v|3IPL+4_h#w?@DT(c^*yXBDbzFlybkIW+cNpyRauW1I)0U<3zTH z0Io1{KHwusd(Po=rS?c1!XJ)@s|AgLl#(cdR0moHugL!rNQj=(ebk);#A2vj!-V@+ zf-*pfdWXc#OY;K-?29-d``E~jT1QHYOdtOG6+G`8PET0B*Z>!Ipxc1xgcMd|VW9P# zfEi+Fv0`>f*21Opq6Kv1StGPkGg(cNfg7wCJdqtRNzy{c1HI%|FQ#w>XFM^|8u@}S z_XjnHJW8>!0865n1R)yNlFi94uCuRYyR^8o%4ZwsBmr)Q` zddM-`!2*!uvyhD?qVXr61M88c@uEB|B@i43f@H-O;@4nkP;`o1*x`9u+X=(4xq#7{ z(9{hRF#;2KKc{bKoYtl!At;!XJ@AUlUdE&I9!M)mkt=0II9t5pj3hQ!mIl(f!RW;9 zf>&U=hI7~h2Em)+Afs`YD4?|4T!bQl40C!Qn+wO*Om55*b2&Ki* z9{1tawxtQlp|rwTBp{c>io-GB_)26TvINs*BK87Q93nSBe~r&VCpC7McrhnweTjL{ zssh8xCKOj{B#lV~6NzDTpd@3Pz(=I!47)8bv`Y7jx$xn`iK`;1$Nn!Y8P~&h0a{A$?K-$Ul`9CUj6z2PNPl1&d3Aoq2PRvBUT5!G*Kbk3W#VvIM9z{0Sk5!sagO6|4%I0oYcGvR_pqax-jflaXue z*@QLb0u2MvvZP<|hJ1zMmBD;c?glx}kmo`edr$&g2YY@SJoi_pM=T?*Bp=QQa^8m0 zLc5|c0CErn%+h6(<-k7LYIEe%z%Xw}k*?8dGUmA5v*NK&-IZoqDb{|kyubyR#%0Wt_RVv9J;d}jyDl6IAy zx#m>N1ghlz%{TG0fP;I%Q8U=2oMolYtE+CmSNWDQpYvKM1mjo zk5IQy`Jx?~FR&DtL7V zY|t?R_>smXL0~(DHCRL10Ul_1xleLtyC7ZM189%_PVhzD_#rNOR3ZbsJD@J0g!W|* z^--i07{@MPrb!=IvJ)?O+KTQ3oInuL6+Er*5FwlJCX%2lWrW$l%p*Uvy@B9Ww0V?O z?%0tB;I4`qqG}y-t52B&;@G-~g!PIpShas&h!#-~ac?#R@l2?~P2 zjyTLDx(~0&_+^5Z&9UBxlo_{y7zj`Y^7No1$j*g2z<@g>FpCkPlt^v_q;0haiK`o_ z9JSB2NzccMbY=lpMsa~nsP_iVX3tWIX^G*ph$_@Zm%c;=Pq|bqU)tOX{JJmsF+?38 zJh;P^pq-)@g<%LmL+mtdB{uX}?&+3BvJjll)>g6QU5~FfoZ!TDCY;Z*Jw;@PW|=t`O*% z=r2M>0J(8xF%!S+nJhrQto8<2kS5##jv2idr!(XX?g$N>U<(l+a*P1H@)m$PvJH_3 z$%0Xdoz`bG3`QPaDw+=|uQ22S)QxURz;aVjL;|lhL))G$>hhKm0Ww_ZK;&{!+2~mf zxmnN(m!TYT-2a?|D>)=oCzRkM6_0&42raO`2)`M?dEzTf1U486bdEyu^zh0|(--eb z$sWeeo}hxrWq=B@T=gO72K9ds+guGu<|TzdM8kUF7eU#R5FiD5ILmER^qSDxk%l5r zkl)5$k=9%Tq5%ZuA1KH7R0t<1W%UeEs5C=TL92V6p@Jqi&4*6j4)4$R71dJw;}0lf zgMp$#+-Q+h_QHkVaW5v(q}_*u@Dmc5g(qxk3bHT@;HfOu+i`#aBapA$1CUSHv$g_Y zcDjG;1J#)Od+D+GjKj?;#c$Oi9tj5(sQ_LU_zO(Kaz9}%V{rpOXGBEtUqY?JH^z}F=gx$KslsvBT=XxLmdIqH|(XHj8xJd;+2 zYeN&k2BB|R!$7RgIqWE8aCZXAfjRr ze{6)i5$D*kD?un4bwk32#YP|{dBYSTGIRyBUC0%}gLpFZD(qJ>F#{`LbR9_A*m8tI z0}sa_;gOe;+wenrwI<9IFY@Sfm28_T$bdAvgD&b^^$qB8H}+HXco9GcMY~jFjw*Xh zT@wTbJhO6*RF`IDJ8-r*qZ(g}I3d0x?!zrUZi>v+G^>%#O=^V_Hi(7*!Wn`Cqa=y; zX%HkO1lsGZPm))p75dbj322ivK8Yh#wIO5xfh-V`LhtH4?5naHaS(7~AQWOWsvB)& z7RD3Ibn#KyK+Ts~xp@}Z_ebkm>k_o9TX|%1;NsdY?1b-xrC`yETE@3-S|G2xj(bw8mb`T4L$! zqH54HhAseR%&Y7X4(JOoozHy{+j1&gQE!rIQqy1y!XP7(&2&R2BiWFYSX%W8xM4CH zO-Ax9EH~gCxaNzR?yQ4*#!1ztAs5;Ju2<+&M*}dqyKKS-HvTGO+^$#2h9u~+U-zio z4mlIqfPLUIAM%yj^V%Z!U@rFh#?HE<^^x&GZujSIbQvLAMu0fkK$?<`6sT(fkco zarayi(Rb9PNh?(wXCy=E_ zNE5o`whDCM#}Yl3oq7fY@!c|M5}`)e^7;G-PVW1a581(v4iQ`T&|r@E-4;~U;iK|O z9-c%ia!3InMXE~Z+Ej3H;Uq7nmK4EV?NLMGClDL)xG=~{q^TYhe2w(3XgL(AYGvEN zFmsAPuvhJ)ictYTwtGrYPHzNkzOen2<}?efjY_RtHyve;Eu79CLn-A zF$(6;pK5&Unt-deU`Y7T(w7f5`K;fGaP9)yE1#!Q8sxsEC?;&~wQGt9_+9fnk!V3U z-fIX07TG|00$&wl?hCz${wEeeryJNSyCI~C7Q>?@hhGdtH202}I6;3IVSa!kR2mtM z*~H~Tlm?{lqB6mWs``Q~keDEj-D%C)Kn-@Vh9Au&i``V31p>}3q)P@ZkgyQQK|WU% z3%oWOMJg|~$S%0tqiUtGd7Ux`l|~E|xDt_V*s_jjAV`vjES@y$>z8x$@;sGrtX#X5 z<}_gS{PTC!}6;#iJMt_`F2)OHB&iw?e)En2^6>bwQ*-j>sLA zA3nhy{H{+jD0%{cdT*nJLvika3Rk-8kxUI?hAudq^2xso=a-m0Vg~WPD%jE(7 z$3BrZkORl79ZpovCFcgbsIojkbI?BvI4430p@PzB>cnEZp4S74)nHLsVM(%G-EApX zt5KeMd6wf5I3l@sHaB2ND;7KEF{7%3U67f)yKP>S2~oQNQiWjO$5(($q+0^&`=HlN zN|;<6KneR?)yu)MacfhJSZ_|V4tb{~kFIim@hZ+k2Lz*aFA`1%|5Vi_$F3%bD^Jln zixgDTK*sYj=;*cC?{~up5k7K3W9ql~fiWvb-Bq>6SF1AW6|Lz5Ab}n2f1{0mJ-?yDSXLxf&OC8Oi>dsWkH>~ zg{M>+-spdX0F3v8d(Nwpq++HjFI)wQyfJiqCzB$?BpMBw2i;CM6OzJuwX0-8?T~Jl z2-h3}l>PJ=?iXFt&T9iEWSlfF!Ur}DZGc%w|1H!c1G^lvn(hmSoW3Cc8Z7KRGO|hy zs>Q?^Q6I;O$`FGbpe5J~%v_a-Xb4g{zYb;K!RsUg|0a zRohb>SO`{{Ynuy}sN}s|>0w!4WsJoDzF09N3mR>L8_jx&Zw3|1e>C)h6uu}nkDS4K z!>6jR_|;|Eun?F;y!lKdTTX<3A|=a_0_s;wCu*4GA4p`?sa zjpNgm*tjh%0h3kvL!7t@PecgDbwch33rmPNjPKBngdm$+S(k=}i5ESBa9BprK~P8{ ziD$!g8JLX5fh`7W{8k%&03rY0A}Yi;+otCHR4!M&hjm;v2o@swqgGMXWM;1D4b#wZ zC{AT~j46L}gU}l*+6Y}~Beg-uOz7?{HPDM36Qhs|#yY7zR@Hzet8;Z2&(hmgS@3XI znmw(J_0sT9ja|;6LxsG9*9SC`l2?)PgecnMa5=i$?kq0y?+*2z*msS2-A6G9Pn6Wl zJyJAEy+T(|#eh7?>o=|BA!*fgY&m3E-%ApHN78(%(QM?YrbI8>_EnlzY2sjZRQ;{2 zBBHT7agdDaPX}a;8e4&FoGQ3OyP3Pji8ZaKI-hX&LY2eIyA!V}-gSFFQK6=T{Ge$$ zu7DrxWiQYEW31ZuWmdTsClFO#7KW2+Q4RjQHO>U49CXT6$)L337eY(9iXq!Zcxjt2 z)Ra`;n~}5^GK2kF-3JsZ&IbhLQn(6{t_E`7^q9N&zg^`cSn(-+eY;94WISm^cq7hP zpr-!g$l%bcFintWzbd#~4&jj8CPEh86FkP|NLwM6$Uo>!C?ZYL(LbiP$5sQszUDa# z+G@&zI<)DlLrU&!(oSVCpeG~P>kqbTVpz%pYl76*P}GAdWD!;`tEzj?im#K?+<;{Y zo{M|nVgez@o7n5)OswD31O<*^XbIAz36!~4hKDCAnx+Rdq@(t7E>~U7f^vhm?72At zIs2trm%1h_x|%e^r$84$1d5=wNVhG3M{_%*=}_vhlgf7VfFyp=;4)y!eqe=FipRVY zk^5OkEU!wpWLAXb5#CZG2h3rSQ{UVl8KokzCTkW!pwTSM=aH`9=U4NdZ`@7;C9D8Z zYgGf_1g$Hm8tK)PkS)C3+9+xijRrt+OKLfT3M@_`g@)FKO~>tfBhdZbcm#H^L}ysU ztwB2Sphw7Lt3t8Wg%DD&u(~1#-XYFHzY9?q+x*($iIhS-qn(-qjc{_N;wrI(ept_S zcidDVaIkLH($z3YY3Og%gNCsligj{eG^mCf+JX`F)jW*CqQiLOOrS5kIxT@KQOV`i zmVuI^0t36kn)>)!>9DB$`(gXprkgY=3$pi)X790_laG37FPA*B{FCpS4c(Y&ME`-n zzd7)v`slij{n1oPEKx;o<+I{O@3EzGyhaqG@V2QAi-((h4p(FiWYR!p9oWjs6#>uUT;+HIs?^ z&>Yl!E2i$0n4-q_Iv>ao4J0h$rMW%?P<*dp@lYIEf`o(A(1GDh1K@k#t3BW!(GC}8 zE5a^l%Me;@Qj*O=rvnXhA^0~8jV4*F_O9xu0y!9H73_&lfMA_ShC&W^*q$5 zyeJn$S3qQkuXSP|>hE$k!CyDL zPw)nnM-iiJxEh*KLkU-La}ib-7AN8i>YqjZ`eYjSe+bZ|booG}Zdggqj=M%5Rn6dJ z9h|6y>QsJc#%HSO{0s2ZrV==4?5ozSo($KQ)MP@OgjYXO+lyo$UL!cK+V@72+hOlo zQ$--Dad}9+E0EdhDOGZ2Y17Xe_{u00M{@LV)%1oPWuR5h+R=kF*7nsr+tmp1^-;ra zJ_pV0FEj<7Vqp4-I^4!|cz?|ej#$rH>k6M=&<79x%t5mGm0i=oU>E6|tozK2azdWMkK|%6iCqc#c=VS}H%X zzQEl<2x|S2d~6y<4EJL~Z}9?_2BrwP%jrA^i5A((_t$1M$?U8_7mc=&Zm$xC6i_#= zqeQA&r1NC^+^BiHfEOD!i}=Ma_q<{zLS^&?@ZR2DX+HVc`9y;Qck9&nt>~ z9Y;$_R1Cs0ji2s>aYxpmxnS!sfZ~k8R7F46<}`TJ`fG1t__r>P%vaM3;R(Q<2c(@m z02ak9Z=pQ;pF=NrO zv#Il^IQ%S>MfjLT@>pANTyuc~m8*d>%zA|@Gv;)B6nchO2EzlKyHO1h%W6Uh8aeJS z_HbaN8+u@A=zo>0jey1Tdkbzyr92s{s{<`1f=4qU;Ll}=*)PBpJ%ACj`AI2=?9Tj0 zF&uTw>LwrR)u|BlV9;@1($XyzWDYo@G0H-WWsu=bS>7Uvs5$|3jWXS;f+fPuG(xvE zDSI`xt`X5v+?Z+?V16{U3kInQ0KuHp|K8TqKtEzcd8k1j#Z1jPXX^5ROaa@^^~pkbImim$G;YC@fT}w4o!)hiHuW-fGDf{jnd4}hOH3LC ziGiIN(zDPG=-YJIfPhtg>hckitGp>$Ip**{15-oDSB=E5cbGo5N=GqYsYu;8~!X zNoU=y`l#30HSVjvxl}6AJTY|WUC61=q(c?2!^&PEQsWz=0MV9? znQLZ8*9#T5g*MS_yXHG~+p5uBouJe3W8q#Lk*;SUSnxVosA@iMpyo0KHZ8m$Y| z8te<_g*DYIv8qVlS*@RvYc|t~g4Jb}1Hps((b-FJ zNdP~?(d2w|QXt$Y8F0vMKx8MvXA$kft$+hlWz+Ys=`8i8sRJ|+mP|zpNTssw*)=v> z-G-pezMA*mIxVXlV@uRK%$+UQ!wv9vUPn(CI|k&-kLcCrvdhrMfi#V8h*po2}r zQCnT(Eg4E5@7&K5Cj-R5CaEpd^^}$%t=+5iQPL@hs`4A~_v{wtfDauy{YVU|JbstZ zaO-5FPz$F#de-puI~a``sMVt({ei1umAVn_>U`S+5d2MMEx30bR>8+r^^Z&t$dy!$ z;2{w~1J$v;PC?ItxoU=v(*R3*)eoIm#WAT>iiQR2mgMcwa4y#nG$|4HMcVI6@}f^& z$|P-gXLuy%o{01sv&5fN70J*(cWMNHM20yvlMFu;_DH1|WIiz7HN!r&@-SV6t+_Fq z@5m7HLDh7fLDE>+(9~ABI>Nx6ls>j*Z}vAE{VJj^sGqZkPJxqj8s){Tx@gGOdq12d<=g}OD0h5F*gHHyxr>wp5L0;B0>Ct{_-IDB%F4<5YST@TpYB zbtKoCPT2m4E1klv_S-tH@2KX+;3hDPKgsQPWK3tAd3UH{K$-<>=2XPcY21t{I6An% zuSF=0t&)`Hpc;|1)*G79(Z8cZs)x0VcsU~pHO2A#8nDc_kxB1Jlj*@awM#{rMqJQf zT?KG_rk=}z4E;G5r3w2jLD1g0C^z*il=KciAulwIsY-}*j?p|&J)B$uSo z>?e(6*k09=jAa>BHNPY+wj5?lYA!y2Ly!0bA%NAGWZ#ncurt1890gi>e^|8Y`_1n?pkD0OHHF zKw5SfI^za%mm_$Tlz<_P2u4I<(YgFFN|jqlIzfKriFbAyxXwCD8r2L&7a+WSN4)1G zvjZ}UF3&q&0zzp(E|X8iPSCX6%3TK}8>$x7F@;S!>$J1fdKSwk9p=*P$MjnRooF?Q zGrtrM>Koat)%aixEb?|c7P#uX1}a?~AIktvt4x>X*7E7^q(L)rrm9XlKSQc$pM9ws zj*vfS%N-2})BtTo<$#_jg6Oz9M4NOV(EP4%+SN zgd!B)>;b^ROR8US>oFsyAx+J~<#8@@R{E*D$1xxouFj3r?P1G}h%h}7Lp_SDr#|Sh z9$Jl=vx@K?D}?dXGk-v8kWCXW!cUSFoa$Mo7hQ85@5Ys?_@)PH?6Y)WoA@pXcz7Kd z(~P#vh)!o|Xzx9?1k}}YTVx5|)jQ3>L{?7IrB#Nla1pBT!$o-J2F)%)Kov;S!Q-Oi zOswS4;b@`cdoBwBse>Gv18%fAxSjI0?G^>smX6xRNck(9ju!$q)NNUub}}4 zNHe+Pb&LxfCygGF>3pvai6cI?=H8|%;X2ltblO|T)kx1;_iGSfHxUp8(ds%H8E@jx zn+y}t+beD3Af-d`3md%*{32%CTW^hg^7iT*C!H!S87tnL4r`d#yoK5%MtDW_1<#ed zL5u_?s%GR_!}ll`%ytA)z5`^Zlh8zdQLbqWc|*IbPRs{{x!gyKSvQnTGxO)j^5|Mm z(&MUFWIaCx6fixNu6q#2b!@$!(!mXNY?%(C2F>QJszcP+;rx^_Oo9f$6xDQ8j2bri zk&fl0uRQE#{O8lNU|4dWL?bo8=BQ(FQKEBrJxdJd4R>O~;TjK<%jyp-MB-!ku=%m; zPC9+5M&BVu#rRbvQS8pt2^lkz8|1=y$@&mqKE9_mIL#&WsIE86K&T*rv6)9lQc?D5 z)2pk9*3x6P8UjdD2t75O7(@1||EcH2m}{?3xI=q~)LRKUjf+Yfh|EGXjisXldQb&x zjB48|CgA%D2o`LjdAa|Yj)PkW-y$VH^jMK^5EUVb#3D{=-pgay)c;fSpLe?IoM{6z z9H~b2#KR5TQPF{0J*0?a(byi|L&v1vNwM&xfS%?>0F3weEhA{4x1?tbsbH@$BygMT z*Z8O=YIoEmZqQm3i58v3C{5D!ydJ;TNQ%xJRz1=T_hw2FfCA;wqho)sTr4=NLH`7} zVg=Cwa0*U>kUx4r(tFm)cgAYsHj3}MGd)HLK7?mBi`_L0Ds0L`iTc=TETI$LnL~sy z5IpWX-KJ;N47Dw~PBl)|@^pY>>hX2Jh&=GCed)5BnggIMgpTqACbypSGVCa7bg)5w zMN)05JvxJ;cI(KP>v{;@2#@7;@DZYdm=N>vouSs823}8U5wDK4Q9Bb0QMo%zRw$|_ zCm)AX)A)@g1XLDcU8f>~4r=|J5?6V?>DggPbNd?l3wlfsB57k?(Ai$c3iEVWxh`|h zEsobp9azSqY2ok+l_%@zHC`hzS5H;&RSHB$*2x&sa#XcpQgIdLBFb-OpY((ZBX|g( z1#N2FRYz%-jvncmU8bFsFuz73l>6;9;;b%Gy&{?wRW9=xk<+a)Z7G6KvrAa<$J=w)U^1} z1B-}SmQhFc@^aqiH*WFjkEl!KI3kISLu*f+*==g_K^fs?Bk`s-#?UkX4quNzM3|8M z?=e%*%TLwJt2Cy=3h#MY_^r2~liP}V9zj)gacPuYy<8Yv<0v@Pd>x87VjeWG35rO} zya{(rAZg~Vj(2Glp9+{zAU{7g?29;)vK9i3QC6+oR%L9ci{i|#x%q6bpJ-P{a(G0AGeNas*> zc9xu1f2m~^iEmTkPS0c8BL^LUf6pG$V^Wc3gu|W#mKBxv6{q7LHQwLDUVr(9PY6uY zXkOzHN>(nbtTRi}cGgpsx*pMo5f%ZP zPE?8D42h_r8ysSAI!%L>A4Ly+cpOrCKz0brK_V@ALp7QQqH(fb=+^a=mN9RCj~9^~ zOIg{EPDq;kLlq)tPSrrTLDe9I4za6yu4W+jCc`o{9K+sr0H^6OOPU0L`_;qHm<0jB zEoc;<9b2+nC|&erP*)Mc<8s$)2~0gt^KOk%qK46{a=K?YJrxDe383FX%>X}|x|*Wi z+@O!Eqc-DBQRrB%S|`W_7E(uB5AwJTkme$58p1*4O*tbSt>KPG((^yrH9I2Ru9@hG z`0c4j4Z`K!bfgw=0N1==+z_Mh@gV(8fCl9vZZXL%;#Q^}PN&9te5oKNJzFPBx_F;` z{~A~Uq2?Vw)5oCFbOctzBH=w$sOjvNo)TN$GXmgNe59}6LzGPIs>A*uq9Zvf%$ENG z3$wuwY!fE-1%w_G!HTHt8m_v60FU=q=fmC_L)JHVO#|X83Y-Jfwx{{f?<6c&E)(Dh z(No^@GzmRfXLdvFQ*}V=(rF{?tBE!Z2tW#Av-DI&9mOCg%FshSq(VFIsI!@xpO%AN zviN$mXVaU4{lq@pqEf;!QV>ZRtmx-w8XFU*4 zMa!Z20&do8EJTOkn}SzoO@f|ChfW!KkZvsi1>&r~r$XqlpYRi~sDe)iQ*;I)Wk?=i zU^SM5fizE~r$8nRrY=4CRTW5$IJ}c9RRHVdi-@kw2qw~0TUg+I_1F>sm85ZOeNxCCc7#IUg1YSLWp5RW|lE0NlAE)uY36TdKcwc-sk=tAvI?) zz$X&VGQ+fqH;AV`&;VI;7KB}fpVpo$X8uo0zIC&faF z_TwJ@p{8FVmqM-*7&#VDfd;wh2mgcL-CFtBq?;6s1Klr<^Dznpc7aCCalVfor*Q)K zpMfjA?XT2J=5y%2bI}!wUbWco&W#?08mU+MF0Q*00030 zdQab3Gv8S=>S93NSTo;PGv8P<;8-*0T{+ERM&DR8-&r%@Su@~SG~ik^;94}}TsPrg zJl|L|-&ix>STo;QGv8S=;aWA|S~TNZG~Zb>-&r%?Sv22TGvHY>-&r)^Sv2EbHsxA2 z+*vf=Sv22SGv8S>-&ix?Sv22SGv8P<-dZ%`TsPoaGfqxUP*6}zOiWEpO-@cuPft%w zOiW8lOW;~H-dHpL|NsBf3TM4X)z{c9PmSJLGyeYm|NQ&?`S{{(O#Jfj-(Nf4TQ=C) z+T(Ch;A24HX-Mv@n&*ga=6_@R?C9TIIr!e!_S4DZa#Q-{-}u|p@U)}hXGZCfdFYLF z{rC0#_4E4Y;`!p-_0GiWorv=D^Y_`%^ToLG!L;RkU-|j^_SMYsx2Nisf98W{<8)U4 z{`~y!>*(p~;Nju*%fIx;yX~fu>6Coug=*w^T=w?&^1ZL%WkcU#KK;%M@w=?;qmSTU zFzoH^`s(K7<>uYo+}hjR;MmvV($DUxm+F{;jh#XJ{rv9m^wHSnzah< zif?tpTTH1)V!21-X)WY$E9iYD?vx(#qZ;(97yi);yT;nV<+NgZs#$cUQEj2`uboF_ zoNKy9sf9eoY&Z9|6a2~z_51Yc?epR0@7&_-%G2YmyVK3;!+@2#73|MtstinO!dqo~@JG*ywI z*N*?{hke3$h0APv#bjo*V6}BQ)L}K{b1LkPA^E%#__`A1^xwnH-~ag5=GW8M?$Gbl z&Em_(ik-m!@T#oan&haMcdSJD!!Pll8(A!95C8xG0d!JMQvg8b*k%9# z00Cl4M??UK1szBL000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jv414Kxkt8+M`q z01aD7L_t(|+SOcFR20b?o^$kg;2a(Sc~Id6!_lXGxaZ73GkIWU$QcGuK#-tB$zlQp zQGy9!O?xGobJlCv^_th!HLYpW-EcSW%{fe0bywHSRP|I3=sov;@Gw2y)!$Tof2_Y$ zsm3K?q4Q?=hXknpC*tonN$oD$psAs6>iq$;wQ3oeH2t+B@SCD$kU;;}hhRDr0w|MT z3r|7_B(U0&3rjL%<7#7U4W2k=Pc(!Xt~{{DwRcsd=rx#RC+6F$Yb~zRF`?^#kK7QO zmZ;NE#E{e$hXVF7$Ih&7ok4w9LQhF;LTUe-XQXB40rF%;Xx%QJk%ATDb%ngxg5$Y7|<)k&iI7^=i6 zn>8+_Fn0-D&{f7U8%$f9Nq~`3B3zm>j-|+qhlA-0V$@2++$=n($xru{pMsG#7YGoV zjB2Hluv36xiWRO*Rfa(@4y7pq8%x!`i1{#FNnM)23_l+z*=_)1lrK{ID#=OkSEL#h z(-S^m*$4-yv#Q4-8IYmbB?^6-FqgUT=?wMw#0YJSUKl4x$y!+9vx%ZkXzP>L#~9On zm=#MJBu1VBR{}X{gOqGa0H5l&M=#b%aYL+G8H`=o;88pL6wIodHmF@yQWWv$Rr4jc zpigSHDM3*Rhf9N>=CIi)E0_npi&n(_W+Cn+_4$QLh>?Q-s8AMLZ3c0JAr>2@+Tj^B z6eY8xsD~75ho2Y}!vgfefP0FK#MnjOmB4Pezz-|i%NH+Rwru{= zh3+sC*{NX#p@yN*o9TpvXa~c)@ZpPSARHIHWcjkCIEwOGcFzjf84r~_Kt7I2Hn{4A zi^>~IHeXt|dI_c|CU)nV42)-mJT2hbfmv&k8B1Hb2v?L=b}fkm{;XNfW(7%vNTd=j z#-3_$Cq{W4D~>9_wnF+;guxgFSVhVdr&lFXV*H{SHWWbb9N;I;rJ8FqAP?DRneACJ zsYYcw3y2NzlKq}TGgF6w?TWXCemf_Fg%BV|G0iu24dkvyfPz-!v2Yi2&=Q>b4Ddbg zWb~w%cHMloL|Dhd3*gGC2~z=p)zHk;<|T~TxW>fbOA7fLbHJZ2MYa%diO=@*g#5y? zVks*KO(nxrB#~JG!l^j^y8^;P->^+Y$E^t7W0O96= zsHmueoxnXEY$_ei3=EXxh4qg0&h~f01zH{@>ocr>;h9OgmmFC>d zVsFw=CUZLn-*a|H)PcTz=RP@00?{eZW~t7>FcqzQ4aMx5B!e$_-_%Na;)|7V`~yci znYdBn9fTceDRN_eAmX5!yj5?*3BP=kO+gC0gNWhpOLAEcuo_+bb)pMj2|;w8XVg+d z0~KCSZxIZHS_rUc4B#Y0EkzpravJ%TBA(zy@N=X?t>s^ zgAAU(O03Iiqq((=Z`YkY%THH4gMRRlY&ix3_>Css@RRS4<`}JZ=MiA8DAaP5V*Y_- zNl6hUD0Y7(*MYrh?XAv*6tle}D(bxM4;?7klM@ij=1Bz$v_^U4`&V#_r8n(!zUjeT zB8a*D{fP=V4)YiTzAbn!==A9HN2!x-g zGG!L>?W?)B(Tfg(x9q!20HeO5Yu{B@Xmu!S|+p%;UV5gzh0z8ricmnwjmhYTh)x4(p`hgT{4^p6k!eKLX| zCx3DowFsp^LIRj6tK1owdQjzeUp@Tp>ecst9YK-3|LOOvm$V8X{80=}t)1IAOg)J5 z{&&=u3lK*4kn%8x03rk>U-UF`1?D|S5Z;qV0d5A7`4Dk(px<-Q1t<*@g1hyy#B};m zjvip%_^THP*MDju4SEL!wSt|9p$2!NdQgL_8}if8IQpD2r~|nxJf@*1El&05pn;IX z&^XpZ@4qR>qZ$xV%SY<593EV`$X8SZy`#f&9Y6{E0&f&I(!nK@Y{kjxJ!pm-*NWbs z$HoRvT<`6DIXE)h&ys}M#UK+=wN5Rg9u&iULxS*XNYR#5EJ{a%#fYEZ&nTilv6^PM z-gV%q&BkXw)hL zk&1pc4z8a9ahLspZw9%Lis^t|Alzl(}f>?%B4jTT7@T zrb&GjsA`tz12Z*x2}N&Di^uy%#(LqG+g!idgaS%GseZ^`)X{_FU&(|N|JW;;$iZ#H zL;YH{wq;Lu&%j_WW<;KQI`XmxG3^j)ck88EuOephPwg3W^V@`=s>jXz8L+rYS`U+K zb%V}KFsVbMdu82NZ#O9^2b7qJgQ(>9O%i07xl*=T*FW--?#Bi^e0c%Nzr;#^Ai|d6 z12a*o;EeAZN#VqZXEr1K!_KbMts57^(q{(sAGAwkw(7pmVd9o}07x z)u^rIk|7ACv<-l2NtTgPXs6}ohu!WBKla1X<75yOU{6#_VgxVKkVn@nuu#m^TA3P^ z)e3lY z^)3x9u&9>I)qVao-(FbjxgOzLk48cvtVaXrz`K*+?ln9c5P>bpB5=(rnX3=sdv<^Q zv7jGXb@(&>ryu_zQk0K8Lm9ABp9PCCA@ZGfU?;oWNHSNVBfWxN_3h`*kDq_=cb*1Y zwZ|eQIp*;^Y~X{@G`&q0wsIIj3#X%A##~*&UiNtZW8trNf5a|FZgqbg7$L!4%XN~^ zf_e%X!xF7@bA^MTi93j9*nFKp*9_O**bLw#?$mp<4~XXKL+oYm{E`e}4WZdglLLR* zRF+QVJgELQTHLQ31YC<&n-@ahdJ3DqG_A=Lb9G-K2ul;*u{e|UFhd%tiws3qA1DK1 zg?;QMsP|fyLvQ#R>Z*uUJRHOpuOMPze{Z}nuT0J3P({>>;4!BPjGh+JhwWzofwW^0 z>>JFnDZqe^cI*<46U2H(R~K*){}liF*GFrPdVttaDIAOtG(JS(k*7l8d`6QM^I^bT z{T}DUmZwj4?|$;=(Nm|P4!?$QT!X(v=v^#GP>4Zv>uPI-&_~wpmJHs;K6*|jyi4Uc@rvmsa56cek(aQI)m#e^bQtm+8oeNti8+aUU|?-7Lk&hj!ybze)>4}gH`ud-KVflp^91I2{A0)^FWmjoa7 zapd<`E_kLP!cMm(GgmyunB6Rfic?iSi61gjDd;uxmqQ>p^ zd%b?DamySmGnY;t%1V3}wy8HEM`tmD@~XEpU%rXlP-Kt83Klab?$CX(YjU4g>3Wh{ z)P?vYdx=XucGAS2E}!n+3}>v_RGeRtl$z7(NG!_DuWQR#?_P8ZR86=9OjcBe&<3ks zkND4Jg)mL^I%VE0uK;EStKNY42hjoeg}urD1|w|7>_F^)VVD#Y9HRQamj43l^drmh S+%!G_0000x literal 0 HcmV?d00001 diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg new file mode 100644 index 000000000000..e7fa529fbad5 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg new file mode 100644 index 000000000000..09d92456dfbf --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg new file mode 100644 index 000000000000..616649e71fec --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg new file mode 100644 index 000000000000..86b88037dfa2 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg new file mode 100644 index 000000000000..c82fddf86b52 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg new file mode 100644 index 000000000000..ad24185a26a1 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg @@ -0,0 +1,3 @@ + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg new file mode 100644 index 000000000000..3910c2941080 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg @@ -0,0 +1,4 @@ + + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg new file mode 100644 index 000000000000..df1d25f89b9e --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg @@ -0,0 +1 @@ + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html new file mode 100644 index 000000000000..a9b67364af59 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html @@ -0,0 +1,18 @@ + + + + + + + + Privacy Dashboard + + +

    Links

    + + + diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css new file mode 100644 index 000000000000..b21ec65a2e2a --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css @@ -0,0 +1,148 @@ +.material-design-ripple { + --mdc-ripple-fg-size: 0; + --mdc-ripple-left: 0; + --mdc-ripple-top: 0; + --mdc-ripple-fg-scale: 1; + --mdc-ripple-fg-translate-end: 0; + --mdc-ripple-fg-translate-start: 0; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + will-change: transform, opacity; + overflow: hidden; +} +.material-design-ripple::before, .material-design-ripple::after { + position: absolute; + border-radius: 50%; + opacity: 0; + pointer-events: none; + content: ""; +} +.material-design-ripple::before { + transition: opacity 15ms linear, background-color 15ms linear; + z-index: 1; + /* @alternate */ + z-index: var(--mdc-ripple-z-index, 1); +} +.material-design-ripple::after { + z-index: 0; + /* @alternate */ + z-index: var(--mdc-ripple-z-index, 0); +} +.material-design-ripple.mdc-ripple-upgraded::before { + transform: scale(var(--mdc-ripple-fg-scale, 1)); +} +.material-design-ripple.mdc-ripple-upgraded::after { + top: 0; + /* @noflip */ /*rtl:ignore*/ + left: 0; + transform: scale(0); + transform-origin: center center; +} +.material-design-ripple.mdc-ripple-upgraded--unbounded::after { + top: var(--mdc-ripple-top, 0); + /* @noflip */ /*rtl:ignore*/ + left: var(--mdc-ripple-left, 0); +} +.material-design-ripple.mdc-ripple-upgraded--foreground-activation::after { + animation: mdc-ripple-fg-radius-in 225ms forwards, mdc-ripple-fg-opacity-in 75ms forwards; +} +.material-design-ripple.mdc-ripple-upgraded--foreground-deactivation::after { + animation: mdc-ripple-fg-opacity-out 150ms; + transform: translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1)); +} +.material-design-ripple::before, .material-design-ripple::after { + top: calc(50% - 100%); + /* @noflip */ /*rtl:ignore*/ + left: calc(50% - 100%); + width: 200%; + height: 200%; +} +.material-design-ripple.mdc-ripple-upgraded::after { + width: var(--mdc-ripple-fg-size, 100%); + height: var(--mdc-ripple-fg-size, 100%); +} +.material-design-ripple::before, .material-design-ripple::after { + background-color: #000; + /* @alternate */ + background-color: var(--mdc-ripple-color, #000); +} +.material-design-ripple:hover::before, .material-design-ripple.mdc-ripple-surface--hover::before { + opacity: 0.04; + /* @alternate */ + opacity: var(--mdc-ripple-hover-opacity, 0.04); +} +.material-design-ripple.mdc-ripple-upgraded--background-focused::before, .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { + transition-duration: 75ms; + opacity: 0.12; + /* @alternate */ + opacity: var(--mdc-ripple-focus-opacity, 0.12); +} +.material-design-ripple:not(.mdc-ripple-upgraded)::after { + transition: opacity 150ms linear; +} +.material-design-ripple:not(.mdc-ripple-upgraded):active::after { + transition-duration: 75ms; + opacity: 0.12; + /* @alternate */ + opacity: var(--mdc-ripple-press-opacity, 0.12); +} +.material-design-ripple.mdc-ripple-upgraded { + --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.12); +} + +.body--theme-light .material-design-ripple::before, .body--theme-light .material-design-ripple::after { + background-color: black; + /* @alternate */ + background-color: var(--mdc-ripple-color, black); +} +.body--theme-light .material-design-ripple:hover::before, .body--theme-light .material-design-ripple.mdc-ripple-surface--hover::before { + opacity: 0; + /* @alternate */ + opacity: var(--mdc-ripple-hover-opacity, 0); +} +.body--theme-light .material-design-ripple.mdc-ripple-upgraded--background-focused::before, .body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { + transition-duration: 75ms; + opacity: 0.08; + /* @alternate */ + opacity: var(--mdc-ripple-focus-opacity, 0.08); +} +.body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded)::after { + transition: opacity 150ms linear; +} +.body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded):active::after { + transition-duration: 75ms; + opacity: 0.08; + /* @alternate */ + opacity: var(--mdc-ripple-press-opacity, 0.08); +} +.body--theme-light .material-design-ripple.mdc-ripple-upgraded { + --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.08); +} + +.body--theme-dark .material-design-ripple::before, .body--theme-dark .material-design-ripple::after { + background-color: white; + /* @alternate */ + background-color: var(--mdc-ripple-color, white); +} +.body--theme-dark .material-design-ripple:hover::before, .body--theme-dark .material-design-ripple.mdc-ripple-surface--hover::before { + opacity: 0; + /* @alternate */ + opacity: var(--mdc-ripple-hover-opacity, 0); +} +.body--theme-dark .material-design-ripple.mdc-ripple-upgraded--background-focused::before, .body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { + transition-duration: 75ms; + opacity: 0.3; + /* @alternate */ + opacity: var(--mdc-ripple-focus-opacity, 0.3); +} +.body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded)::after { + transition: opacity 150ms linear; +} +.body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded):active::after { + transition-duration: 75ms; + opacity: 0.3; + /* @alternate */ + opacity: var(--mdc-ripple-press-opacity, 0.3); +} +.body--theme-dark .material-design-ripple.mdc-ripple-upgraded { + --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.3); +} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css new file mode 100644 index 000000000000..2721c686a2f4 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css @@ -0,0 +1,765 @@ +/* Status icons */ +/* Colors */ +/* Dark theme */ +/* Neutral Colors */ +/* #888 */ +/* #d0d0d0 */ +/* Cards */ +/* CSS Arrow */ +/* links */ +/** Separators */ +/* Status icons */ +/* Colors */ +/* Dark theme */ +/* Neutral Colors */ +/* #888 */ +/* #d0d0d0 */ +/* Cards */ +/* CSS Arrow */ +/* links */ +/** Separators */ +/* Logo */ +/* Font groupings */ +.uppercase { + font-size: 12px; + color: #888888; + text-transform: uppercase; + letter-spacing: 0.1em; + font-weight: bold; +} + +/* Lists */ +/* Images & icons */ +/* Cross-platform background image */ +* { + box-sizing: border-box; +} + +/* Normalize File */ +/*! normalize.scss v0.1.0 | MIT License | based on git.io/normalize */ +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS text size adjust after orientation change, without disabling + * user zoom. + */ +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. + */ +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ +/** + * Remove the gray background color from active links in IE 10. + */ +a { + background-color: transparent; +} + +/** + * Improve readability when focused and also mouse hovered in all browsers. + */ +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ +/** + * Remove border when inside `a` element in IE 8/9/10. + */ +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ +/** + * Address margin not present in IE 8/9 and Safari. + */ +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ +button, +html input[type=button], +input[type=reset], +input[type=submit] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ +input[type=checkbox], +input[type=radio] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ +input[type=number]::-webkit-inner-spin-button, +input[type=number]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome + * (include `-moz` to future-proof). + */ +input[type=search] { + -webkit-appearance: textfield; /* 1 */ + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; /* 2 */ + box-sizing: content-box; +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ +input[type=search]::-webkit-search-cancel-button, +input[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ +/** + * Remove most spacing between table cells. + */ +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} + +/** + * DDG Extension Resets & Base Styles + */ +h1, +h2, +h3, +h4, +h5, +h5, +p, +div { + margin: 0; + padding: 0; +} + +section, +ul, +ol, +li { + margin: 0; + padding: 0; + position: relative; +} + +.environment--android form, +.environment--android input, +.environment--android select, +.environment--android option, +.environment--android button, +.environment--ios form, +.environment--ios input, +.environment--ios select, +.environment--ios option, +.environment--ios button { + outline: none; +} +.environment--android form *, +.environment--android input *, +.environment--android select *, +.environment--android option *, +.environment--android button *, +.environment--ios form *, +.environment--ios input *, +.environment--ios select *, +.environment--ios option *, +.environment--ios button * { + outline: none; +} + +button { + border: none; + background-color: #ffffff; + padding: 0; +} + +/* Fonts */ +input, +textarea, +select { + color: #333333; +} + +.body--theme-dark input, +.body--theme-dark textarea { + color: rgba(255, 255, 255, 0.9); +} +.body--theme-dark input, +.body--theme-dark textarea { + background-color: #333333; +} + +.body--theme-dark.environment--windows select { + background-color: rgba(255, 255, 255, 0.06); + border-color: #444; + color: rgba(255, 255, 255, 0.9); +} + +.body--theme-dark.environment--windows select > option { + background-color: #333333; +} + +.bold { + font-weight: bold; +} + +strong { + font-weight: bold; +} +.environment--browser strong { + font-weight: 600; +} + +/* Links */ +a { + color: var(--color-accent-blue); + text-decoration: none; +} +a:hover { + text-decoration: underline; +} +.environment--ios a.link-action:visited, .environment--ios a.link-action:active, .environment--ios a.link-action:hover, .environment--android a.link-action:visited, .environment--android a.link-action:active, .environment--android a.link-action:hover { + text-decoration: none; +} +a.link-action--text { + padding: 16px 0; + display: block; +} +a.link-action--text-short { + display: block; + padding: 12px 0; +} +a.link-action--text-micro { + display: block; + padding: 8px 0; +} +a.link-action--rounded { + border-radius: 12px; + padding-top: 14px; + padding-bottom: 14px; +} +.environment--ios a.link-action--rounded { + font-size: 14px; + padding-top: 16px; + padding-bottom: 16px; +} +.environment--windows a.link-action--rounded { + line-height: 22px; + font-size: 14px; + padding-top: 16px; + padding-bottom: 16px; +} +.environment--browser a.link-action--rounded { + line-height: 18px; + font-size: 14px; + padding-top: 12px; + padding-bottom: 12px; +} + +/** + * DDG Extension Helper Classes + */ +/* Hide element */ +.is-hidden { + display: none; +} + +/* Position */ +.pull-right { + position: absolute; + right: 16px; +} + +.pull-left { + position: absolute; + left: 16px; +} + +/* Display */ +.block { + display: block; +} + +/* Floats */ +.float-left { + float: left; +} + +.float-right { + float: right; +} + +.clearfix { + clear: both; + height: 0; + line-height: 0; +} + +/* Text Centering */ +.text--center { + text-align: center; +} + +.height-full { + height: 100%; +} + +.text--left { + text-align: left; +} + +/* Text Wrap */ +.text--balance { + text-wrap: balance; +} + +/* Borders */ +.border--top { + border-top: 1px solid var(--color-lines-light); +} + +.border--bottom { + border-bottom: 1px solid var(--color-lines-light); +} + +.border-light--top { + border-top: 1px solid var(--color-lines-lighter); +} + +.border--top--inner { + position: relative; +} +.border--top--inner:before { + content: ""; + border-top: 1px solid var(--color-lines-light); + position: absolute; + top: 0; + left: 0; + right: 0; +} + +.padding-x { + padding-left: 16px; + padding-right: 16px; +} + +.padding-y { + padding-top: 16px; + padding-bottom: 16px; +} + +.padding-y-third { + padding-top: 24px; + padding-bottom: 24px; +} + +.padding-y--reduced { + padding-top: 14px; + padding-bottom: 14px; +} +.environment--ios .padding-y--reduced, .environment--android .padding-y--reduced { + padding-top: 8.5px; + padding-bottom: 8.5px; +} + +.padding-bottom-half { + padding-bottom: 10px; +} + +.bg-primary { + background: white; +} + +.padding-x-double { + padding-left: 32px; + padding-right: 32px; +} + +.padding-x-third { + padding-left: 24px; + padding-right: 24px; +} + +.padding-x-xl { + padding-left: 44px; + padding-right: 44px; +} + +.padded--top { + padding: 24px 0 0; +} + +.padded--no-bottom-padding { + padding-bottom: 0; +} + +/* Icons */ +/* Standard icon display within the extension */ +.icon { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + /* you'll need to set the background image within each instance of .icon */ +} +.icon.icon__close { + width: 14px; + height: 14px; + background-image: url("../../img/close.svg"); +} +.icon.icon__arrow { + width: 12px; + height: 12px; + background-size: contain; + background-image: url("../../img/refresh-assets/chevron.svg"); +} +.body--theme-dark .icon.icon__arrow { + background-image: url("../../img/refresh-assets/chevron--light.svg"); +} +.icon.icon__arrow.icon__arrow--left { + transform: rotate(180deg); +} +.icon.icon__arrow.icon__arrow--large { + width: 7px; + margin-top: -20px; + background-image: url("../../img/arrow--large.svg"); +} +.icon.icon__back-arrow { + background-size: contain; + background-image: url("../../img/refresh-assets/back-arrow.svg"); +} +.body--theme-dark .icon.icon__back-arrow { + background-image: url("../../img/refresh-assets/back-arrow--light.svg"); +} +.environment--android .icon.icon__back-arrow { + background-image: url("../../img/refresh-assets/back-arrow-android.svg"); +} +.body--theme-dark.environment--android .icon.icon__back-arrow { + background-image: url("../../img/refresh-assets/back-arrow-android--light.svg"); +} +.environment--ios .icon.icon__back-arrow { + background-image: url("../../img/refresh-assets/back-chevron-ios.svg"); + width: 20px; + height: 20px; +} +.environment--ios .icon.icon__back-arrow:before { + content: attr(data-icon-text); + display: block; + height: 20px; + line-height: 20px; + margin-left: 20px; +} +.body--theme-dark.environment--ios .icon.icon__back-arrow { + background-image: url("../../img/refresh-assets/back-chevron-ios--light.svg"); +} + +.separator { + width: 1px; + height: 18px; + background-color: rgba(0, 0, 0, 0.05); + display: inline-block; + vertical-align: bottom; + margin: 0 7px; +} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css new file mode 100644 index 000000000000..4d02f2bf9b19 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css @@ -0,0 +1,4095 @@ +@charset "UTF-8"; +/* Status icons */ +/* Colors */ +/* Dark theme */ +/* Neutral Colors */ +/* #888 */ +/* #d0d0d0 */ +/* Cards */ +/* CSS Arrow */ +/* links */ +/** Separators */ +/* Status icons */ +/* Colors */ +/* Dark theme */ +/* Neutral Colors */ +/* #888 */ +/* #d0d0d0 */ +/* Cards */ +/* CSS Arrow */ +/* links */ +/** Separators */ +/* Logo */ +/* Font groupings */ +.uppercase { + font-size: 12px; + color: #888888; + text-transform: uppercase; + letter-spacing: 0.1em; + font-weight: bold; +} + +/* Lists */ +/* Images & icons */ +/* Cross-platform background image */ +/** + * We are using a subset of DDG fonts that are compatible with Chrome: + */ +@font-face { + font-family: "DDG_ProximaNova"; + src: url("/public/font/ProximaNova-Reg-webfont.woff") format("woff"); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: "DDG_ProximaNova"; + src: url("/public/font/ProximaNova-Sbold-webfont.woff") format("woff"); + font-weight: 600; + font-style: bold; +} +.token-body { + font-family: system, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 13px; + font-weight: 400; + line-height: 16px; +} +.token-body.environment--android { + font-size: 14px; + font-weight: 400; + line-height: 20px; +} +.token-body.environment--browser { + font-family: "DDG_ProximaNova"; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 18px; +} + +.token-body-em { + font-size: 13px; + font-weight: 600; + line-height: 16px; +} +.environment--android .token-body-em { + font-size: 14px; + font-weight: 500; + line-height: 20px; +} +.environment--ios .token-body-em { + font-size: 15px; + font-weight: 600; + line-height: 22px; +} +.environment--browser .token-body-em { + font-family: "DDG_ProximaNova"; + font-style: normal; + font-weight: 600; + font-size: 14px; + line-height: 20px; +} + +/* Mac/System Keywords/Title 2 (Emphasis) */ +.token-title-2-em { + font-size: 17px; + font-style: normal; + font-weight: 600; + line-height: 22px; +} + +.token-title-3 { + font-size: 15px; + font-weight: 400; + line-height: 20px; +} +.environment--ios .token-title-3 { + font-size: 16px; + line-height: 22px; + letter-spacing: 0; +} +.environment--android .token-title-3 { + font-size: 16px; + line-height: 20px; + letter-spacing: 0; +} +.environment--browser .token-title-3 { + font-family: "DDG_ProximaNova"; + font-size: 16px; + line-height: 20px; +} + +.token-ios-title-3 { + font-size: 20px; + font-weight: 600; + line-height: 1.25; +} + +.token-title-3-em { + font-size: 16px; + font-weight: 600; + line-height: 22px; +} +.environment--android .token-title-3-em { + font-size: 16px; + line-height: 20px; +} +.token-title-3-em .environment--windows { + font-size: 16px; + font-weight: 600; + line-height: 1.25; +} +.environment--browser .token-title-3-em { + font-family: "DDG_ProximaNova"; + font-style: normal; + font-size: 16px; + line-height: 20px; +} + +.token-breakage-form-body { + font-size: 13px; + font-weight: 400; + line-height: 16px; +} +.environment--android .token-breakage-form-body { + font-size: 16px; + font-weight: 400; + line-height: 20px; + letter-spacing: 0em; +} +.environment--browser .token-breakage-form-body { + font-size: 14px; + font-weight: 400; + line-height: 18px; +} +.environment--windows .token-breakage-form-body { + font-size: 14px; + font-weight: 400; + line-height: 20px; +} + +.token-headline-2 { + font-size: 20px; + font-weight: 500; + line-height: 1.2; +} + +.token-label-em { + font-size: 13px; + font-weight: 600; + line-height: 13px; +} +.environment--android .token-label-em { + font-size: 15px; + font-weight: 700; + line-height: 21px; + letter-spacing: 0em; +} +.environment--browser .token-label-em { + font-size: 13px; + font-weight: 600; + line-height: 13px; +} + +.token-search-input { + font-weight: 400; + font-size: 15px; + line-height: 20px; +} + +.token-bold { + font-weight: 600; +} + +@media (prefers-reduced-motion: reduce) { + * { + transition: none !important; + } +} + +/* Popup */ +body { + font-family: system, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 13px; + font-weight: 400; + line-height: 16px; + overflow: hidden; + user-select: none; + -webkit-user-select: none; + -webkit-tap-highlight-color: transparent; + --width: 360px; + --height: 100vh; + --bg: #eee; + --page-bg: #ffffff; + --page-outer-bg: #eee; + --color-text-primary: rgba(0, 0, 0, 0.84); + --color-text-secondary: rgba(0, 0, 0, 0.6); + --color-accent-blue: #3969ef; + --color-accent-blue-active: #1e42a4; + --color-lines-light: rgba(0, 0, 0, 0.12); + --color-lines-lighter: rgba(0, 0, 0, 0.06); + --color-hover-bg: rgba(0, 0, 0, 0.06); + --color-system-lines: rgba(0, 0, 0, 0.09); + --size-unit: 16px; + --size-unit-half: calc(var(--size-unit) / 2); + --size-unit-double: calc(var(--size-unit) * 2); + --btn-accent-border-radius: 8px; + --btn-accent-border: 0.5px solid rgba(40, 145, 255, 0.05); + --btn-accent-bg: linear-gradient(180deg, #4690f7 0%, #307bf7 100%); + --btn-accent-bg-hover: linear-gradient(180deg, #4690f7 0%, #307bf7 100%); + --btn-accent-bg-active: linear-gradient(0deg, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.12)), + linear-gradient(180deg, #1f8aff 0%, #0173ff 100%); + --btn-accent-color: #ffffff; + --btn-accent-shadow: 0px 0px 1px rgba(40, 145, 255, 0.05), 0px 1px 1px rgba(40, 145, 255, 0.1); + color: var(--color-text-primary); + background: var(--bg); + width: var(--width); + height: var(--height); +} +body.environment--android { + font-size: 14px; + font-weight: 400; + line-height: 20px; +} +body.environment--browser { + font-family: "DDG_ProximaNova"; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 18px; +} +body.environment--ios { + --width: 100%; + --height: -webkit-fill-available; +} +body.environment--android { + --width: 100%; +} +body.environment--macos[data-screen=toggleReport] { + --height: auto; +} +body.environment--browser { + --height: 600px; +} +body.environment--windows { + --bg: #ffffff; + --btn-accent-border-radius: none; + --btn-accent-border: 0.5px solid rgba(40, 145, 255, 0.05); + --btn-accent-bg: #3969ef; + --btn-accent-bg-hover: #2b55ca; + --btn-accent-bg-active: #1e42a4; + --btn-accent-shadow: none; +} +body.body--theme-light.environment--ios, body.body--theme-light.environment--android { + --bg: #ffffff; +} +body.body--theme-dark { + --text: rgba(255, 255, 255, 0.9); + --page-bg: #333333; + --bg: #34383b; + --page-outer-bg: #34383b; + --color-text-primary: rgba(255, 255, 255, 0.84); + --color-text-secondary: rgba(255, 255, 255, 0.6); + --color-accent-blue: #7295f6; + --color-accent-blue-active: #8fabf9; + --color-lines-light: rgba(255, 255, 255, 0.18); + --color-lines-lighter: rgba(255, 255, 255, 0.09); + --color-hover-bg: rgba(255, 255, 255, 0.12); + --color-system-lines: rgba(255, 255, 255, 0.09); +} +body.body--theme-dark.environment--windows { + --btn-accent-color: #000000; + --btn-accent-bg: #7295f6; + --btn-accent-bg-hover: #557ff3; + --btn-accent-bg-active: #3969ef; +} +body.body--theme-dark.environment--android { + --bg: #111111; + --page-bg: #111111; +} +body.body--theme-dark.environment--ios { + --bg: #222222; + --page-bg: #222222; +} + +.app-height { + height: var(--height); +} + +#popup-container { + display: block; +} +#popup-container section::-webkit-scrollbar { + display: none; +} +#popup-container .text-line-after-icon { + margin-left: 12px; +} +#popup-container .sliding-subview { + background-color: var(--page-bg); +} + +body { + /* 'toggle' here means the wrapping container, a button element */ + --toggle-width: 32px; + --toggle-height: 18px; + --toggle-opacity: 1; + --toggle-opacity-disabled: 1; + /* the 'knob', also referred to as the 'handle' */ + --handle-size: 16px; + --handle-offset: 1px; + --handle-color: #ffffff; + --handle-color-off: #ffffff; + --handle-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.25); + /* the 'track' is the underlying colored background */ + --track-color: #007aff; + --track-outline: none; + --track-outline-off: none; + --track-color-off: #d8d8d8; + /* the 'spinner' is only used on ios/macos */ + --toggle-spinner-size: 18px; +} +body.environment--ios { + --toggle-width: 51px; + --toggle-height: 31px; + --toggle-spinner-size: 31px; + --handle-size: 27px; + --handle-offset: 2px; + --track-color: #21c000; +} +body.environment--android { + --toggle-width: 51px; + --toggle-height: 31px; + --toggle-spinner-size: 31px; + --handle-size: 24px; + --handle-offset: 4px; + --handle-shadow: none; + --track-color: #3969ef; + --track-color-off: rgba(136, 136, 136, 0.5); +} +body.environment--android.body--theme-dark { + --track-color: #7295f6; + --track-color-off: rgba(204, 204, 204, 0.5); +} +body.environment--windows { + --toggle-width: 40px; + --toggle-height: 20px; + --handle-size: 10px; + --handle-offset: 5px; + --handle-color-off: rgba(0, 0, 0, 0.9); + --handle-shadow: none; + --track-color: #3969ef; + --track-color-off: #ffffff; + --track-outline: 1px solid var(--track-color); + --track-outline-off: 1px solid rgba(0, 0, 0, 0.48); + --toggle-opacity-disabled: 0.6; +} + +.toggle-button { + z-index: 0; + margin: 0; + padding: 0; + border: none; + background-color: transparent; + text-align: left; + position: relative; + border-radius: 100px; + opacity: var(--toggle-opacity); + width: var(--toggle-width); + height: var(--toggle-height); +} +.toggle-button[disabled] { + opacity: var(--toggle-opacity-disabled); +} + +.toggle-button__track { + z-index: -1; + position: absolute; + right: 0; + top: 0; + overflow: visible; + border-radius: 100px; + border: var(--track-outline); + width: var(--toggle-width); + height: var(--toggle-height); + background-color: var(--track-color); +} +[aria-checked=false] .toggle-button__track { + background-color: var(--track-color-off); + border: var(--track-outline-off); +} + +.toggle-button__handle { + z-index: 2; + position: absolute; + border-radius: 100px; + top: 50%; + transform: translateY(-50%); + transition: all 0.2s ease; + box-shadow: var(--handle-shadow); + background-color: var(--handle-color); + width: var(--handle-size); + height: var(--handle-size); + right: var(--handle-offset); +} +[aria-checked=false] .toggle-button__handle { + right: calc(100% - var(--handle-size) - var(--handle-offset)); + background-color: var(--handle-color-off); +} + +.toggle-spinner { + margin: 0 auto; + height: var(--toggle-spinner-size); + width: var(--toggle-spinner-size); +} + +.page { + display: flex; + flex-direction: column; +} +.environment--browser .page, .environment--ios .page, .environment--android .page { + height: 100%; +} + +.page-inner { + display: flex; + flex-direction: column; + flex-flow: column; + z-index: 1; + overflow-y: auto; + -ms-overflow-style: none; + scrollbar-width: none; + background: var(--page-bg); +} +.page-inner::-webkit-scrollbar { + display: none; +} +.environment--browser .page-inner, .environment--ios .page-inner, .environment--android .page-inner { + height: 100%; +} +.page-inner[data-with-permissions=true] { + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.05), 0px 1px 0px rgba(0, 0, 0, 0.1); +} + +.page-outer { + z-index: 0; + background: var(--page-outer-bg); +} + +.header { + padding-left: 16px; + padding-right: 16px; + border-bottom: 1px solid var(--color-lines-light); +} +.environment--macos .header { + padding-top: 16px; + padding-bottom: 2px; +} +.environment--windows .header { + padding-top: 16px; +} +.environment--browser .header { + padding-top: 6px; +} +.environment--android .header { + padding-bottom: 10px; +} +.environment--ios .header { + padding-bottom: 10px; +} + +.header--breakage { + padding-left: 16px; + padding-right: 16px; + padding-bottom: 16px; + border-bottom: 0; +} +.environment--macos .header--breakage, .environment--windows .header--breakage { + padding-bottom: 16px; +} +.environment--browser .header--breakage { + padding-top: 16px; + padding-bottom: 12px; +} + +.header-spacer { + padding-top: 24px; +} +.environment--macos .header-spacer { + padding-top: 20px; +} +.environment--windows .header-spacer { + padding-top: 20px; +} +.environment--browser .header-spacer { + padding-top: 12px; +} + +.footer { + margin-top: auto; +} +.environment--macos .footer, .environment--windows .footer { + padding-bottom: 20px; +} + +.site-info { + margin-top: 0; +} +.environment--browser .site-info { + height: 100%; +} +.environment--ios .site-info > :last-child { + padding-bottom: 18px; +} +.site-info .list-wrapper { + background-color: var(--page-bg); +} +.site-info .default-list { + padding-bottom: 0; +} +.site-info:has(.page-outer) .page-inner { + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.05), 0px 1px 0px rgba(0, 0, 0, 0.1); +} + +.site-info__page-permission label { + display: flex; + justify-content: space-between; + overflow: hidden; + padding: 16px 0; +} +.site-info__page-permission select { + float: right; + max-width: 170px; +} +.site-info__page-permission + .site-info__page-permission { + border-top: 1px solid var(--color-lines-light); +} + +.site-info__li--manage-permissions { + padding: 5px 16px 0; +} + +.site-info__page-permission__icon { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + margin-right: 8px; +} +.site-info__page-permission__icon[data-icon=geolocation] { + background-image: url("../../img/refresh-assets/permissions-location.svg"); +} +.body--theme-dark .site-info__page-permission__icon[data-icon=geolocation] { + background-image: url("../../img/refresh-assets/permissions-location-light.svg"); +} +.site-info__page-permission__icon[data-icon=microphone] { + background-image: url("../../img/refresh-assets/permissions-microphone.svg"); + margin-top: -2px; +} +.body--theme-dark .site-info__page-permission__icon[data-icon=microphone] { + background-image: url("../../img/refresh-assets/permissions-microphone-light.svg"); +} +.site-info__page-permission__icon[data-icon=camera] { + background-image: url("../../img/refresh-assets/permissions-camera.svg"); + width: 16px; + height: 12px; + margin-top: -2px; +} +.body--theme-dark .site-info__page-permission__icon[data-icon=camera] { + background-image: url("../../img/refresh-assets/permissions-camera-light.svg"); +} +.site-info__page-permission__icon[data-icon=popups] { + background-image: url("../../img/refresh-assets/permissions-popups.svg"); +} +.body--theme-dark .site-info__page-permission__icon[data-icon=popups] { + background-image: url("../../img/refresh-assets/permissions-popups-light.svg"); +} +.site-info__page-permission__icon[data-icon=externalScheme] { + background-image: url("../../img/refresh-assets/permissions-externalScheme.svg"); + margin-top: -4px; +} +.body--theme-dark .site-info__page-permission__icon[data-icon=externalScheme] { + background-image: url("../../img/refresh-assets/permissions-externalScheme-light.svg"); +} +.site-info__page-permission__icon[data-icon=notification] { + background-image: url("../../img/refresh-assets/permissions-notification.svg"); + width: 16px; + height: 14px; + margin-top: -4px; +} +.body--theme-dark .site-info__page-permission__icon[data-icon=notification] { + background-image: url("../../img/refresh-assets/permissions-notification-light.svg"); +} + +.site-info__protection-wrapper { + padding: 16px; +} + +.site-info__protection { + opacity: 1; + margin-top: 0; + padding-right: 10px; +} + +.site-info-toggle { + color: #333333; + display: flex; + align-items: center; +} +.body--theme-dark .site-info-toggle { + color: rgba(255, 255, 255, 0.9); +} + +.site-info__toggle-container { + margin-left: auto; + text-align: center; + display: flex; + width: var(--toggle-width); + height: var(--toggle-height); +} + +.card { + background-color: var(--page-bg); +} +.environment--browser .card { + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; +} + +.card-list--bordered { + border: 1px solid var(--color-lines-light); + border-radius: 12px; + position: relative; + z-index: 0; + overflow: hidden; +} + +.main-nav { + border: 1px solid var(--color-lines-light); + border-radius: 12px; + position: relative; + z-index: 0; + overflow: hidden; +} + +.main-nav__row { + position: relative; + /* + The following avoids height shifts when hovering over nav rows. + + Each row has an :after element that provides the separator line. When hovering a row, we need to change the color of any adjacent separators (i.e. the current row and the row above it). + + We do that by targeting the current row directly, then use a :has selector to also target the previous sibling of the current row. + + We also use the :not selector to exclude any rows marked as no-hover. + */ +} +.main-nav__row:after { + content: " "; + display: block; + width: calc(100% - 32px); + height: 1px; + background: var(--color-lines-light); + position: absolute; + bottom: -0.5px; + left: 16px; +} +.main-nav__row:not(.no-hover):hover:after, .main-nav__row:has(+ :not(.no-hover):hover):after { + background-color: var(--page-bg); +} +.main-nav__row:last-child { + border-bottom: none; +} +.main-nav__row:last-child:after { + display: none; +} + +.main-nav__item { + z-index: 10; + position: relative; + display: flex; + height: 44px; + align-items: center; + -webkit-touch-callout: none; +} +.environment--ios .main-nav__item, .environment--android .main-nav__item { + height: 48px; +} +.environment--browser .main-nav__item { + height: 40px; +} +.main-nav__item:has(.main-nav__icon) .main-nav__text { + margin-left: 10px; +} + +.main-nav__item--link { + color: var(--color-text-primary); +} +.environment--example .main-nav__item--link:focus, .environment--browser .main-nav__item--link:focus, .environment--windows .main-nav__item--link:focus, .environment--macos .main-nav__item--link:focus { + outline: 0; + text-decoration: underline; +} +.environment--example .main-nav__item--link:visited, .environment--example .main-nav__item--link:active, .environment--example .main-nav__item--link:hover, .environment--browser .main-nav__item--link:visited, .environment--browser .main-nav__item--link:active, .environment--browser .main-nav__item--link:hover, .environment--windows .main-nav__item--link:visited, .environment--windows .main-nav__item--link:active, .environment--windows .main-nav__item--link:hover, .environment--macos .main-nav__item--link:visited, .environment--macos .main-nav__item--link:active, .environment--macos .main-nav__item--link:hover { + text-decoration: none; + background: var(--color-hover-bg); +} +.environment--ios .main-nav__item--link:active { + opacity: 0.5; +} + +.main-nav__icon { + width: 18px; + height: 18px; + z-index: 1; + margin-left: 19px; + background-repeat: no-repeat; + background-size: cover; + flex-shrink: 0; +} + +.main-nav__text { + display: block; + z-index: 1; + margin-left: 16px; + margin-right: 10px; + line-height: 1; + /** TODO: Move */ +} +.environment--ios .main-nav__text { + line-height: 1.3333333333; +} +.environment--android .main-nav__text { + line-height: 1.4285714286; +} +.environment--macos .main-nav__text { + line-height: 1.2307692308; +} +.environment--windows .main-nav__text { + line-height: 1.2857142857; +} + +.main-nav__chev { + width: 7px; + height: 18px; + margin-left: auto; + margin-right: 16px; + background-repeat: no-repeat; + background-size: 7px; + background-position: center center; + opacity: 60%; + background-image: url("../../img/refresh-assets/chevron.svg"); +} +.body--theme-dark .main-nav__chev { + background-image: url("../../img/refresh-assets/chevron--light.svg"); +} +.environment--ios .main-nav__chev, .environment--android .main-nav__chev { + opacity: 24%; +} + +.icon-small--info { + background-image: url("../../img/status--info.svg"); +} + +.icon-small--blocked, +.icon-small--secure { + background-image: url("../../img/refresh-assets/Check-Color-16.svg"); +} + +.icon-small--warning, +.icon-small--insecure { + background-image: url("../../img/refresh-assets/Error-Color-16.svg"); +} + +.search { + display: flex; + align-items: center; + padding: 8px; + background: #ffffff; + height: 56px; +} +.body--theme-dark .search { + background-color: #333333; +} + +.search-form { + flex: 1; + display: flex; + margin-right: 8px; +} + +.search-form__input { + -moz-appearance: none; + outline: medium none; + border: medium none; + padding-left: 46px; + z-index: 1; + color: #333333; + height: 40px; + background-color: #eee; + background-image: url("../../img/logo-small-new.svg"); + background-repeat: no-repeat; + background-position: 10px 8px; + background-size: 24px; + border-radius: 10px 0 0 10px; + flex-grow: 1; +} +.body--theme-dark .search-form__input { + background-color: rgba(255, 255, 255, 0.12); +} +.search-form__input::placeholder { + color: #999999; +} + +.search-form__go { + display: flex; + align-items: center; + justify-content: center; + background-color: #eee; + height: 40px; + width: 42px; + padding: 0 0.64em; + min-height: 1.8em; + -moz-appearance: none; + cursor: pointer; + text-align: center; + border: medium none; + outline: medium none; + z-index: 2; + border-radius: 0 10px 10px 0; +} +.search-form__go svg { + position: relative; + top: -1px; + left: -1px; +} +.search-form__go .loupe-handle { + fill: currentColor; + opacity: 0.8; +} +.search-form__go .loupe-glass { + stroke: currentColor; + opacity: 0.8; +} +.body--theme-dark .search-form__go { + background-color: rgba(255, 255, 255, 0.12); +} +.body--theme-dark .search-form__go:hover, .body--theme-dark .search-form__go:focus { + background-color: rgba(255, 255, 255, 0.2); +} +.search-form__go:hover, .search-form__go:focus { + background-color: #2950bf; + color: white; +} +[data-focussed=true] .search-form__go, .search-form__go.go--focused { + background-color: #3969ef; + color: white; +} +[data-focussed=true] .search-form__go:hover, [data-focussed=true] .search-form__go:focus, .search-form__go.go--focused:hover, .search-form__go.go--focused:focus { + background-color: #2950bf; +} + +/* cog-button */ +.cog-button { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + background-position: center; + background-repeat: no-repeat; + background-color: transparent; + border-radius: 3px; +} +.cog-button:hover, .cog-button:active, .cog-button:focus { + background-color: #eee; +} +.body--theme-dark .cog-button:hover, .body--theme-dark .cog-button:active, .body--theme-dark .cog-button:focus { + background-color: #444; +} +.cog-button .settings-cog { + fill: black; +} +.body--theme-dark .cog-button .settings-cog { + fill: white; + opacity: 0.8; +} + +.fire-button { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + background-position: center; + background-repeat: no-repeat; + background-color: transparent; + border-radius: 3px; +} +.fire-button:hover, .fire-button:active, .fire-button:focus { + background-color: #eee; +} +.body--theme-dark .fire-button:hover, .body--theme-dark .fire-button:active, .body--theme-dark .fire-button:focus { + background-color: #444; +} +.fire-button .fire-icon { + fill: black; +} +.body--theme-dark .fire-button .fire-icon { + fill: white; + opacity: 0.8; +} + +.large-icon-container { + height: 96px; + background-position: center center; + background-repeat: no-repeat; + margin-bottom: 24px; + background-size: contain; +} + +.medium-icon-container { + height: 72px; + background-position: center center; + background-repeat: no-repeat; + margin-bottom: 16px; + background-size: contain; +} + +.hero-icon--breakage-form { + background-image: url("../../img/refresh-assets/Breakage-128.svg"); + margin-bottom: 20px; +} +.environment--browser .hero-icon--breakage-form { + margin-bottom: 16px; +} + +.hero-icon--toggle-report { + background-image: url("../../img/refresh-assets/Breakage-128.svg"); + margin-bottom: 0; +} + +.hero-icon--toggle-report-sent { + background-image: url("../../img/refresh-assets/breakage-sent.svg"); +} + +.hero-icon--tracker-network { + background-image: url("../../img/refresh-assets/Network-128.svg"); +} + +.hero-icon--insecure-connection, +.hero-icon--trackers-blocked, +.hero-icon--connection-none, +.hero-icon--connection-invalid { + background-image: url("../../img/refresh-assets/Unlocked-128.svg"); +} + +.hero-icon--major-networks-blocked { + background-image: url("../../img/refresh-assets/Shield-128.svg"); +} + +.hero-icon--protections-off, +.hero-icon--major-networks-warning, +.hero-icon--major-networks-protections-off { + background-image: url("../../img/refresh-assets/Block-Disabled-128.svg"); +} + +.hero-icon--info, +.hero-icon--major-networks-info { + background-image: url("../../img/refresh-assets/Block-Info-128.svg"); +} + +.hero-icon--no-activity, +.hero-icon--major-networks-no-activity { + background-image: url("../../img/refresh-assets/Counter-128.svg"); +} + +.hero-icon--connection-secure, +.hero-icon--connection-upgraded { + background-image: url("../../img/refresh-assets/Locked-128.svg"); +} + +.hero-icon--cookies-managed { + background-image: url("../../img/refresh-assets/Cookies-Managed-128.svg"); +} + +.hero-icon--cookies-hidden { + background-image: url("../../img/refresh-assets/Cookies-Hidden-128.svg"); +} + +.hero-icon--phishing, +.hero-icon--connection-phishing { + background-image: url("../../img/refresh-assets/Phishing-128.svg"); +} + +.hero-icon--chat { + background-image: url("../../img/refresh-assets/chat-private-128.svg"); +} + +.hero-icon--switch-shield { + background-image: url("../../img/refresh-assets/switch-shield-128.svg"); +} + +.key-insight { + position: relative; + padding-bottom: 24px; + text-align: center; +} +.key-insight[data-suffix=about-link] { + padding-bottom: 12px; +} +.environment--browser .key-insight { + background-color: transparent; +} +.environment--ios .key-insight { + padding-top: 6px; +} +.key-insight .token-title-3-em { + margin-bottom: 8px; +} + +.key-insight__icon { + height: 96px; + background-position: center center; + background-repeat: no-repeat; + margin-bottom: 24px; + background-size: contain; +} +.environment--macos .key-insight__icon { + margin-bottom: 20px; +} +.environment--windows .key-insight__icon { + margin-bottom: 20px; +} +.environment--browser .key-insight__icon { + margin-bottom: 12px; +} + +.environment--macos .key-insight--main { + padding-bottom: 20px; +} +.environment--windows .key-insight--main { + padding-bottom: 20px; +} +.environment--browser .key-insight--main { + padding-bottom: 12px; +} + +.key-insight--breakage { + padding-bottom: 20px; +} +.environment--browser .key-insight--breakage { + padding-bottom: 16px; +} +.environment--windows .key-insight--breakage { + padding-bottom: 12px; +} + +body { + --nav-height: 56px; +} +body.environment--macos, body.environment--browser, body.environment--windows, body.environment--example { + --nav-height: var(--size-unit-double); +} + +.top-nav { + text-align: center; + position: fixed; + z-index: 1; + width: 100%; + height: var(--nav-height); + background: var(--page-bg); +} + +.top-nav__spacer { + height: var(--nav-height); +} + +.top-nav__back { + position: absolute; + padding: var(--size-unit-half); + left: var(--size-unit-half); + top: 50%; + transform: translateY(-50%); + display: flex; + color: var(--color-text-primary); +} +.top-nav__back:hover, .top-nav__back:focus, .top-nav__back:active { + text-decoration: none; +} +.environment--android .top-nav__back { + border-radius: 100%; + left: 10px; +} +.environment--ios .top-nav__back { + font-size: 17px; + font-weight: 400; + left: 0; +} +.environment--ios .top-nav__back:active { + opacity: 0.5; +} +.environment--macos .top-nav__back, .environment--browser .top-nav__back, .environment--windows .top-nav__back, .environment--example .top-nav__back { + border-radius: 0; + bottom: 0; + padding: 0; + height: 32px; + width: 32px; +} +.environment--macos .top-nav__back .icon, .environment--browser .top-nav__back .icon, .environment--windows .top-nav__back .icon, .environment--example .top-nav__back .icon { + position: absolute; + left: 50%; + transform: translateX(-50%) translateY(100%); + width: 15px; + height: 15px; +} + +.top-nav__done { + position: absolute; + padding: 0 var(--size-unit-half); + right: var(--size-unit-half); + height: var(--nav-height); + line-height: var(--nav-height); + color: var(--color-text-primary); +} +.top-nav__done:hover, .top-nav__done:focus, .top-nav__done:active { + text-decoration: none; +} +.environment--ios .top-nav__done { + font-size: 17px; + font-weight: 600; + font-weight: 600; +} +.environment--ios .top-nav__done:active { + opacity: 0.5; +} +.environment--macos .top-nav__done { + height: auto; + line-height: normal; + bottom: 0; +} + +.top-nav__cancel { + position: absolute; + padding: 0 var(--size-unit-half); + right: var(--size-unit-half); + height: var(--nav-height); + line-height: var(--nav-height); + color: var(--color-text-primary); +} +.top-nav__cancel:hover, .top-nav__cancel:focus, .top-nav__cancel:active { + text-decoration: none; +} +.environment--ios .top-nav__cancel { + font-size: 17px; +} +.environment--ios .top-nav__cancel:active { + opacity: 0.5; +} + +.top-nav__title { + position: absolute; + height: var(--nav-height); + line-height: 1.1; + color: var(--color-text-primary); + left: 50%; + transform: translateX(-50%); + display: flex; + align-items: center; +} +.environment--ios .top-nav__title { + font-size: 17px; + font-weight: 600; +} +.environment--ios .top-nav__title:active { + opacity: 0.5; +} +.environment--android .top-nav__title { + transform: unset; + left: 72px; + top: 2px; + font-size: 20px; + font-weight: 500; +} +.environment--android .top-nav__title:active { + opacity: 0.5; +} + +.status-list--right .status-list__item { + padding-left: 0; + padding-right: 40px; +} +.status-list--right .status-list__item:before { + left: auto; + right: 0; +} + +.status-list__item { + padding-left: 40px; + list-style-type: none; + line-height: 22px; + margin-bottom: 23px; +} +.status-list__item:last-child { + margin-bottom: 0; +} +.status-list__item:before { + content: ""; + position: absolute; + left: 0; + height: 20px; + width: 23px; + top: -1px; + background-repeat: no-repeat; + background-position-y: center; + min-height: 22px; + max-height: 30px; +} + +.status-list__item--good:before { + background-image: url("../../img/status--good.svg"); +} + +.status-list__item--bad:before { + background-image: url("../../img/status--bad.svg"); +} + +.status-list__item--mixed:before { + background-image: url("../../img/status--mixed.svg"); +} + +/* privacy practices uses the modifier 'poor' */ +.status-list__item--poor:before { + background-image: url("../../img/status--bad.svg"); +} + +.icon-list { + position: relative; + display: flex; + justify-content: center; +} + +.icon-list__item { + display: flex; + align-items: center; +} + +.icon-list__count { + display: inline-block; + letter-spacing: -0.7px; +} + +.icon-list__icon { + border-radius: 50%; + overflow: hidden; + background-size: contain; + margin: 0; + width: 20px; + height: 20px; +} +.icon-list__icon.color-1 { + background-color: #94b3af; +} +.icon-list__icon.color-2 { + background-color: #727998; +} +.icon-list__icon.color-3 { + background-color: #645468; +} +.icon-list__icon.color-4 { + background-color: #4d5f7f; +} +.icon-list__icon.color-5 { + background-color: #855db6; +} +.icon-list__icon.color-6 { + background-color: #5e5adb; +} +.icon-list__icon.color-7 { + background-color: #678fff; +} +.icon-list__icon.color-8 { + background-color: #6bb4ef; +} +.icon-list__icon.color-9 { + background-color: #4a9bae; +} +.icon-list__icon.color-10 { + background-color: #66c4c6; +} +.icon-list__icon.color-11 { + background-color: #55d388; +} +.icon-list__icon.color-12 { + background-color: #99db7a; +} +.icon-list__icon.color-13 { + background-color: #eccc7b; +} +.icon-list__icon.color-14 { + background-color: #e7a538; +} +.icon-list__icon.color-15 { + background-color: #dd6b4c; +} +.icon-list__icon.color-16 { + background-color: #d65d62; +} +.icon-list__icon.A { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/A.svg"); +} +.icon-list__icon.B { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/B.svg"); +} +.icon-list__icon.C { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/C.svg"); +} +.icon-list__icon.D { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/D.svg"); +} +.icon-list__icon.E { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/E.svg"); +} +.icon-list__icon.F { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/F.svg"); +} +.icon-list__icon.G { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/G.svg"); +} +.icon-list__icon.H { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/H.svg"); +} +.icon-list__icon.I { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/I.svg"); +} +.icon-list__icon.J { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/J.svg"); +} +.icon-list__icon.K { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/K.svg"); +} +.icon-list__icon.L { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/L.svg"); +} +.icon-list__icon.M { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/M.svg"); +} +.icon-list__icon.N { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/N.svg"); +} +.icon-list__icon.O { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/O.svg"); +} +.icon-list__icon.P { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/P.svg"); +} +.icon-list__icon.Q { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/Q.svg"); +} +.icon-list__icon.R { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/R.svg"); +} +.icon-list__icon.S { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/S.svg"); +} +.icon-list__icon.T { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/T.svg"); +} +.icon-list__icon.U { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/U.svg"); +} +.icon-list__icon.V { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/V.svg"); +} +.icon-list__icon.W { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/W.svg"); +} +.icon-list__icon.X { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/X.svg"); +} +.icon-list__icon.Y { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/Y.svg"); +} +.icon-list__icon.Z { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/Z.svg"); +} +.icon-list__icon.adjust { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/adjust.svg"); + background-color: transparent; +} +.icon-list__icon.adobe { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/adobe.svg"); + background-color: transparent; +} +.icon-list__icon.amazon { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/amazon.svg"); + background-color: transparent; +} +.icon-list__icon.amplitude { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/amplitude.svg"); + background-color: transparent; +} +.icon-list__icon.appnexus { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/appnexus.svg"); + background-color: transparent; +} +.icon-list__icon.appsflyer { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/appsflyer.svg"); + background-color: transparent; +} +.icon-list__icon.beeswax { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/beeswax.svg"); + background-color: transparent; +} +.icon-list__icon.branchmetrics { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/branchmetrics.svg"); + background-color: transparent; +} +.icon-list__icon.braze { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/braze.svg"); + background-color: transparent; +} +.icon-list__icon.bugsnag { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/bugsnag.svg"); + background-color: transparent; +} +.icon-list__icon.chartbeat { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/chartbeat.svg"); + background-color: transparent; +} +.icon-list__icon.comscore { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/comscore.svg"); + background-color: transparent; +} +.icon-list__icon.criteo { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/criteo.svg"); + background-color: transparent; +} +.icon-list__icon.facebook { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/facebook.svg"); + background-color: transparent; +} +.icon-list__icon.google { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/google.svg"); + background-color: transparent; +} +.icon-list__icon.googleadsgoogle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg"); + background-color: transparent; +} +.icon-list__icon.googleanalyticsgoogle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg"); + background-color: transparent; +} +.icon-list__icon.indexexchange { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/indexexchange.svg"); + background-color: transparent; +} +.icon-list__icon.iponweb { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/iponweb.svg"); + background-color: transparent; +} +.icon-list__icon.instagramfacebook { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/instagramfacebook.svg"); + background-color: transparent; +} +.icon-list__icon.kochava { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/kochava.svg"); + background-color: transparent; +} +.icon-list__icon.linkedin { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/linkedin.svg"); + background-color: transparent; +} +.icon-list__icon.liveramp { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/liveramp.svg"); + background-color: transparent; +} +.icon-list__icon.mediamath { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/mediamath.svg"); + background-color: transparent; +} +.icon-list__icon.microsoft { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/microsoft.svg"); + background-color: transparent; +} +.icon-list__icon.mixpanel { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/mixpanel.svg"); + background-color: transparent; +} +.icon-list__icon.neustar { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/neustar.svg"); + background-color: transparent; +} +.icon-list__icon.newrelic { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/newrelic.svg"); + background-color: transparent; +} +.icon-list__icon.openx { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/openx.svg"); + background-color: transparent; +} +.icon-list__icon.oracle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/oracle.svg"); + background-color: transparent; +} +.icon-list__icon.outbrain { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/outbrain.svg"); + background-color: transparent; +} +.icon-list__icon.pinterest { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/pinterest.svg"); + background-color: transparent; +} +.icon-list__icon.pubmatic { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/pubmatic.svg"); + background-color: transparent; +} +.icon-list__icon.quantcast { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/quantcast.svg"); + background-color: transparent; +} +.icon-list__icon.magnite { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/magnite.svg"); + background-color: transparent; +} +.icon-list__icon.rythmone { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/rythmone.svg"); + background-color: transparent; +} +.icon-list__icon.salesforce { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/salesforce.svg"); + background-color: transparent; +} +.icon-list__icon.sharetrough { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/sharetrough.svg"); + background-color: transparent; +} +.icon-list__icon.smaato { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/smaato.svg"); + background-color: transparent; +} +.icon-list__icon.spotx { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/spotx.svg"); + background-color: transparent; +} +.icon-list__icon.taboola { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/taboola.svg"); + background-color: transparent; +} +.icon-list__icon.tapad { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/tapad.svg"); + background-color: transparent; +} +.icon-list__icon.thenielsencompany { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/thenielsencompany.svg"); + background-color: transparent; +} +.icon-list__icon.thetradedesk { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/thetradedesk.svg"); + background-color: transparent; +} +.icon-list__icon.twitter { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/twitter.svg"); + background-color: transparent; +} +.icon-list__icon.urbanairship { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/urbanairship.svg"); + background-color: transparent; +} +.icon-list__icon.verizonmedia { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/verizonmedia.svg"); + background-color: transparent; +} +.icon-list__icon.warnermedia { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/warnermedia.svg"); + background-color: transparent; +} +.icon-list__icon.xaxis { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/xaxis.svg"); + background-color: transparent; +} +.icon-list__icon.yahoojapan { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/yahoojapan.svg"); + background-color: transparent; +} +.icon-list__icon.yandex { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/yandex.svg"); + background-color: transparent; +} +.icon-list__icon.youtubegoogle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/youtubegoogle.svg"); + background-color: transparent; +} +.icon-list__icon.zeotap { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/zeotap.svg"); + background-color: transparent; +} + +.icon-list__blocked-icon { + border-radius: 100%; + position: absolute; +} +.icon-list__blocked-icon svg path { + shape-rendering: geometricPrecision; +} +.icon-list__blocked-icon svg circle { + shape-rendering: geometricPrecision; +} +.body--theme-dark .icon-list__blocked-icon circle { + fill: #222; +} + +[data-company-icon-position]:nth-child(n+2):nth-child(odd) { + margin-left: -8px; +} + +[data-company-icon-position]:nth-child(n+2):nth-child(even) { + margin-right: -8px; +} + +[data-company-icon-size=large] { + z-index: 4; + display: block; + box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.1), 0px 4px 8px rgba(0, 0, 0, 0.08); + height: 96px; + width: 96px; +} +[data-company-icon-size=large] .icon-list__icon { + margin: 0; + width: 64px; + height: 64px; +} +[data-company-icon-size=large] .icon-list__blocked-icon { + bottom: 14px; + right: 14px; + width: 30px; + height: 30px; +} +.environment--browser [data-company-icon-size=large] .icon-list__blocked-icon { + bottom: 10px; + right: 10px; +} + +[data-company-icon-size=medium] { + z-index: 3; + box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.08), 0px 2px 4px rgba(0, 0, 0, 0.1); + height: 64px; + width: 64px; +} +[data-company-icon-size=medium] .icon-list__icon { + margin: 0; + width: 32px; + height: 32px; +} +[data-company-icon-size=medium] .icon-list__blocked-icon { + width: 24px; + height: 24px; + bottom: 8px; + right: 8px; +} + +[data-company-icon-size=small] { + z-index: 2; + border: 1px solid #f2f2f2; + box-shadow: 0px 1px 0px rgba(125, 125, 125, 0.06); + height: 48px; + width: 48px; +} +[data-company-icon-size=small] .icon-list__icon { + margin: 0; + width: 20px; + height: 20px; +} +[data-company-icon-size=small] .icon-list__blocked-icon { + width: 24px; + height: 24px; + bottom: 3px; + right: 3px; +} + +.icon-list__wrapper { + background-color: #ffffff; + border-radius: 50%; + position: relative; + display: flex; + color: rgba(0, 0, 0, 0.85); + align-items: center; + justify-content: center; +} +.body--theme-dark .icon-list__wrapper { + background-color: #222; + border-color: #222; + color: rgba(255, 255, 255, 0.85); +} + +.icon-list__wrapper--count { + border: 1px solid var(--color-lines-light); + height: 46px; + width: 46px; + background: #fafafa; + font-size: 16px; +} + +.tracker-networks__explainer { + padding: 0 32px 0; +} +.tracker-networks__explainer .about-link { + display: block; + padding-top: 8px; + margin-bottom: 20px; +} + +.section-list-header { + color: var(--color-text-secondary); + padding: 12px 0; + text-align: center; + border-top: 1px solid var(--color-lines-light); + border-bottom: 1px solid var(--color-lines-light); +} +.section-list-header[data-section-name=adAttribution] { + padding-bottom: 4px; +} + +.icon-major-networks-blocked { + background-image: url("../../img/refresh-assets/Check-Color-16.svg"); +} + +.icon-major-networks-warning { + background-image: url("../../img/refresh-assets/Error-Color-16.svg"); +} + +.icon-major-networks-info { + background-image: url("../../img/status--info.svg"); +} + +.icon-major-networks-mixed { + background-image: url("../../img/refresh-assets/Stop-Grey-16.svg"); +} + +.site-info__tracker__icon { + border-radius: 50%; + overflow: hidden; + background-size: contain; + margin-right: 8px; +} +.site-info__tracker__icon.color-1 { + background-color: #94b3af; +} +.site-info__tracker__icon.color-2 { + background-color: #727998; +} +.site-info__tracker__icon.color-3 { + background-color: #645468; +} +.site-info__tracker__icon.color-4 { + background-color: #4d5f7f; +} +.site-info__tracker__icon.color-5 { + background-color: #855db6; +} +.site-info__tracker__icon.color-6 { + background-color: #5e5adb; +} +.site-info__tracker__icon.color-7 { + background-color: #678fff; +} +.site-info__tracker__icon.color-8 { + background-color: #6bb4ef; +} +.site-info__tracker__icon.color-9 { + background-color: #4a9bae; +} +.site-info__tracker__icon.color-10 { + background-color: #66c4c6; +} +.site-info__tracker__icon.color-11 { + background-color: #55d388; +} +.site-info__tracker__icon.color-12 { + background-color: #99db7a; +} +.site-info__tracker__icon.color-13 { + background-color: #eccc7b; +} +.site-info__tracker__icon.color-14 { + background-color: #e7a538; +} +.site-info__tracker__icon.color-15 { + background-color: #dd6b4c; +} +.site-info__tracker__icon.color-16 { + background-color: #d65d62; +} +.site-info__tracker__icon.A { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/A.svg"); +} +.site-info__tracker__icon.B { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/B.svg"); +} +.site-info__tracker__icon.C { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/C.svg"); +} +.site-info__tracker__icon.D { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/D.svg"); +} +.site-info__tracker__icon.E { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/E.svg"); +} +.site-info__tracker__icon.F { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/F.svg"); +} +.site-info__tracker__icon.G { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/G.svg"); +} +.site-info__tracker__icon.H { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/H.svg"); +} +.site-info__tracker__icon.I { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/I.svg"); +} +.site-info__tracker__icon.J { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/J.svg"); +} +.site-info__tracker__icon.K { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/K.svg"); +} +.site-info__tracker__icon.L { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/L.svg"); +} +.site-info__tracker__icon.M { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/M.svg"); +} +.site-info__tracker__icon.N { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/N.svg"); +} +.site-info__tracker__icon.O { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/O.svg"); +} +.site-info__tracker__icon.P { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/P.svg"); +} +.site-info__tracker__icon.Q { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/Q.svg"); +} +.site-info__tracker__icon.R { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/R.svg"); +} +.site-info__tracker__icon.S { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/S.svg"); +} +.site-info__tracker__icon.T { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/T.svg"); +} +.site-info__tracker__icon.U { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/U.svg"); +} +.site-info__tracker__icon.V { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/V.svg"); +} +.site-info__tracker__icon.W { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/W.svg"); +} +.site-info__tracker__icon.X { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/X.svg"); +} +.site-info__tracker__icon.Y { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/Y.svg"); +} +.site-info__tracker__icon.Z { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/letters/Z.svg"); +} +.site-info__tracker__icon.adjust { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/adjust.svg"); + background-color: transparent; +} +.site-info__tracker__icon.adobe { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/adobe.svg"); + background-color: transparent; +} +.site-info__tracker__icon.amazon { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/amazon.svg"); + background-color: transparent; +} +.site-info__tracker__icon.amplitude { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/amplitude.svg"); + background-color: transparent; +} +.site-info__tracker__icon.appnexus { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/appnexus.svg"); + background-color: transparent; +} +.site-info__tracker__icon.appsflyer { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/appsflyer.svg"); + background-color: transparent; +} +.site-info__tracker__icon.beeswax { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/beeswax.svg"); + background-color: transparent; +} +.site-info__tracker__icon.branchmetrics { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/branchmetrics.svg"); + background-color: transparent; +} +.site-info__tracker__icon.braze { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/braze.svg"); + background-color: transparent; +} +.site-info__tracker__icon.bugsnag { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/bugsnag.svg"); + background-color: transparent; +} +.site-info__tracker__icon.chartbeat { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/chartbeat.svg"); + background-color: transparent; +} +.site-info__tracker__icon.comscore { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/comscore.svg"); + background-color: transparent; +} +.site-info__tracker__icon.criteo { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/criteo.svg"); + background-color: transparent; +} +.site-info__tracker__icon.facebook { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/facebook.svg"); + background-color: transparent; +} +.site-info__tracker__icon.google { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/google.svg"); + background-color: transparent; +} +.site-info__tracker__icon.googleadsgoogle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg"); + background-color: transparent; +} +.site-info__tracker__icon.googleanalyticsgoogle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg"); + background-color: transparent; +} +.site-info__tracker__icon.indexexchange { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/indexexchange.svg"); + background-color: transparent; +} +.site-info__tracker__icon.iponweb { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/iponweb.svg"); + background-color: transparent; +} +.site-info__tracker__icon.instagramfacebook { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/instagramfacebook.svg"); + background-color: transparent; +} +.site-info__tracker__icon.kochava { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/kochava.svg"); + background-color: transparent; +} +.site-info__tracker__icon.linkedin { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/linkedin.svg"); + background-color: transparent; +} +.site-info__tracker__icon.liveramp { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/liveramp.svg"); + background-color: transparent; +} +.site-info__tracker__icon.mediamath { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/mediamath.svg"); + background-color: transparent; +} +.site-info__tracker__icon.microsoft { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/microsoft.svg"); + background-color: transparent; +} +.site-info__tracker__icon.mixpanel { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/mixpanel.svg"); + background-color: transparent; +} +.site-info__tracker__icon.neustar { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/neustar.svg"); + background-color: transparent; +} +.site-info__tracker__icon.newrelic { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/newrelic.svg"); + background-color: transparent; +} +.site-info__tracker__icon.openx { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/openx.svg"); + background-color: transparent; +} +.site-info__tracker__icon.oracle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/oracle.svg"); + background-color: transparent; +} +.site-info__tracker__icon.outbrain { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/outbrain.svg"); + background-color: transparent; +} +.site-info__tracker__icon.pinterest { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/pinterest.svg"); + background-color: transparent; +} +.site-info__tracker__icon.pubmatic { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/pubmatic.svg"); + background-color: transparent; +} +.site-info__tracker__icon.quantcast { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/quantcast.svg"); + background-color: transparent; +} +.site-info__tracker__icon.magnite { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/magnite.svg"); + background-color: transparent; +} +.site-info__tracker__icon.rythmone { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/rythmone.svg"); + background-color: transparent; +} +.site-info__tracker__icon.salesforce { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/salesforce.svg"); + background-color: transparent; +} +.site-info__tracker__icon.sharetrough { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/sharetrough.svg"); + background-color: transparent; +} +.site-info__tracker__icon.smaato { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/smaato.svg"); + background-color: transparent; +} +.site-info__tracker__icon.spotx { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/spotx.svg"); + background-color: transparent; +} +.site-info__tracker__icon.taboola { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/taboola.svg"); + background-color: transparent; +} +.site-info__tracker__icon.tapad { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/tapad.svg"); + background-color: transparent; +} +.site-info__tracker__icon.thenielsencompany { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/thenielsencompany.svg"); + background-color: transparent; +} +.site-info__tracker__icon.thetradedesk { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/thetradedesk.svg"); + background-color: transparent; +} +.site-info__tracker__icon.twitter { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/twitter.svg"); + background-color: transparent; +} +.site-info__tracker__icon.urbanairship { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/urbanairship.svg"); + background-color: transparent; +} +.site-info__tracker__icon.verizonmedia { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/verizonmedia.svg"); + background-color: transparent; +} +.site-info__tracker__icon.warnermedia { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/warnermedia.svg"); + background-color: transparent; +} +.site-info__tracker__icon.xaxis { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/xaxis.svg"); + background-color: transparent; +} +.site-info__tracker__icon.yahoojapan { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/yahoojapan.svg"); + background-color: transparent; +} +.site-info__tracker__icon.yandex { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/yandex.svg"); + background-color: transparent; +} +.site-info__tracker__icon.youtubegoogle { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/youtubegoogle.svg"); + background-color: transparent; +} +.site-info__tracker__icon.zeotap { + background-repeat: no-repeat; + background-size: cover; + display: inline-block; + width: 18px; + height: 18px; + vertical-align: middle; + background-image: url("../../img/refresh-assets/tracker-icons/logos/zeotap.svg"); + background-color: transparent; +} + +.site-info__tracker__icon--company { + width: 24px !important; + height: 24px !important; + flex-shrink: 0; +} + +.site-info__domain { + overflow: hidden; + text-overflow: ellipsis; + padding-right: 12px; + display: flex; + align-items: center; +} + +.site-info__trackers__company-list--bordered { + border-top: 1px solid var(--color-lines-light); +} + +.site-info__trackers__company-list-item { + margin-top: 16px; + margin-bottom: 16px; +} + +.site-info__trackers__company-list-item + .site-info__trackers__company-list-item { + padding-top: 16px; + border-top: 1px solid var(--color-lines-lighter); +} +.body--theme-dark .site-info__trackers__company-list-item + .site-info__trackers__company-list-item { + border-top: 1px solid rgba(255, 255, 255, 0.06); +} + +.site-info__trackers__company-list__url-list .url-list-item { + display: flex; + margin-top: 8px; + align-items: baseline; +} +.site-info__trackers__company-list__url-list .url { + width: 100%; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + direction: rtl; + padding-right: 10px; + line-height: 18px; +} +.site-info__trackers__company-list__url-list .category { + padding: 1px 8px; + border-radius: 33px; + color: var(--color-text-secondary); + background-color: var(--color-lines-lighter); + white-space: nowrap; + text-align: right; +} + +.page-connection__certificate-value { + text-align: right; + color: #666; +} +.body--theme-dark .page-connection__certificate-value { + color: #aaa; +} + +.page-connection__certificate-details { + padding: 18px 0; +} +.page-connection__certificate-details h3 { + color: #111111; + margin-bottom: 14px; +} +.body--theme-dark .page-connection__certificate-details h3 { + color: rgba(255, 255, 255, 0.9); +} +.page-connection__certificate-details > div { + color: #333333; + display: flex; + margin-top: 6px; + justify-content: space-between; +} +.body--theme-dark .page-connection__certificate-details > div { + color: rgba(255, 255, 255, 0.9); +} +.page-connection__certificate-details + .page-connection__certificate-details { + border-top: 1px solid var(--color-lines-lighter); +} +.body--theme-dark .page-connection__certificate-details + .page-connection__certificate-details { + border-top: 1px solid var(--color-lines-lighter); +} + +.environment--browser .breakage-form { + padding-bottom: 0; +} + +.breakage-form__content { + z-index: 1; + position: relative; + text-align: center; +} +[data-state=sent] .breakage-form__content { + display: none; +} + +.breakage-form__close-container { + top: 13px; + right: 15px; + position: absolute; +} + +.form__icon--wrapper { + padding-bottom: 5px; + margin: 0 20px; + position: relative; +} + +.breakage-form__element { + display: flex; + flex-direction: column; + gap: 24px; + opacity: 1; + transition: all 0.2s ease-in-out; +} +.breakage-form__element.is-transparent { + opacity: 0; + max-height: 0; + overflow: hidden; +} + +.breakage-form__title { + padding: 5px 0 0; +} + +.breakage-form__advise { + display: none; +} +[data-state=idle] .breakage-form__advise { + display: block; +} + +.form__label__select { + display: block; + text-align: left; +} + +.form__group { + display: flex; + flex-direction: column; + gap: 16px; +} + +.form__select { + width: 100%; +} + +.form__select select { + cursor: pointer; + display: block; + width: 100%; + min-height: 20px; + border: 1px solid var(--color-lines-light); + border-radius: 4px; +} +.environment--ios .form__select select { + height: 34px; +} +.environment--windows .form__select select { + min-height: 34px; +} + +.form__textarea { + resize: none; + width: 100%; + height: 88px; + display: block; + box-sizing: border-box; + padding: var(--size-unit-half) var(--size-unit); + border: 1px solid var(--color-lines-light); + border-radius: 4px; + font-size: 13px; + line-height: 16px; +} +.form__textarea::placeholder { + color: rgba(0, 0, 0, 0.6); +} +.body--theme-dark .form__textarea { + background-color: rgba(255, 255, 255, 0.12); + border-color: var(--color-lines-light); +} +.body--theme-dark .form__textarea::placeholder { + color: rgba(255, 255, 255, 0.6); +} +.environment--macos .form__textarea { + height: 102px; +} +.environment--windows .form__textarea { + height: 102px; + line-height: 20px; +} + +.form__submit { + text-align: center; + padding: 10px 12px; + cursor: pointer; + display: block; + text-decoration: none; + width: 100%; + box-shadow: var(--btn-accent-shadow); + border-radius: var(--btn-accent-border-radius); + border: var(--btn-accent-border); + color: var(--btn-accent-color); + background: var(--btn-accent-bg); + /* https://www.figma.com/file/DBZiXJRgTTJTuBeWAPyE5h/Desktop-Components?node-id=9113%3A130956&t=de8DMDVt8GbRBQub-0 */ +} +.form__submit:hover { + background: var(--btn-accent-bg-hover); +} +.form__submit:active { + background: var(--btn-accent-bg-active); +} +.environment--windows .form__submit { + /* Windows/Label */ + box-shadow: none; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 19px; + border-radius: 4px; +} +.environment--windows .form__submit:focus { + /* todo(Shane): where does this live? */ + box-shadow: 0px 0px 0px 1px #ffffff, 0px 0px 0px 3px #3969ef; +} +.environment--windows .form__submit:active { + box-shadow: none; +} + +.breakage-form__footer { + padding-bottom: 24px; + padding-top: 24px; + text-align: center; +} +.body--theme-dark .breakage-form__footer { + color: rgba(255, 255, 255, 0.5); +} +.environment--browser .breakage-form__footer { + margin-top: auto; +} +[data-state=sent] .breakage-form__footer { + display: none; +} + +.breakage-form__inner { + height: calc(100% - var(--nav-height)); + display: flex; + flex-direction: column; +} + +.thanks { + text-align: center; + padding-bottom: 20px; + transition: all 0.2s ease-in-out; + opacity: 1; + display: none; +} +[data-state=sent] .thanks { + display: block; +} + +.thanks__primary { + font-size: 15px; + font-style: normal; + font-weight: 800; + line-height: 20px; /* 133.333% */ + margin-bottom: 8px; +} +.environment--macos .thanks__primary, .environment--macos .thanks__primary { + font-size: 17px; + font-style: normal; + font-weight: 600; + line-height: 22px; /* 129.412% */ +} + +.thanks__secondary { + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 20px; +} +.environment--macos .thanks__secondary { + font-size: 15px; + font-style: normal; + font-weight: 400; + line-height: 20px; +} + +/* Android-specific styles */ +.environment--android { + --btn-accent-bg: #3969ef; + --btn-accent-bg-hover: #1e42a4; + --btn-accent-bg-active: #1e42a4; + --btn-accent-color: #fff; + --form-select-bg: none; + --form-select-color: rgba(0, 0, 0, 0.6); + --form-select-border-color: rgba(0, 0, 0, 0.3); + --form-select-chevron: url("../../img/refresh-assets/chevron.svg"); + /** + * prevent the empty element from taking any screen height + */ +} +.environment--android ddg-android-breakage-dialog { + position: absolute; +} +.environment--android .breakage-form .form__submit { + height: calc(var(--size-unit) * 3); +} +.environment--android .breakage-form .breakage-form__input--dropdown { + position: relative; +} +.environment--android .breakage-form .breakage-form__input--dropdown select { + appearance: none; + background: var(--form-select-bg); + border: 1px solid var(--form-select-border-color); + border-radius: var(--size-unit-half); + color: var(--form-select-color); + font-size: var(--size-unit); + padding: var(--size-unit); +} +.environment--android .breakage-form .breakage-form__input--dropdown::after { + content: ""; + position: absolute; + right: var(--size-unit); + top: calc(1.25 * var(--size-unit)); + background-image: var(--form-select-chevron); + width: 8px; + height: 14px; + transform: rotate(90deg); + opacity: 0.75; +} +.environment--android .breakage-form textarea { + border-radius: var(--size-unit-half); + border-color: var(--form-select-border-color); + font-size: var(--size-unit); + line-height: 1.25; + height: calc(var(--size-unit) * 7); + padding: var(--size-unit); + background: none; +} +.environment--android .breakage-form .breakage-form__content.padding-x-double { + padding-left: var(--size-unit); + padding-right: var(--size-unit); +} +.environment--android.body--theme-dark { + --btn-accent-bg: #7295f6; + --btn-accent-bg-hover: #3969ef; + --btn-accent-bg-active: #3969ef; + --btn-accent-color: rgba(0, 0, 0, 0.84); + --form-select-color: rgba(255, 255, 255, 0.9); + --form-select-border-color: rgba(255, 255, 255, 0.3); + --form-select-chevron: url("../../img/refresh-assets/chevron--light.svg"); +} + +.email-alias { + margin-bottom: var(--size-unit); +} + +.email-alias__button { + display: block; + padding: 5px 10px; + background: var(--color-lines-lighter); + border: 1px solid transparent; + width: 100%; + border-radius: 8px; + vertical-align: middle; +} +.email-alias__button svg { + vertical-align: middle; + position: relative; + top: -1px; + left: -4px; +} +.email-alias__button svg path { + fill: currentColor; +} +.email-alias__button:hover, .email-alias__button:focus, .email-alias__button:active { + background: var(--color-lines-light); +} +.email-alias__button[data-state=added] { + background: white; + border-color: var(--color-lines-lighter); +} +.body--theme-dark .email-alias__button { + border: 1px solid transparent; +} +.body--theme-dark .email-alias__button:hover, .body--theme-dark .email-alias__button:focus, .body--theme-dark .email-alias__button:active { + background: rgba(255, 255, 255, 0.25); +} +.body--theme-dark .email-alias__button[data-state=added] { + border: 1px solid rgba(255, 255, 255, 0.18); + background: transparent; +} + +.cta-screen { + padding-top: 24px; +} + +.cta { + max-width: 85%; + margin: 0 auto; + margin-top: 32px; +} + +.cta__icon { + width: 100px; + height: 100px; + margin-left: auto; + margin-right: auto; + display: flex; + justify-content: center; + align-items: center; +} + +.cta__title { + font-size: 16px; + line-height: 20px; + margin-top: 14px; +} + +.cta__text { + font-size: 16px; + line-height: 22px; + font-weight: normal; + margin-top: 2px; +} + +.cta__action { + text-align: center; + margin-top: 22px; +} + +.cta__button { + display: inline-block; + background: var(--color-accent-blue); + border-radius: 8px; + padding: 10px 16px; + max-width: 250px; + font-style: normal; + font-weight: 600; + font-size: 13px; + line-height: 14px; + color: #ffffff; +} +.cta__button:hover, .cta__button:focus { + background-color: #2950bf; + text-decoration: none; +} +.body--theme-dark .cta__button { + color: #222222; +} +.body--theme-dark .cta__button:hover, .body--theme-dark .cta__button:focus { + background-color: #4271f3; + text-decoration: none; +} + +.note { + background: #fff0c2; + border-radius: 12px; + padding: 12px 16px; +} +.body--theme-dark .note { + background: rgba(255, 222, 122, 0.18); +} + +.note--nested { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.note--nested--alt { + background: #ccdaff; +} +.body--theme-dark .note--nested--alt { + background: rgba(85, 127, 243, 0.18); +} + +.note--key-insight { + margin-top: 12px; + margin-left: -16px; + margin-right: -16px; +} + +#fire-button-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 100; + background-color: rgba(0, 0, 0, 0.6); + border: 0px; + color: rgba(0, 0, 0, 0.84); +} +.body--theme-dark #fire-button-container { + color: rgba(255, 255, 255, 0.84); +} + +#fire-button-header { + font-weight: 600; + font-size: 17px; + text-align: center; + padding-bottom: 4px; +} + +#fire-button-content { + box-sizing: border-box; + /* Auto layout */ + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 16px; + gap: 12px; + background: #ffffff; + /* Tints-Shades/Shade 12% */ + border: 1px solid rgba(0, 0, 0, 0.12); + /* Shadows/On Light/Elevation 90 */ + box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1), 0px 20px 40px rgba(0, 0, 0, 0.08); + border-radius: 16px; +} +.body--theme-dark #fire-button-content { + background-color: #333333; + border: 1px solid rgba(255, 255, 255, 0.12); +} + +#fire-button-burn { + background: #3969ef; + color: #fff; + font-weight: 600; + font-size: 15px; + line-height: 16px; +} +.body--theme-dark #fire-button-burn { + background: #7295f6; + color: rgba(0, 0, 0, 0.84); +} +#fire-button-burn:hover { + background: #2b55ca; +} +#fire-button-burn:active { + background: #1e42a4; +} + +#fire-button-cancel { + font-weight: 600; + font-size: 15px; + line-height: 16px; + background-color: rgba(0, 0, 0, 0.06); +} +.body--theme-dark #fire-button-cancel { + background-color: rgba(0, 0, 0, 0.18); +} +.body--theme-dark #fire-button-cancel:hover { + background: rgba(0, 0, 0, 0.09); +} +#fire-button-cancel:hover { + background: rgba(0, 0, 0, 0.03); +} +#fire-button-cancel:active { + background: rgba(0, 0, 0, 0.06); +} + +#fire-button-row { + display: flex; + justify-content: center; + align-items: center; + gap: 12px; + align-self: stretch; +} + +#fire-button-row > button { + display: flex; + height: 40px; + justify-content: center; + align-items: center; + gap: 10px; + flex: 1 0 0; + border-radius: 8px; +} + +#fire-button-summary { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 12px; + padding-top: 4px; + padding-bottom: 4px; +} + +#fire-button-summary .fire-button-disclaimer { + font-size: 15px; +} + +#fire-button-summary p { + text-align: center; + font-weight: 400; + font-size: 15px; + line-height: 22px; +} + +#fire-button-opts { + width: 100%; + height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + border-radius: 8px; + display: inline-block; + position: relative; + overflow: hidden; + line-height: 2.2; + border: 1px solid #ddd; + background-color: #fafafa; + color: #333; + padding: 0 32px 0 0.75em; + vertical-align: middle; + margin-bottom: 0; + cursor: pointer; + -webkit-appearance: none !important; + -moz-appearance: none !important; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACVSURBVHgB7dXtCYAgEMbxq0ZqjtZwqBZomVqgaepAQUTzzrcvPT8QP+TRHyEiAgAA+L3NrlFz6pecdhnFnPHmqiJnxVlDskjpOZEl8/y2+xrsV+J8GLe/66AKuUA/JhcZi9upkiTQj0lFdolj0kA/Zo3sXeLYRHpfH0HTOKa5QSe8Sad5HCsJZGFkl7gWhvwtAAAAyj31qB2UieFidQAAAABJRU5ErkJggg==); + background-position: 100%; + background-repeat: no-repeat; + background-size: 20px; +} +#fire-button-opts:hover { + background-color: #fff; +} +#fire-button-opts select { + -webkit-appearance: none; + -moz-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + background: none; + cursor: pointer; + margin: 0; + padding: 0 32px 0 0.75em; + position: relative; + display: block; + font-size: 1em; + line-height: inherit; + min-width: 10em; + width: 140% !important; + height: 2.2em !important; + outline: none !important; + border: none !important; +} +@media (prefers-color-scheme: dark) { + #fire-button-opts { + border: 1px solid #444; + background-color: #333; + color: #fafafa; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACFSURBVHgB7dVdCoAgEATg3e7XNTxUZ+pOxoIPJf3suGYPzQcSxC6OoihCRET0bznn2YaAWvtaJlnLSEBf2vWFQk5AbfKELDXuxYRVu3G7k0jt8JCfhfMEeDOcIsUn52sp38M/VV2kEyigebgEXcMZOKC5CNk9XEh17sZeCK8hrwUREVHIBuQ4wvCLsemUAAAAAElFTkSuQmCC); + } + #fire-button-opts:hover { + background-color: #444; + } +} + +.protection-toggle__row { + padding: 12px; +} +.environment--browser .protection-toggle__row { + padding-top: 11px; + padding-bottom: 11px; +} +.environment--ios .protection-toggle__row { + padding: 8.5px 16px; + font-size: 15px; + font-style: normal; + font-weight: 400; + line-height: 20px; +} +.environment--android .protection-toggle__row { + padding: 8.5px 16px; + font-size: 15px; + font-style: normal; + font-weight: 400; + line-height: 20px; +} +.environment--windows .protection-toggle__row { + padding: 10px 16px; + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 24px; +} +.environment--macos .protection-toggle__row { + padding-top: 13px; + padding-bottom: 13px; +} + +.protection-toggle__row--alt { + background: #ccdaff; +} +.body--theme-dark .protection-toggle__row--alt { + background: rgba(85, 127, 243, 0.18); +} +.environment--ios .protection-toggle__row--alt { + padding: 12px 16px; +} +.environment--android .protection-toggle__row--alt { + padding: 12px 16px; +} + +/* Generic menu list styling */ +.default-list { + list-style-type: none; + padding-left: 0; + margin-top: 0; +} +.default-list li .icon__arrow { + right: 15px; + top: calc(50% - 6px); +} +.environment--browser .default-list li .icon__arrow { + right: 10px; +} + +/* Sliding subviews */ +.sliding-subview { + position: absolute; + top: 0; + left: 100%; + width: 100%; + height: 100%; + box-sizing: border-box; +} +.sliding-subview.sliding-subview--root { + position: relative; + top: 0; + left: 0; + transition: left 0.3s ease-in-out; +} +.sliding-subview.sliding-subview--root.sliding-subview--immediate { + transition: none; +} +.sliding-subview.sliding-subview--root.sliding-subview--open { + left: -100%; +} + +/* Sliding subviews */ +.sliding-subview-v2 { + position: absolute; + top: 0; + width: var(--width); + height: var(--height); + box-sizing: border-box; +} +.sliding-subview-v2:not(.sliding-subview-v2--root) { + overflow-y: auto; +} + +.sliding-subview-v2--root { + position: absolute; + top: 0; + left: 0; +} + +.sliding-subview-v2--animating { + transition: transform 0.3s ease-in-out; +} + +.platform-limitations { + padding: 16px 0; + text-align: center; +} + +.button[data-size=small] { + line-height: 13px; + height: 20px; + padding: 0px 12px; + border-radius: 5px; +} +.button[data-size=big] { + height: 50px; + padding: 0px 24px; + /* Button */ + font-size: 15px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 133.333% */ +} +.button[data-size=desktop-large] { + height: 29px; + padding: 0px 12px; +} +.button[data-variant=desktop-standard] { + background: rgba(0, 0, 0, 0.06); + border-radius: 6px; + color: rgba(0, 0, 0, 0.84); +} +.button[data-variant=desktop-standard]:hover { + background: rgba(0, 0, 0, 0.09); +} +.button[data-variant=desktop-standard]:active { + background: rgba(0, 0, 0, 0.12); +} +.button[data-variant=desktop-standard]:disabled { + opacity: 0.8; +} +.body--theme-dark .button[data-variant=desktop-standard] { + background: rgba(255, 255, 255, 0.12); + color: rgba(255, 255, 255, 0.84); +} +.body--theme-dark .button[data-variant=desktop-standard]:hover { + background: rgba(255, 255, 255, 0.18); +} +.body--theme-dark .button[data-variant=desktop-standard]:active { + background: rgba(255, 255, 255, 0.24); +} +.button[data-variant=desktop-standard][data-size=desktop-large] { + font-size: 14px; + font-weight: 400; + height: 40px; + padding: 0 16px; +} +.button[data-variant=desktop-vibrancy] { + border-radius: 6px; + background: rgba(0, 0, 0, 0.1); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); +} +.button[data-variant=desktop-vibrancy]:active { + border-radius: 6px; + background: rgba(0, 0, 0, 0.2); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); +} +.body--theme-dark .button[data-variant=desktop-vibrancy] { + border-radius: 6px; + background: rgba(255, 255, 255, 0.28); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); +} +.body--theme-dark .button[data-variant=desktop-vibrancy]:active { + border-radius: 6px; + background: rgba(255, 255, 255, 0.35); + /* Mac/Control/Vibrant */ + box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); +} +.button[data-variant=ios-secondary] { + justify-content: center; + align-items: center; + gap: 8px; + flex-shrink: 0; + border-radius: 8px; + border: 1px solid var(--color-accent-blue); + color: var(--color-accent-blue); + text-align: center; + background: transparent; +} +.button[data-variant=ios-secondary]:active { + background: rgba(57, 105, 239, 0.2); + color: var(--color-accent-blue-active); +} + +.button-bar[data-layout=horizontal] { + display: grid; + gap: 12px; + grid-template-columns: 1fr 1fr; +} +.button-bar[data-layout=vertical] { + display: flex; + gap: 12px; + flex-direction: column; +} +.button-bar[data-layout=vertical] > * { + width: 100%; +} +.environment--android .button-bar[data-layout=vertical] { + gap: 8px; +} + +.text-link-as-button:hover { + text-decoration: underline; +} +.text-link-as-button:active { + text-decoration: none; +} + +.stack { + display: flex; + flex-direction: column; + gap: 24px; + width: 100%; +} +.stack[data-debug=true] > * { + outline: 1px dotted black; +} + +.scrollable { + height: 280px; + overflow-y: scroll; + border-radius: 6px; + border: 1px solid rgba(0, 0, 0, 0.1); + /* NOTE: this is not using alpha because the custom scrollbars need to stack */ + background: rgb(252, 252, 252); + padding: 16px 20px 20px 16px; +} +.body--theme-dark .scrollable { + /* NOTE: this is not using alpha because the custom scrollbars need to stack */ + background: rgb(57, 57, 57); + border-color: rgba(255, 255, 255, 0.09); +} + +.data-list__content { + font-size: 14px; + font-weight: 400; + line-height: 1.4285714286; +} +.environment--android .data-list__content { + font-size: 14px; + font-weight: 400; + line-height: 1.2857142857; +} +.environment--ios .data-list__content, .environment--macos .data-list__content { + font-size: 13px; + font-weight: 400; + line-height: 1.3846153846; +} +.environment--android .data-list__content--breakage, .environment--browser .data-list__content--breakage, .environment--ios .data-list__content--breakage, .environment--macos .data-list__content--breakage, .environment--windows .data-list__content--breakage { + font-size: 13px; + line-height: 1.3846153846; +} + +.data-list__heading { + font-weight: 600; +} +.environment--android .data-list__heading { + font-weight: 700; +} + +.data-list { + list-style: none; +} + +.data-list__item { + word-wrap: anywhere; + color: var(--color-text-secondary); + position: relative; + padding-left: 20px; +} +.data-list__item + .data-list__item { + margin-top: 3px; +} + +.data-list__item::before { + content: "•"; + font-size: 12px; + position: absolute; + left: 8px; + top: 8px; + transform: translateY(-50%); + color: currentColor; +} + +.ios-separator { + padding-top: 16px; + border-top: 1px solid var(--color-system-lines); +} + +.fade-in { + opacity: 0; + visibility: hidden; + animation-name: fade-in; + animation-fill-mode: forwards; + animation-duration: 1s; +} + +@keyframes fade-in { + from { + opacity: 0; + visibility: hidden; + } + to { + opacity: 1; + visibility: visible; + } +} +.environment--macos .toggle-report[data-opener=dashboard] .top-nav { + opacity: 0; + visibility: hidden; +} + +.environment--ios [data-toggle-report=child], +.environment--android [data-toggle-report=child] { + opacity: 0; + visibility: hidden; +} + +.environment--ios [data-toggle-report=child][data-ready=true], +.environment--android [data-toggle-report=child][data-ready=true] { + opacity: 1; + visibility: visible; +} + +.toggle-report__heading { + margin-bottom: 24px; +} + +.toggle-report__scroller { + margin-bottom: 16px; +} +.toggle-report__scroller .scrollable::-webkit-scrollbar { + width: 14px; +} +.toggle-report__scroller .scrollable::-webkit-scrollbar-track { + border-radius: 6px; +} +.toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.1); + /* NOTE: this is not using alpha because the custom scrollbars need to stack */ + border: 2px solid rgb(252, 252, 252); + border-radius: 6px; +} +.body--theme-dark .toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { + /* NOTE: this is not using alpha because the custom scrollbars need to stack */ + border-color: rgb(57, 57, 57); + background: rgba(0, 0, 0, 0.3); +} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js new file mode 100644 index 000000000000..1900913d49e9 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js @@ -0,0 +1,5042 @@ +"use strict"; +(() => { + var __defProp = Object.defineProperty; + var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; + var __publicField = (obj, key, value) => { + __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); + return value; + }; + + // node_modules/@lit/reactive-element/css-tag.js + var t = globalThis; + var e = t.ShadowRoot && (void 0 === t.ShadyCSS || t.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype; + var s = Symbol(); + var o = /* @__PURE__ */ new WeakMap(); + var n = class { + constructor(t4, e6, o5) { + if (this._$cssResult$ = true, o5 !== s) + throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); + this.cssText = t4, this.t = e6; + } + get styleSheet() { + let t4 = this.o; + const s2 = this.t; + if (e && void 0 === t4) { + const e6 = void 0 !== s2 && 1 === s2.length; + e6 && (t4 = o.get(s2)), void 0 === t4 && ((this.o = t4 = new CSSStyleSheet()).replaceSync(this.cssText), e6 && o.set(s2, t4)); + } + return t4; + } + toString() { + return this.cssText; + } + }; + var r = (t4) => new n("string" == typeof t4 ? t4 : t4 + "", void 0, s); + var i = (t4, ...e6) => { + const o5 = 1 === t4.length ? t4[0] : e6.reduce((e7, s2, o6) => e7 + ((t5) => { + if (true === t5._$cssResult$) + return t5.cssText; + if ("number" == typeof t5) + return t5; + throw Error("Value passed to 'css' function must be a 'css' function result: " + t5 + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); + })(s2) + t4[o6 + 1], t4[0]); + return new n(o5, t4, s); + }; + var S = (s2, o5) => { + if (e) + s2.adoptedStyleSheets = o5.map((t4) => t4 instanceof CSSStyleSheet ? t4 : t4.styleSheet); + else + for (const e6 of o5) { + const o6 = document.createElement("style"), n5 = t.litNonce; + void 0 !== n5 && o6.setAttribute("nonce", n5), o6.textContent = e6.cssText, s2.appendChild(o6); + } + }; + var c = e ? (t4) => t4 : (t4) => t4 instanceof CSSStyleSheet ? ((t5) => { + let e6 = ""; + for (const s2 of t5.cssRules) + e6 += s2.cssText; + return r(e6); + })(t4) : t4; + + // node_modules/@lit/reactive-element/reactive-element.js + var { is: i2, defineProperty: e2, getOwnPropertyDescriptor: r2, getOwnPropertyNames: h, getOwnPropertySymbols: o2, getPrototypeOf: n2 } = Object; + var a = globalThis; + var c2 = a.trustedTypes; + var l = c2 ? c2.emptyScript : ""; + var p = a.reactiveElementPolyfillSupport; + var d = (t4, s2) => t4; + var u = { toAttribute(t4, s2) { + switch (s2) { + case Boolean: + t4 = t4 ? l : null; + break; + case Object: + case Array: + t4 = null == t4 ? t4 : JSON.stringify(t4); + } + return t4; + }, fromAttribute(t4, s2) { + let i4 = t4; + switch (s2) { + case Boolean: + i4 = null !== t4; + break; + case Number: + i4 = null === t4 ? null : Number(t4); + break; + case Object: + case Array: + try { + i4 = JSON.parse(t4); + } catch (t5) { + i4 = null; + } + } + return i4; + } }; + var f = (t4, s2) => !i2(t4, s2); + var y = { attribute: true, type: String, converter: u, reflect: false, hasChanged: f }; + Symbol.metadata ??= Symbol("metadata"), a.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap(); + var b = class extends HTMLElement { + static addInitializer(t4) { + this._$Ei(), (this.l ??= []).push(t4); + } + static get observedAttributes() { + return this.finalize(), this._$Eh && [...this._$Eh.keys()]; + } + static createProperty(t4, s2 = y) { + if (s2.state && (s2.attribute = false), this._$Ei(), this.elementProperties.set(t4, s2), !s2.noAccessor) { + const i4 = Symbol(), r5 = this.getPropertyDescriptor(t4, i4, s2); + void 0 !== r5 && e2(this.prototype, t4, r5); + } + } + static getPropertyDescriptor(t4, s2, i4) { + const { get: e6, set: h4 } = r2(this.prototype, t4) ?? { get() { + return this[s2]; + }, set(t5) { + this[s2] = t5; + } }; + return { get() { + return e6?.call(this); + }, set(s3) { + const r5 = e6?.call(this); + h4.call(this, s3), this.requestUpdate(t4, r5, i4); + }, configurable: true, enumerable: true }; + } + static getPropertyOptions(t4) { + return this.elementProperties.get(t4) ?? y; + } + static _$Ei() { + if (this.hasOwnProperty(d("elementProperties"))) + return; + const t4 = n2(this); + t4.finalize(), void 0 !== t4.l && (this.l = [...t4.l]), this.elementProperties = new Map(t4.elementProperties); + } + static finalize() { + if (this.hasOwnProperty(d("finalized"))) + return; + if (this.finalized = true, this._$Ei(), this.hasOwnProperty(d("properties"))) { + const t5 = this.properties, s2 = [...h(t5), ...o2(t5)]; + for (const i4 of s2) + this.createProperty(i4, t5[i4]); + } + const t4 = this[Symbol.metadata]; + if (null !== t4) { + const s2 = litPropertyMetadata.get(t4); + if (void 0 !== s2) + for (const [t5, i4] of s2) + this.elementProperties.set(t5, i4); + } + this._$Eh = /* @__PURE__ */ new Map(); + for (const [t5, s2] of this.elementProperties) { + const i4 = this._$Eu(t5, s2); + void 0 !== i4 && this._$Eh.set(i4, t5); + } + this.elementStyles = this.finalizeStyles(this.styles); + } + static finalizeStyles(s2) { + const i4 = []; + if (Array.isArray(s2)) { + const e6 = new Set(s2.flat(1 / 0).reverse()); + for (const s3 of e6) + i4.unshift(c(s3)); + } else + void 0 !== s2 && i4.push(c(s2)); + return i4; + } + static _$Eu(t4, s2) { + const i4 = s2.attribute; + return false === i4 ? void 0 : "string" == typeof i4 ? i4 : "string" == typeof t4 ? t4.toLowerCase() : void 0; + } + constructor() { + super(), this._$Ep = void 0, this.isUpdatePending = false, this.hasUpdated = false, this._$Em = null, this._$Ev(); + } + _$Ev() { + this._$ES = new Promise((t4) => this.enableUpdating = t4), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t4) => t4(this)); + } + addController(t4) { + (this._$EO ??= /* @__PURE__ */ new Set()).add(t4), void 0 !== this.renderRoot && this.isConnected && t4.hostConnected?.(); + } + removeController(t4) { + this._$EO?.delete(t4); + } + _$E_() { + const t4 = /* @__PURE__ */ new Map(), s2 = this.constructor.elementProperties; + for (const i4 of s2.keys()) + this.hasOwnProperty(i4) && (t4.set(i4, this[i4]), delete this[i4]); + t4.size > 0 && (this._$Ep = t4); + } + createRenderRoot() { + const t4 = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); + return S(t4, this.constructor.elementStyles), t4; + } + connectedCallback() { + this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(true), this._$EO?.forEach((t4) => t4.hostConnected?.()); + } + enableUpdating(t4) { + } + disconnectedCallback() { + this._$EO?.forEach((t4) => t4.hostDisconnected?.()); + } + attributeChangedCallback(t4, s2, i4) { + this._$AK(t4, i4); + } + _$EC(t4, s2) { + const i4 = this.constructor.elementProperties.get(t4), e6 = this.constructor._$Eu(t4, i4); + if (void 0 !== e6 && true === i4.reflect) { + const r5 = (void 0 !== i4.converter?.toAttribute ? i4.converter : u).toAttribute(s2, i4.type); + this._$Em = t4, null == r5 ? this.removeAttribute(e6) : this.setAttribute(e6, r5), this._$Em = null; + } + } + _$AK(t4, s2) { + const i4 = this.constructor, e6 = i4._$Eh.get(t4); + if (void 0 !== e6 && this._$Em !== e6) { + const t5 = i4.getPropertyOptions(e6), r5 = "function" == typeof t5.converter ? { fromAttribute: t5.converter } : void 0 !== t5.converter?.fromAttribute ? t5.converter : u; + this._$Em = e6, this[e6] = r5.fromAttribute(s2, t5.type), this._$Em = null; + } + } + requestUpdate(t4, s2, i4) { + if (void 0 !== t4) { + if (i4 ??= this.constructor.getPropertyOptions(t4), !(i4.hasChanged ?? f)(this[t4], s2)) + return; + this.P(t4, s2, i4); + } + false === this.isUpdatePending && (this._$ES = this._$ET()); + } + P(t4, s2, i4) { + this._$AL.has(t4) || this._$AL.set(t4, s2), true === i4.reflect && this._$Em !== t4 && (this._$Ej ??= /* @__PURE__ */ new Set()).add(t4); + } + async _$ET() { + this.isUpdatePending = true; + try { + await this._$ES; + } catch (t5) { + Promise.reject(t5); + } + const t4 = this.scheduleUpdate(); + return null != t4 && await t4, !this.isUpdatePending; + } + scheduleUpdate() { + return this.performUpdate(); + } + performUpdate() { + if (!this.isUpdatePending) + return; + if (!this.hasUpdated) { + if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) { + for (const [t6, s3] of this._$Ep) + this[t6] = s3; + this._$Ep = void 0; + } + const t5 = this.constructor.elementProperties; + if (t5.size > 0) + for (const [s3, i4] of t5) + true !== i4.wrapped || this._$AL.has(s3) || void 0 === this[s3] || this.P(s3, this[s3], i4); + } + let t4 = false; + const s2 = this._$AL; + try { + t4 = this.shouldUpdate(s2), t4 ? (this.willUpdate(s2), this._$EO?.forEach((t5) => t5.hostUpdate?.()), this.update(s2)) : this._$EU(); + } catch (s3) { + throw t4 = false, this._$EU(), s3; + } + t4 && this._$AE(s2); + } + willUpdate(t4) { + } + _$AE(t4) { + this._$EO?.forEach((t5) => t5.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t4)), this.updated(t4); + } + _$EU() { + this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = false; + } + get updateComplete() { + return this.getUpdateComplete(); + } + getUpdateComplete() { + return this._$ES; + } + shouldUpdate(t4) { + return true; + } + update(t4) { + this._$Ej &&= this._$Ej.forEach((t5) => this._$EC(t5, this[t5])), this._$EU(); + } + updated(t4) { + } + firstUpdated(t4) { + } + }; + b.elementStyles = [], b.shadowRootOptions = { mode: "open" }, b[d("elementProperties")] = /* @__PURE__ */ new Map(), b[d("finalized")] = /* @__PURE__ */ new Map(), p?.({ ReactiveElement: b }), (a.reactiveElementVersions ??= []).push("2.0.4"); + + // node_modules/lit-html/lit-html.js + var n3 = globalThis; + var c3 = n3.trustedTypes; + var h2 = c3 ? c3.createPolicy("lit-html", { createHTML: (t4) => t4 }) : void 0; + var f2 = "$lit$"; + var v = `lit$${Math.random().toFixed(9).slice(2)}$`; + var m = "?" + v; + var _ = `<${m}>`; + var w = document; + var lt = () => w.createComment(""); + var st = (t4) => null === t4 || "object" != typeof t4 && "function" != typeof t4; + var g = Array.isArray; + var $ = (t4) => g(t4) || "function" == typeof t4?.[Symbol.iterator]; + var x = "[ \n\f\r]"; + var T = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g; + var E = /-->/g; + var k = />/g; + var O = RegExp(`>|${x}(?:([^\\s"'>=/]+)(${x}*=${x}*(?:[^ +\f\r"'\`<>=]|("|')|))|$)`, "g"); + var S2 = /'/g; + var j = /"/g; + var M = /^(?:script|style|textarea|title)$/i; + var P = (t4) => (i4, ...s2) => ({ _$litType$: t4, strings: i4, values: s2 }); + var ke = P(1); + var Oe = P(2); + var Se = P(3); + var R = Symbol.for("lit-noChange"); + var D = Symbol.for("lit-nothing"); + var V = /* @__PURE__ */ new WeakMap(); + var I = w.createTreeWalker(w, 129); + function N(t4, i4) { + if (!g(t4) || !t4.hasOwnProperty("raw")) + throw Error("invalid template strings array"); + return void 0 !== h2 ? h2.createHTML(i4) : i4; + } + var U = (t4, i4) => { + const s2 = t4.length - 1, e6 = []; + let h4, o5 = 2 === i4 ? "" : 3 === i4 ? "" : "", n5 = T; + for (let i5 = 0; i5 < s2; i5++) { + const s3 = t4[i5]; + let r5, l2, c4 = -1, a2 = 0; + for (; a2 < s3.length && (n5.lastIndex = a2, l2 = n5.exec(s3), null !== l2); ) + a2 = n5.lastIndex, n5 === T ? "!--" === l2[1] ? n5 = E : void 0 !== l2[1] ? n5 = k : void 0 !== l2[2] ? (M.test(l2[2]) && (h4 = RegExp("" === l2[0] ? (n5 = h4 ?? T, c4 = -1) : void 0 === l2[1] ? c4 = -2 : (c4 = n5.lastIndex - l2[2].length, r5 = l2[1], n5 = void 0 === l2[3] ? O : '"' === l2[3] ? j : S2) : n5 === j || n5 === S2 ? n5 = O : n5 === E || n5 === k ? n5 = T : (n5 = O, h4 = void 0); + const u2 = n5 === O && t4[i5 + 1].startsWith("/>") ? " " : ""; + o5 += n5 === T ? s3 + _ : c4 >= 0 ? (e6.push(r5), s3.slice(0, c4) + f2 + s3.slice(c4) + v + u2) : s3 + v + (-2 === c4 ? i5 : u2); + } + return [N(t4, o5 + (t4[s2] || "") + (2 === i4 ? "" : 3 === i4 ? "" : "")), e6]; + }; + var B = class _B { + constructor({ strings: t4, _$litType$: i4 }, s2) { + let e6; + this.parts = []; + let h4 = 0, o5 = 0; + const n5 = t4.length - 1, r5 = this.parts, [l2, a2] = U(t4, i4); + if (this.el = _B.createElement(l2, s2), I.currentNode = this.el.content, 2 === i4 || 3 === i4) { + const t5 = this.el.content.firstChild; + t5.replaceWith(...t5.childNodes); + } + for (; null !== (e6 = I.nextNode()) && r5.length < n5; ) { + if (1 === e6.nodeType) { + if (e6.hasAttributes()) + for (const t5 of e6.getAttributeNames()) + if (t5.endsWith(f2)) { + const i5 = a2[o5++], s3 = e6.getAttribute(t5).split(v), n6 = /([.?@])?(.*)/.exec(i5); + r5.push({ type: 1, index: h4, name: n6[2], strings: s3, ctor: "." === n6[1] ? Y : "?" === n6[1] ? Z : "@" === n6[1] ? q : G }), e6.removeAttribute(t5); + } else + t5.startsWith(v) && (r5.push({ type: 6, index: h4 }), e6.removeAttribute(t5)); + if (M.test(e6.tagName)) { + const t5 = e6.textContent.split(v), i5 = t5.length - 1; + if (i5 > 0) { + e6.textContent = c3 ? c3.emptyScript : ""; + for (let s3 = 0; s3 < i5; s3++) + e6.append(t5[s3], lt()), I.nextNode(), r5.push({ type: 2, index: ++h4 }); + e6.append(t5[i5], lt()); + } + } + } else if (8 === e6.nodeType) + if (e6.data === m) + r5.push({ type: 2, index: h4 }); + else { + let t5 = -1; + for (; -1 !== (t5 = e6.data.indexOf(v, t5 + 1)); ) + r5.push({ type: 7, index: h4 }), t5 += v.length - 1; + } + h4++; + } + } + static createElement(t4, i4) { + const s2 = w.createElement("template"); + return s2.innerHTML = t4, s2; + } + }; + function z(t4, i4, s2 = t4, e6) { + if (i4 === R) + return i4; + let h4 = void 0 !== e6 ? s2.o?.[e6] : s2.l; + const o5 = st(i4) ? void 0 : i4._$litDirective$; + return h4?.constructor !== o5 && (h4?._$AO?.(false), void 0 === o5 ? h4 = void 0 : (h4 = new o5(t4), h4._$AT(t4, s2, e6)), void 0 !== e6 ? (s2.o ??= [])[e6] = h4 : s2.l = h4), void 0 !== h4 && (i4 = z(t4, h4._$AS(t4, i4.values), h4, e6)), i4; + } + var F = class { + constructor(t4, i4) { + this._$AV = [], this._$AN = void 0, this._$AD = t4, this._$AM = i4; + } + get parentNode() { + return this._$AM.parentNode; + } + get _$AU() { + return this._$AM._$AU; + } + u(t4) { + const { el: { content: i4 }, parts: s2 } = this._$AD, e6 = (t4?.creationScope ?? w).importNode(i4, true); + I.currentNode = e6; + let h4 = I.nextNode(), o5 = 0, n5 = 0, r5 = s2[0]; + for (; void 0 !== r5; ) { + if (o5 === r5.index) { + let i5; + 2 === r5.type ? i5 = new et(h4, h4.nextSibling, this, t4) : 1 === r5.type ? i5 = new r5.ctor(h4, r5.name, r5.strings, this, t4) : 6 === r5.type && (i5 = new K(h4, this, t4)), this._$AV.push(i5), r5 = s2[++n5]; + } + o5 !== r5?.index && (h4 = I.nextNode(), o5++); + } + return I.currentNode = w, e6; + } + p(t4) { + let i4 = 0; + for (const s2 of this._$AV) + void 0 !== s2 && (void 0 !== s2.strings ? (s2._$AI(t4, s2, i4), i4 += s2.strings.length - 2) : s2._$AI(t4[i4])), i4++; + } + }; + var et = class _et { + get _$AU() { + return this._$AM?._$AU ?? this.v; + } + constructor(t4, i4, s2, e6) { + this.type = 2, this._$AH = D, this._$AN = void 0, this._$AA = t4, this._$AB = i4, this._$AM = s2, this.options = e6, this.v = e6?.isConnected ?? true; + } + get parentNode() { + let t4 = this._$AA.parentNode; + const i4 = this._$AM; + return void 0 !== i4 && 11 === t4?.nodeType && (t4 = i4.parentNode), t4; + } + get startNode() { + return this._$AA; + } + get endNode() { + return this._$AB; + } + _$AI(t4, i4 = this) { + t4 = z(this, t4, i4), st(t4) ? t4 === D || null == t4 || "" === t4 ? (this._$AH !== D && this._$AR(), this._$AH = D) : t4 !== this._$AH && t4 !== R && this._(t4) : void 0 !== t4._$litType$ ? this.$(t4) : void 0 !== t4.nodeType ? this.T(t4) : $(t4) ? this.k(t4) : this._(t4); + } + O(t4) { + return this._$AA.parentNode.insertBefore(t4, this._$AB); + } + T(t4) { + this._$AH !== t4 && (this._$AR(), this._$AH = this.O(t4)); + } + _(t4) { + this._$AH !== D && st(this._$AH) ? this._$AA.nextSibling.data = t4 : this.T(w.createTextNode(t4)), this._$AH = t4; + } + $(t4) { + const { values: i4, _$litType$: s2 } = t4, e6 = "number" == typeof s2 ? this._$AC(t4) : (void 0 === s2.el && (s2.el = B.createElement(N(s2.h, s2.h[0]), this.options)), s2); + if (this._$AH?._$AD === e6) + this._$AH.p(i4); + else { + const t5 = new F(e6, this), s3 = t5.u(this.options); + t5.p(i4), this.T(s3), this._$AH = t5; + } + } + _$AC(t4) { + let i4 = V.get(t4.strings); + return void 0 === i4 && V.set(t4.strings, i4 = new B(t4)), i4; + } + k(t4) { + g(this._$AH) || (this._$AH = [], this._$AR()); + const i4 = this._$AH; + let s2, e6 = 0; + for (const h4 of t4) + e6 === i4.length ? i4.push(s2 = new _et(this.O(lt()), this.O(lt()), this, this.options)) : s2 = i4[e6], s2._$AI(h4), e6++; + e6 < i4.length && (this._$AR(s2 && s2._$AB.nextSibling, e6), i4.length = e6); + } + _$AR(t4 = this._$AA.nextSibling, i4) { + for (this._$AP?.(false, true, i4); t4 && t4 !== this._$AB; ) { + const i5 = t4.nextSibling; + t4.remove(), t4 = i5; + } + } + setConnected(t4) { + void 0 === this._$AM && (this.v = t4, this._$AP?.(t4)); + } + }; + var G = class { + get tagName() { + return this.element.tagName; + } + get _$AU() { + return this._$AM._$AU; + } + constructor(t4, i4, s2, e6, h4) { + this.type = 1, this._$AH = D, this._$AN = void 0, this.element = t4, this.name = i4, this._$AM = e6, this.options = h4, s2.length > 2 || "" !== s2[0] || "" !== s2[1] ? (this._$AH = Array(s2.length - 1).fill(new String()), this.strings = s2) : this._$AH = D; + } + _$AI(t4, i4 = this, s2, e6) { + const h4 = this.strings; + let o5 = false; + if (void 0 === h4) + t4 = z(this, t4, i4, 0), o5 = !st(t4) || t4 !== this._$AH && t4 !== R, o5 && (this._$AH = t4); + else { + const e7 = t4; + let n5, r5; + for (t4 = h4[0], n5 = 0; n5 < h4.length - 1; n5++) + r5 = z(this, e7[s2 + n5], i4, n5), r5 === R && (r5 = this._$AH[n5]), o5 ||= !st(r5) || r5 !== this._$AH[n5], r5 === D ? t4 = D : t4 !== D && (t4 += (r5 ?? "") + h4[n5 + 1]), this._$AH[n5] = r5; + } + o5 && !e6 && this.j(t4); + } + j(t4) { + t4 === D ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t4 ?? ""); + } + }; + var Y = class extends G { + constructor() { + super(...arguments), this.type = 3; + } + j(t4) { + this.element[this.name] = t4 === D ? void 0 : t4; + } + }; + var Z = class extends G { + constructor() { + super(...arguments), this.type = 4; + } + j(t4) { + this.element.toggleAttribute(this.name, !!t4 && t4 !== D); + } + }; + var q = class extends G { + constructor(t4, i4, s2, e6, h4) { + super(t4, i4, s2, e6, h4), this.type = 5; + } + _$AI(t4, i4 = this) { + if ((t4 = z(this, t4, i4, 0) ?? D) === R) + return; + const s2 = this._$AH, e6 = t4 === D && s2 !== D || t4.capture !== s2.capture || t4.once !== s2.once || t4.passive !== s2.passive, h4 = t4 !== D && (s2 === D || e6); + e6 && this.element.removeEventListener(this.name, this, s2), h4 && this.element.addEventListener(this.name, this, t4), this._$AH = t4; + } + handleEvent(t4) { + "function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t4) : this._$AH.handleEvent(t4); + } + }; + var K = class { + constructor(t4, i4, s2) { + this.element = t4, this.type = 6, this._$AN = void 0, this._$AM = i4, this.options = s2; + } + get _$AU() { + return this._$AM._$AU; + } + _$AI(t4) { + z(this, t4); + } + }; + var si = { M: f2, P: v, A: m, C: 1, L: U, R: F, D: $, V: z, I: et, H: G, N: Z, U: q, B: Y, F: K }; + var Re = n3.litHtmlPolyfillSupport; + Re?.(B, et), (n3.litHtmlVersions ??= []).push("3.2.0"); + var Q = (t4, i4, s2) => { + const e6 = s2?.renderBefore ?? i4; + let h4 = e6._$litPart$; + if (void 0 === h4) { + const t5 = s2?.renderBefore ?? null; + e6._$litPart$ = h4 = new et(i4.insertBefore(lt(), t5), t5, void 0, s2 ?? {}); + } + return h4._$AI(t4), h4; + }; + + // node_modules/lit-element/lit-element.js + var h3 = class extends b { + constructor() { + super(...arguments), this.renderOptions = { host: this }, this.o = void 0; + } + createRenderRoot() { + const t4 = super.createRenderRoot(); + return this.renderOptions.renderBefore ??= t4.firstChild, t4; + } + update(t4) { + const e6 = this.render(); + this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t4), this.o = Q(e6, this.renderRoot, this.renderOptions); + } + connectedCallback() { + super.connectedCallback(), this.o?.setConnected(true); + } + disconnectedCallback() { + super.disconnectedCallback(), this.o?.setConnected(false); + } + render() { + return R; + } + }; + h3._$litElement$ = true, h3["finalized"] = true, globalThis.litElementHydrateSupport?.({ LitElement: h3 }); + var f3 = globalThis.litElementPolyfillSupport; + f3?.({ LitElement: h3 }); + (globalThis.litElementVersions ??= []).push("4.1.0"); + + // node_modules/lit-html/is-server.js + var co = false; + + // node_modules/lit-html/directives/map.js + function* oo(o5, f4) { + if (void 0 !== o5) { + let i4 = 0; + for (const t4 of o5) + yield f4(t4, i4++); + } + } + + // node_modules/tslib/tslib.es6.js + function __decorate(decorators, target, key, desc) { + var c4 = arguments.length, r5 = c4 < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d2; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") + r5 = Reflect.decorate(decorators, target, key, desc); + else + for (var i4 = decorators.length - 1; i4 >= 0; i4--) + if (d2 = decorators[i4]) + r5 = (c4 < 3 ? d2(r5) : c4 > 3 ? d2(target, key, r5) : d2(target, key)) || r5; + return c4 > 3 && r5 && Object.defineProperty(target, key, r5), r5; + } + + // node_modules/@lit/reactive-element/decorators/custom-element.js + var t2 = (t4) => (e6, o5) => { + void 0 !== o5 ? o5.addInitializer(() => { + customElements.define(t4, e6); + }) : customElements.define(t4, e6); + }; + + // node_modules/@lit/reactive-element/decorators/property.js + var o3 = { attribute: true, type: String, converter: u, reflect: false, hasChanged: f }; + var r3 = (t4 = o3, e6, r5) => { + const { kind: n5, metadata: i4 } = r5; + let s2 = globalThis.litPropertyMetadata.get(i4); + if (void 0 === s2 && globalThis.litPropertyMetadata.set(i4, s2 = /* @__PURE__ */ new Map()), s2.set(r5.name, t4), "accessor" === n5) { + const { name: o5 } = r5; + return { set(r6) { + const n6 = e6.get.call(this); + e6.set.call(this, r6), this.requestUpdate(o5, n6, t4); + }, init(e7) { + return void 0 !== e7 && this.P(o5, void 0, t4), e7; + } }; + } + if ("setter" === n5) { + const { name: o5 } = r5; + return function(r6) { + const n6 = this[o5]; + e6.call(this, r6), this.requestUpdate(o5, n6, t4); + }; + } + throw Error("Unsupported decorator location: " + n5); + }; + function n4(t4) { + return (e6, o5) => "object" == typeof o5 ? r3(t4, e6, o5) : ((t5, e7, o6) => { + const r5 = e7.hasOwnProperty(o6); + return e7.constructor.createProperty(o6, r5 ? { ...t5, wrapped: true } : t5), r5 ? Object.getOwnPropertyDescriptor(e7, o6) : void 0; + })(t4, e6, o5); + } + + // node_modules/@lit/reactive-element/decorators/state.js + function r4(r5) { + return n4({ ...r5, state: true, attribute: false }); + } + + // node_modules/@lit/reactive-element/decorators/base.js + var e3 = (e6, t4, c4) => (c4.configurable = true, c4.enumerable = true, Reflect.decorate && "object" != typeof t4 && Object.defineProperty(e6, t4, c4), c4); + + // node_modules/@lit/reactive-element/decorators/query.js + function e4(e6, r5) { + return (n5, s2, i4) => { + const o5 = (t4) => t4.renderRoot?.querySelector(e6) ?? null; + if (r5) { + const { get: e7, set: r6 } = "object" == typeof s2 ? n5 : i4 ?? (() => { + const t4 = Symbol(); + return { get() { + return this[t4]; + }, set(e8) { + this[t4] = e8; + } }; + })(); + return e3(n5, s2, { get() { + let t4 = e7.call(this); + return void 0 === t4 && (t4 = o5(this), (null !== t4 || this.hasUpdated) && r6.call(this, t4)), t4; + } }); + } + return e3(n5, s2, { get() { + return o5(this); + } }); + }; + } + + // node_modules/@lit/reactive-element/decorators/query-assigned-elements.js + function o4(o5) { + return (e6, n5) => { + const { slot: r5, selector: s2 } = o5 ?? {}, c4 = "slot" + (r5 ? `[name=${r5}]` : ":not([name])"); + return e3(e6, n5, { get() { + const t4 = this.renderRoot?.querySelector(c4), e7 = t4?.assignedElements(o5) ?? []; + return void 0 === s2 ? e7 : e7.filter((t5) => t5.matches(s2)); + } }); + }; + } + + // node_modules/@material/web/elevation/internal/elevation.js + var Elevation = class extends h3 { + connectedCallback() { + super.connectedCallback(); + this.setAttribute("aria-hidden", "true"); + } + render() { + return ke``; + } + }; + + // node_modules/@material/web/elevation/internal/elevation-styles.js + var styles = i`:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}:host{display:flex;pointer-events:none;transition-property:box-shadow,opacity}.shadow::before,.shadow::after{content:"";transition-property:box-shadow,opacity;--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000))}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15} +`; + + // node_modules/@material/web/elevation/elevation.js + var MdElevation = class MdElevation2 extends Elevation { + }; + MdElevation.styles = [styles]; + MdElevation = __decorate([ + t2("md-elevation") + ], MdElevation); + + // node_modules/@material/web/internal/controller/attachable-controller.js + var ATTACHABLE_CONTROLLER = Symbol("attachableController"); + var FOR_ATTRIBUTE_OBSERVER; + if (!co) { + FOR_ATTRIBUTE_OBSERVER = new MutationObserver((records) => { + for (const record of records) { + record.target[ATTACHABLE_CONTROLLER]?.hostConnected(); + } + }); + } + var AttachableController = class { + get htmlFor() { + return this.host.getAttribute("for"); + } + set htmlFor(htmlFor) { + if (htmlFor === null) { + this.host.removeAttribute("for"); + } else { + this.host.setAttribute("for", htmlFor); + } + } + get control() { + if (this.host.hasAttribute("for")) { + if (!this.htmlFor || !this.host.isConnected) { + return null; + } + return this.host.getRootNode().querySelector(`#${this.htmlFor}`); + } + return this.currentControl || this.host.parentElement; + } + set control(control) { + if (control) { + this.attach(control); + } else { + this.detach(); + } + } + /** + * Creates a new controller for an `Attachable` element. + * + * @param host The `Attachable` element. + * @param onControlChange A callback with two parameters for the previous and + * next control. An `Attachable` element may perform setup or teardown + * logic whenever the control changes. + */ + constructor(host, onControlChange) { + this.host = host; + this.onControlChange = onControlChange; + this.currentControl = null; + host.addController(this); + host[ATTACHABLE_CONTROLLER] = this; + FOR_ATTRIBUTE_OBSERVER?.observe(host, { attributeFilter: ["for"] }); + } + attach(control) { + if (control === this.currentControl) { + return; + } + this.setCurrentControl(control); + this.host.removeAttribute("for"); + } + detach() { + this.setCurrentControl(null); + this.host.setAttribute("for", ""); + } + /** @private */ + hostConnected() { + this.setCurrentControl(this.control); + } + /** @private */ + hostDisconnected() { + this.setCurrentControl(null); + } + setCurrentControl(control) { + this.onControlChange(this.currentControl, control); + this.currentControl = control; + } + }; + + // node_modules/@material/web/focus/internal/focus-ring.js + var EVENTS = ["focusin", "focusout", "pointerdown"]; + var FocusRing = class extends h3 { + constructor() { + super(...arguments); + this.visible = false; + this.inward = false; + this.attachableController = new AttachableController(this, this.onControlChange.bind(this)); + } + get htmlFor() { + return this.attachableController.htmlFor; + } + set htmlFor(htmlFor) { + this.attachableController.htmlFor = htmlFor; + } + get control() { + return this.attachableController.control; + } + set control(control) { + this.attachableController.control = control; + } + attach(control) { + this.attachableController.attach(control); + } + detach() { + this.attachableController.detach(); + } + connectedCallback() { + super.connectedCallback(); + this.setAttribute("aria-hidden", "true"); + } + /** @private */ + handleEvent(event) { + if (event[HANDLED_BY_FOCUS_RING]) { + return; + } + switch (event.type) { + default: + return; + case "focusin": + this.visible = this.control?.matches(":focus-visible") ?? false; + break; + case "focusout": + case "pointerdown": + this.visible = false; + break; + } + event[HANDLED_BY_FOCUS_RING] = true; + } + onControlChange(prev, next) { + if (co) + return; + for (const event of EVENTS) { + prev?.removeEventListener(event, this); + next?.addEventListener(event, this); + } + } + update(changed) { + if (changed.has("visible")) { + this.dispatchEvent(new Event("visibility-changed")); + } + super.update(changed); + } + }; + __decorate([ + n4({ type: Boolean, reflect: true }) + ], FocusRing.prototype, "visible", void 0); + __decorate([ + n4({ type: Boolean, reflect: true }) + ], FocusRing.prototype, "inward", void 0); + var HANDLED_BY_FOCUS_RING = Symbol("handledByFocusRing"); + + // node_modules/@material/web/focus/internal/focus-ring-styles.js + var styles2 = i`:host{animation-delay:0s,calc(var(--md-focus-ring-duration, 600ms)*.25);animation-duration:calc(var(--md-focus-ring-duration, 600ms)*.25),calc(var(--md-focus-ring-duration, 600ms)*.75);animation-timing-function:cubic-bezier(0.2, 0, 0, 1);box-sizing:border-box;color:var(--md-focus-ring-color, var(--md-sys-color-secondary, #625b71));display:none;pointer-events:none;position:absolute}:host([visible]){display:flex}:host(:not([inward])){animation-name:outward-grow,outward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));inset:calc(-1*var(--md-focus-ring-outward-offset, 2px));outline:var(--md-focus-ring-width, 3px) solid currentColor}:host([inward]){animation-name:inward-grow,inward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border:var(--md-focus-ring-width, 3px) solid currentColor;inset:var(--md-focus-ring-inward-offset, 0px)}@keyframes outward-grow{from{outline-width:0}to{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes outward-shrink{from{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-grow{from{border-width:0}to{border-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-shrink{from{border-width:var(--md-focus-ring-active-width, 8px)}}@media(prefers-reduced-motion){:host{animation:none}} +`; + + // node_modules/@material/web/focus/md-focus-ring.js + var MdFocusRing = class MdFocusRing2 extends FocusRing { + }; + MdFocusRing.styles = [styles2]; + MdFocusRing = __decorate([ + t2("md-focus-ring") + ], MdFocusRing); + + // node_modules/lit-html/directive.js + var t3 = { ATTRIBUTE: 1, CHILD: 2, PROPERTY: 3, BOOLEAN_ATTRIBUTE: 4, EVENT: 5, ELEMENT: 6 }; + var e5 = (t4) => (...e6) => ({ _$litDirective$: t4, values: e6 }); + var i3 = class { + constructor(t4) { + } + get _$AU() { + return this._$AM._$AU; + } + _$AT(t4, e6, i4) { + this.t = t4, this._$AM = e6, this.i = i4; + } + _$AS(t4, e6) { + return this.update(t4, e6); + } + update(t4, e6) { + return this.render(...e6); + } + }; + + // node_modules/lit-html/directives/class-map.js + var Rt = e5(class extends i3 { + constructor(s2) { + if (super(s2), s2.type !== t3.ATTRIBUTE || "class" !== s2.name || s2.strings?.length > 2) + throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute."); + } + render(t4) { + return " " + Object.keys(t4).filter((s2) => t4[s2]).join(" ") + " "; + } + update(t4, [s2]) { + if (void 0 === this.st) { + this.st = /* @__PURE__ */ new Set(), void 0 !== t4.strings && (this.nt = new Set(t4.strings.join(" ").split(/\s/).filter((t5) => "" !== t5))); + for (const t5 in s2) + s2[t5] && !this.nt?.has(t5) && this.st.add(t5); + return this.render(s2); + } + const i4 = t4.element.classList; + for (const t5 of this.st) + t5 in s2 || (i4.remove(t5), this.st.delete(t5)); + for (const t5 in s2) { + const r5 = !!s2[t5]; + r5 === this.st.has(t5) || this.nt?.has(t5) || (r5 ? (i4.add(t5), this.st.add(t5)) : (i4.remove(t5), this.st.delete(t5))); + } + return R; + } + }); + + // node_modules/@material/web/internal/motion/animation.js + var EASING = { + STANDARD: "cubic-bezier(0.2, 0, 0, 1)", + STANDARD_ACCELERATE: "cubic-bezier(.3,0,1,1)", + STANDARD_DECELERATE: "cubic-bezier(0,0,0,1)", + EMPHASIZED: "cubic-bezier(.3,0,0,1)", + EMPHASIZED_ACCELERATE: "cubic-bezier(.3,0,.8,.15)", + EMPHASIZED_DECELERATE: "cubic-bezier(.05,.7,.1,1)" + }; + + // node_modules/@material/web/ripple/internal/ripple.js + var PRESS_GROW_MS = 450; + var MINIMUM_PRESS_MS = 225; + var INITIAL_ORIGIN_SCALE = 0.2; + var PADDING = 10; + var SOFT_EDGE_MINIMUM_SIZE = 75; + var SOFT_EDGE_CONTAINER_RATIO = 0.35; + var PRESS_PSEUDO = "::after"; + var ANIMATION_FILL = "forwards"; + var State; + (function(State2) { + State2[State2["INACTIVE"] = 0] = "INACTIVE"; + State2[State2["TOUCH_DELAY"] = 1] = "TOUCH_DELAY"; + State2[State2["HOLDING"] = 2] = "HOLDING"; + State2[State2["WAITING_FOR_CLICK"] = 3] = "WAITING_FOR_CLICK"; + })(State || (State = {})); + var EVENTS2 = [ + "click", + "contextmenu", + "pointercancel", + "pointerdown", + "pointerenter", + "pointerleave", + "pointerup" + ]; + var TOUCH_DELAY_MS = 150; + var FORCED_COLORS = co ? null : window.matchMedia("(forced-colors: active)"); + var Ripple = class extends h3 { + constructor() { + super(...arguments); + this.disabled = false; + this.hovered = false; + this.pressed = false; + this.rippleSize = ""; + this.rippleScale = ""; + this.initialSize = 0; + this.state = State.INACTIVE; + this.checkBoundsAfterContextMenu = false; + this.attachableController = new AttachableController(this, this.onControlChange.bind(this)); + } + get htmlFor() { + return this.attachableController.htmlFor; + } + set htmlFor(htmlFor) { + this.attachableController.htmlFor = htmlFor; + } + get control() { + return this.attachableController.control; + } + set control(control) { + this.attachableController.control = control; + } + attach(control) { + this.attachableController.attach(control); + } + detach() { + this.attachableController.detach(); + } + connectedCallback() { + super.connectedCallback(); + this.setAttribute("aria-hidden", "true"); + } + render() { + const classes = { + "hovered": this.hovered, + "pressed": this.pressed + }; + return ke`
    `; + } + update(changedProps) { + if (changedProps.has("disabled") && this.disabled) { + this.hovered = false; + this.pressed = false; + } + super.update(changedProps); + } + /** + * TODO(b/269799771): make private + * @private only public for slider + */ + handlePointerenter(event) { + if (!this.shouldReactToEvent(event)) { + return; + } + this.hovered = true; + } + /** + * TODO(b/269799771): make private + * @private only public for slider + */ + handlePointerleave(event) { + if (!this.shouldReactToEvent(event)) { + return; + } + this.hovered = false; + if (this.state !== State.INACTIVE) { + this.endPressAnimation(); + } + } + handlePointerup(event) { + if (!this.shouldReactToEvent(event)) { + return; + } + if (this.state === State.HOLDING) { + this.state = State.WAITING_FOR_CLICK; + return; + } + if (this.state === State.TOUCH_DELAY) { + this.state = State.WAITING_FOR_CLICK; + this.startPressAnimation(this.rippleStartEvent); + return; + } + } + async handlePointerdown(event) { + if (!this.shouldReactToEvent(event)) { + return; + } + this.rippleStartEvent = event; + if (!this.isTouch(event)) { + this.state = State.WAITING_FOR_CLICK; + this.startPressAnimation(event); + return; + } + if (this.checkBoundsAfterContextMenu && !this.inBounds(event)) { + return; + } + this.checkBoundsAfterContextMenu = false; + this.state = State.TOUCH_DELAY; + await new Promise((resolve) => { + setTimeout(resolve, TOUCH_DELAY_MS); + }); + if (this.state !== State.TOUCH_DELAY) { + return; + } + this.state = State.HOLDING; + this.startPressAnimation(event); + } + handleClick() { + if (this.disabled) { + return; + } + if (this.state === State.WAITING_FOR_CLICK) { + this.endPressAnimation(); + return; + } + if (this.state === State.INACTIVE) { + this.startPressAnimation(); + this.endPressAnimation(); + } + } + handlePointercancel(event) { + if (!this.shouldReactToEvent(event)) { + return; + } + this.endPressAnimation(); + } + handleContextmenu() { + if (this.disabled) { + return; + } + this.checkBoundsAfterContextMenu = true; + this.endPressAnimation(); + } + determineRippleSize() { + const { height, width } = this.getBoundingClientRect(); + const maxDim = Math.max(height, width); + const softEdgeSize = Math.max(SOFT_EDGE_CONTAINER_RATIO * maxDim, SOFT_EDGE_MINIMUM_SIZE); + const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE); + const hypotenuse = Math.sqrt(width ** 2 + height ** 2); + const maxRadius = hypotenuse + PADDING; + this.initialSize = initialSize; + this.rippleScale = `${(maxRadius + softEdgeSize) / initialSize}`; + this.rippleSize = `${initialSize}px`; + } + getNormalizedPointerEventCoords(pointerEvent) { + const { scrollX, scrollY } = window; + const { left, top } = this.getBoundingClientRect(); + const documentX = scrollX + left; + const documentY = scrollY + top; + const { pageX, pageY } = pointerEvent; + return { x: pageX - documentX, y: pageY - documentY }; + } + getTranslationCoordinates(positionEvent) { + const { height, width } = this.getBoundingClientRect(); + const endPoint = { + x: (width - this.initialSize) / 2, + y: (height - this.initialSize) / 2 + }; + let startPoint; + if (positionEvent instanceof PointerEvent) { + startPoint = this.getNormalizedPointerEventCoords(positionEvent); + } else { + startPoint = { + x: width / 2, + y: height / 2 + }; + } + startPoint = { + x: startPoint.x - this.initialSize / 2, + y: startPoint.y - this.initialSize / 2 + }; + return { startPoint, endPoint }; + } + startPressAnimation(positionEvent) { + if (!this.mdRoot) { + return; + } + this.pressed = true; + this.growAnimation?.cancel(); + this.determineRippleSize(); + const { startPoint, endPoint } = this.getTranslationCoordinates(positionEvent); + const translateStart = `${startPoint.x}px, ${startPoint.y}px`; + const translateEnd = `${endPoint.x}px, ${endPoint.y}px`; + this.growAnimation = this.mdRoot.animate({ + top: [0, 0], + left: [0, 0], + height: [this.rippleSize, this.rippleSize], + width: [this.rippleSize, this.rippleSize], + transform: [ + `translate(${translateStart}) scale(1)`, + `translate(${translateEnd}) scale(${this.rippleScale})` + ] + }, { + pseudoElement: PRESS_PSEUDO, + duration: PRESS_GROW_MS, + easing: EASING.STANDARD, + fill: ANIMATION_FILL + }); + } + async endPressAnimation() { + this.rippleStartEvent = void 0; + this.state = State.INACTIVE; + const animation = this.growAnimation; + let pressAnimationPlayState = Infinity; + if (typeof animation?.currentTime === "number") { + pressAnimationPlayState = animation.currentTime; + } else if (animation?.currentTime) { + pressAnimationPlayState = animation.currentTime.to("ms").value; + } + if (pressAnimationPlayState >= MINIMUM_PRESS_MS) { + this.pressed = false; + return; + } + await new Promise((resolve) => { + setTimeout(resolve, MINIMUM_PRESS_MS - pressAnimationPlayState); + }); + if (this.growAnimation !== animation) { + return; + } + this.pressed = false; + } + /** + * Returns `true` if + * - the ripple element is enabled + * - the pointer is primary for the input type + * - the pointer is the pointer that started the interaction, or will start + * the interaction + * - the pointer is a touch, or the pointer state has the primary button + * held, or the pointer is hovering + */ + shouldReactToEvent(event) { + if (this.disabled || !event.isPrimary) { + return false; + } + if (this.rippleStartEvent && this.rippleStartEvent.pointerId !== event.pointerId) { + return false; + } + if (event.type === "pointerenter" || event.type === "pointerleave") { + return !this.isTouch(event); + } + const isPrimaryButton = event.buttons === 1; + return this.isTouch(event) || isPrimaryButton; + } + /** + * Check if the event is within the bounds of the element. + * + * This is only needed for the "stuck" contextmenu longpress on Chrome. + */ + inBounds({ x: x2, y: y2 }) { + const { top, left, bottom, right } = this.getBoundingClientRect(); + return x2 >= left && x2 <= right && y2 >= top && y2 <= bottom; + } + isTouch({ pointerType }) { + return pointerType === "touch"; + } + /** @private */ + async handleEvent(event) { + if (FORCED_COLORS?.matches) { + return; + } + switch (event.type) { + case "click": + this.handleClick(); + break; + case "contextmenu": + this.handleContextmenu(); + break; + case "pointercancel": + this.handlePointercancel(event); + break; + case "pointerdown": + await this.handlePointerdown(event); + break; + case "pointerenter": + this.handlePointerenter(event); + break; + case "pointerleave": + this.handlePointerleave(event); + break; + case "pointerup": + this.handlePointerup(event); + break; + default: + break; + } + } + onControlChange(prev, next) { + if (co) + return; + for (const event of EVENTS2) { + prev?.removeEventListener(event, this); + next?.addEventListener(event, this); + } + } + }; + __decorate([ + n4({ type: Boolean, reflect: true }) + ], Ripple.prototype, "disabled", void 0); + __decorate([ + r4() + ], Ripple.prototype, "hovered", void 0); + __decorate([ + r4() + ], Ripple.prototype, "pressed", void 0); + __decorate([ + e4(".surface") + ], Ripple.prototype, "mdRoot", void 0); + + // node_modules/@material/web/ripple/internal/ripple-styles.js + var styles3 = i`:host{display:flex;margin:auto;pointer-events:none}:host([disabled]){display:none}@media(forced-colors: active){:host{display:none}}:host,.surface{border-radius:inherit;position:absolute;inset:0;overflow:hidden}.surface{-webkit-tap-highlight-color:rgba(0,0,0,0)}.surface::before,.surface::after{content:"";opacity:0;position:absolute}.surface::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));inset:0;transition:opacity 15ms linear,background-color 15ms linear}.surface::after{background:radial-gradient(closest-side, var(--md-ripple-pressed-color, var(--md-sys-color-on-surface, #1d1b20)) max(100% - 70px, 65%), transparent 100%);transform-origin:center center;transition:opacity 375ms linear}.hovered::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-ripple-hover-opacity, 0.08)}.pressed::after{opacity:var(--md-ripple-pressed-opacity, 0.12);transition-duration:105ms} +`; + + // node_modules/@material/web/ripple/ripple.js + var MdRipple = class MdRipple2 extends Ripple { + }; + MdRipple.styles = [styles3]; + MdRipple = __decorate([ + t2("md-ripple") + ], MdRipple); + + // node_modules/@material/web/internal/aria/aria.js + var ARIA_PROPERTIES = [ + "role", + "ariaAtomic", + "ariaAutoComplete", + "ariaBusy", + "ariaChecked", + "ariaColCount", + "ariaColIndex", + "ariaColSpan", + "ariaCurrent", + "ariaDisabled", + "ariaExpanded", + "ariaHasPopup", + "ariaHidden", + "ariaInvalid", + "ariaKeyShortcuts", + "ariaLabel", + "ariaLevel", + "ariaLive", + "ariaModal", + "ariaMultiLine", + "ariaMultiSelectable", + "ariaOrientation", + "ariaPlaceholder", + "ariaPosInSet", + "ariaPressed", + "ariaReadOnly", + "ariaRequired", + "ariaRoleDescription", + "ariaRowCount", + "ariaRowIndex", + "ariaRowSpan", + "ariaSelected", + "ariaSetSize", + "ariaSort", + "ariaValueMax", + "ariaValueMin", + "ariaValueNow", + "ariaValueText" + ]; + var ARIA_ATTRIBUTES = ARIA_PROPERTIES.map(ariaPropertyToAttribute); + function isAriaAttribute(attribute) { + return ARIA_ATTRIBUTES.includes(attribute); + } + function ariaPropertyToAttribute(property) { + return property.replace("aria", "aria-").replace(/Elements?/g, "").toLowerCase(); + } + + // node_modules/@material/web/internal/aria/delegate.js + var privateIgnoreAttributeChangesFor = Symbol("privateIgnoreAttributeChangesFor"); + function mixinDelegatesAria(base) { + var _a2; + if (co) { + return base; + } + class WithDelegatesAriaElement extends base { + constructor() { + super(...arguments); + this[_a2] = /* @__PURE__ */ new Set(); + } + attributeChangedCallback(name, oldValue, newValue) { + if (!isAriaAttribute(name)) { + super.attributeChangedCallback(name, oldValue, newValue); + return; + } + if (this[privateIgnoreAttributeChangesFor].has(name)) { + return; + } + this[privateIgnoreAttributeChangesFor].add(name); + this.removeAttribute(name); + this[privateIgnoreAttributeChangesFor].delete(name); + const dataProperty = ariaAttributeToDataProperty(name); + if (newValue === null) { + delete this.dataset[dataProperty]; + } else { + this.dataset[dataProperty] = newValue; + } + this.requestUpdate(ariaAttributeToDataProperty(name), oldValue); + } + getAttribute(name) { + if (isAriaAttribute(name)) { + return super.getAttribute(ariaAttributeToDataAttribute(name)); + } + return super.getAttribute(name); + } + removeAttribute(name) { + super.removeAttribute(name); + if (isAriaAttribute(name)) { + super.removeAttribute(ariaAttributeToDataAttribute(name)); + this.requestUpdate(); + } + } + } + _a2 = privateIgnoreAttributeChangesFor; + setupDelegatesAriaProperties(WithDelegatesAriaElement); + return WithDelegatesAriaElement; + } + function setupDelegatesAriaProperties(ctor) { + for (const ariaProperty of ARIA_PROPERTIES) { + const ariaAttribute = ariaPropertyToAttribute(ariaProperty); + const dataAttribute = ariaAttributeToDataAttribute(ariaAttribute); + const dataProperty = ariaAttributeToDataProperty(ariaAttribute); + ctor.createProperty(ariaProperty, { + attribute: ariaAttribute, + noAccessor: true + }); + ctor.createProperty(Symbol(dataAttribute), { + attribute: dataAttribute, + noAccessor: true + }); + Object.defineProperty(ctor.prototype, ariaProperty, { + configurable: true, + enumerable: true, + get() { + return this.dataset[dataProperty] ?? null; + }, + set(value) { + const prevValue = this.dataset[dataProperty] ?? null; + if (value === prevValue) { + return; + } + if (value === null) { + delete this.dataset[dataProperty]; + } else { + this.dataset[dataProperty] = value; + } + this.requestUpdate(ariaProperty, prevValue); + } + }); + } + } + function ariaAttributeToDataAttribute(ariaAttribute) { + return `data-${ariaAttribute}`; + } + function ariaAttributeToDataProperty(ariaAttribute) { + return ariaAttribute.replace(/-\w/, (dashLetter) => dashLetter[1].toUpperCase()); + } + + // node_modules/@material/web/labs/behaviors/element-internals.js + var internals = Symbol("internals"); + var privateInternals = Symbol("privateInternals"); + function mixinElementInternals(base) { + class WithElementInternalsElement extends base { + get [internals]() { + if (!this[privateInternals]) { + this[privateInternals] = this.attachInternals(); + } + return this[privateInternals]; + } + } + return WithElementInternalsElement; + } + + // node_modules/@material/web/internal/controller/form-submitter.js + function setupFormSubmitter(ctor) { + if (co) { + return; + } + ctor.addInitializer((instance) => { + const submitter = instance; + submitter.addEventListener("click", async (event) => { + const { type, [internals]: elementInternals } = submitter; + const { form } = elementInternals; + if (!form || type === "button") { + return; + } + await new Promise((resolve) => { + setTimeout(resolve); + }); + if (event.defaultPrevented) { + return; + } + if (type === "reset") { + form.reset(); + return; + } + form.addEventListener("submit", (submitEvent) => { + Object.defineProperty(submitEvent, "submitter", { + configurable: true, + enumerable: true, + get: () => submitter + }); + }, { capture: true, once: true }); + elementInternals.setFormValue(submitter.value); + form.requestSubmit(); + }); + }); + } + + // node_modules/@material/web/internal/events/form-label-activation.js + function dispatchActivationClick(element) { + const event = new MouseEvent("click", { bubbles: true }); + element.dispatchEvent(event); + return event; + } + function isActivationClick(event) { + if (event.currentTarget !== event.target) { + return false; + } + if (event.composedPath()[0] !== event.target) { + return false; + } + if (event.target.disabled) { + return false; + } + return !squelchEvent(event); + } + function squelchEvent(event) { + const squelched = isSquelchingEvents; + if (squelched) { + event.preventDefault(); + event.stopImmediatePropagation(); + } + squelchEventsForMicrotask(); + return squelched; + } + var isSquelchingEvents = false; + async function squelchEventsForMicrotask() { + isSquelchingEvents = true; + await null; + isSquelchingEvents = false; + } + + // node_modules/@material/web/button/internal/button.js + var buttonBaseClass = mixinDelegatesAria(mixinElementInternals(h3)); + var Button = class extends buttonBaseClass { + get name() { + return this.getAttribute("name") ?? ""; + } + set name(name) { + this.setAttribute("name", name); + } + /** + * The associated form element with which this element's value will submit. + */ + get form() { + return this[internals].form; + } + constructor() { + super(); + this.disabled = false; + this.softDisabled = false; + this.href = ""; + this.target = ""; + this.trailingIcon = false; + this.hasIcon = false; + this.type = "submit"; + this.value = ""; + if (!co) { + this.addEventListener("click", this.handleClick.bind(this)); + } + } + focus() { + this.buttonElement?.focus(); + } + blur() { + this.buttonElement?.blur(); + } + render() { + const isRippleDisabled = !this.href && (this.disabled || this.softDisabled); + const buttonOrLink = this.href ? this.renderLink() : this.renderButton(); + const buttonId = this.href ? "link" : "button"; + return ke` + ${this.renderElevationOrOutline?.()} +
    + + + ${buttonOrLink} + `; + } + renderButton() { + const { ariaLabel, ariaHasPopup, ariaExpanded } = this; + return ke``; + } + renderLink() { + const { ariaLabel, ariaHasPopup, ariaExpanded } = this; + return ke`${this.renderContent()} + `; + } + renderContent() { + const icon = ke``; + return ke` + + ${this.trailingIcon ? D : icon} + + ${this.trailingIcon ? icon : D} + `; + } + handleClick(event) { + if (!this.href && this.softDisabled) { + event.stopImmediatePropagation(); + event.preventDefault(); + return; + } + if (!isActivationClick(event) || !this.buttonElement) { + return; + } + this.focus(); + dispatchActivationClick(this.buttonElement); + } + handleSlotChange() { + this.hasIcon = this.assignedIcons.length > 0; + } + }; + (() => { + setupFormSubmitter(Button); + })(); + Button.formAssociated = true; + Button.shadowRootOptions = { + mode: "open", + delegatesFocus: true + }; + __decorate([ + n4({ type: Boolean, reflect: true }) + ], Button.prototype, "disabled", void 0); + __decorate([ + n4({ type: Boolean, attribute: "soft-disabled", reflect: true }) + ], Button.prototype, "softDisabled", void 0); + __decorate([ + n4() + ], Button.prototype, "href", void 0); + __decorate([ + n4() + ], Button.prototype, "target", void 0); + __decorate([ + n4({ type: Boolean, attribute: "trailing-icon", reflect: true }) + ], Button.prototype, "trailingIcon", void 0); + __decorate([ + n4({ type: Boolean, attribute: "has-icon", reflect: true }) + ], Button.prototype, "hasIcon", void 0); + __decorate([ + n4() + ], Button.prototype, "type", void 0); + __decorate([ + n4({ reflect: true }) + ], Button.prototype, "value", void 0); + __decorate([ + e4(".button") + ], Button.prototype, "buttonElement", void 0); + __decorate([ + o4({ slot: "icon", flatten: true }) + ], Button.prototype, "assignedIcons", void 0); + + // node_modules/@material/web/button/internal/filled-button.js + var FilledButton = class extends Button { + renderElevationOrOutline() { + return ke``; + } + }; + + // node_modules/@material/web/button/internal/filled-styles.js + var styles4 = i`:host{--_container-color: var(--md-filled-button-container-color, var(--md-sys-color-primary, #6750a4));--_container-elevation: var(--md-filled-button-container-elevation, 0);--_container-height: var(--md-filled-button-container-height, 40px);--_container-shadow-color: var(--md-filled-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-button-focus-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-container-elevation: var(--md-filled-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-button-hover-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-color: var(--md-filled-button-hover-state-layer-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-opacity: var(--md-filled-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-button-label-text-color, var(--md-sys-color-on-primary, #fff));--_label-text-font: var(--md-filled-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-button-pressed-label-text-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-color: var(--md-filled-button-pressed-state-layer-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-opacity: var(--md-filled-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-button-focus-icon-color, var(--md-sys-color-on-primary, #fff));--_hover-icon-color: var(--md-filled-button-hover-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-color: var(--md-filled-button-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-size: var(--md-filled-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-button-pressed-icon-color, var(--md-sys-color-on-primary, #fff));--_container-shape-start-start: var(--md-filled-button-container-shape-start-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-button-container-shape-start-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-button-container-shape-end-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-button-container-shape-end-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-button-leading-space, 24px);--_trailing-space: var(--md-filled-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-button-with-trailing-icon-trailing-space, 16px)} +`; + + // node_modules/@material/web/button/internal/shared-elevation-styles.js + var styles5 = i`md-elevation{transition-duration:280ms}:host(:is([disabled],[soft-disabled])) md-elevation{transition:none}md-elevation{--md-elevation-level: var(--_container-elevation);--md-elevation-shadow-color: var(--_container-shadow-color)}:host(:focus-within) md-elevation{--md-elevation-level: var(--_focus-container-elevation)}:host(:hover) md-elevation{--md-elevation-level: var(--_hover-container-elevation)}:host(:active) md-elevation{--md-elevation-level: var(--_pressed-container-elevation)}:host(:is([disabled],[soft-disabled])) md-elevation{--md-elevation-level: var(--_disabled-container-elevation)} +`; + + // node_modules/@material/web/button/internal/shared-styles.js + var styles6 = i`:host{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end);box-sizing:border-box;cursor:pointer;display:inline-flex;gap:8px;min-height:var(--_container-height);outline:none;padding-block:calc((var(--_container-height) - max(var(--_label-text-line-height),var(--_icon-size)))/2);padding-inline-start:var(--_leading-space);padding-inline-end:var(--_trailing-space);place-content:center;place-items:center;position:relative;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);text-overflow:ellipsis;text-wrap:nowrap;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);vertical-align:top;--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}:host(:is([disabled],[soft-disabled])){cursor:default;pointer-events:none}.button{border-radius:inherit;cursor:inherit;display:inline-flex;align-items:center;justify-content:center;border:none;outline:none;-webkit-appearance:none;vertical-align:middle;background:rgba(0,0,0,0);text-decoration:none;min-width:calc(64px - var(--_leading-space) - var(--_trailing-space));width:100%;z-index:0;height:100%;font:inherit;color:var(--_label-text-color);padding:0;gap:inherit;text-transform:inherit}.button::-moz-focus-inner{padding:0;border:0}:host(:hover) .button{color:var(--_hover-label-text-color)}:host(:focus-within) .button{color:var(--_focus-label-text-color)}:host(:active) .button{color:var(--_pressed-label-text-color)}.background{background-color:var(--_container-color);border-radius:inherit;inset:0;position:absolute}.label{overflow:hidden}:is(.button,.label,.label slot),.label ::slotted(*){text-overflow:inherit}:host(:is([disabled],[soft-disabled])) .label{color:var(--_disabled-label-text-color);opacity:var(--_disabled-label-text-opacity)}:host(:is([disabled],[soft-disabled])) .background{background-color:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}@media(forced-colors: active){.background{border:1px solid CanvasText}:host(:is([disabled],[soft-disabled])){--_disabled-icon-color: GrayText;--_disabled-icon-opacity: 1;--_disabled-container-opacity: 1;--_disabled-label-text-color: GrayText;--_disabled-label-text-opacity: 1}}:host([has-icon]:not([trailing-icon])){padding-inline-start:var(--_with-leading-icon-leading-space);padding-inline-end:var(--_with-leading-icon-trailing-space)}:host([has-icon][trailing-icon]){padding-inline-start:var(--_with-trailing-icon-leading-space);padding-inline-end:var(--_with-trailing-icon-trailing-space)}::slotted([slot=icon]){display:inline-flex;position:relative;writing-mode:horizontal-tb;fill:currentColor;flex-shrink:0;color:var(--_icon-color);font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size)}:host(:hover) ::slotted([slot=icon]){color:var(--_hover-icon-color)}:host(:focus-within) ::slotted([slot=icon]){color:var(--_focus-icon-color)}:host(:active) ::slotted([slot=icon]){color:var(--_pressed-icon-color)}:host(:is([disabled],[soft-disabled])) ::slotted([slot=icon]){color:var(--_disabled-icon-color);opacity:var(--_disabled-icon-opacity)}.touch{position:absolute;top:50%;height:48px;left:0;right:0;transform:translateY(-50%)}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_container-height))/2) 0}:host([touch-target=none]) .touch{display:none} +`; + + // node_modules/@material/web/button/filled-button.js + var MdFilledButton = class MdFilledButton2 extends FilledButton { + }; + MdFilledButton.styles = [ + styles6, + styles5, + styles4 + ]; + MdFilledButton = __decorate([ + t2("md-filled-button") + ], MdFilledButton); + + // node_modules/@material/web/button/internal/filled-tonal-button.js + var FilledTonalButton = class extends Button { + renderElevationOrOutline() { + return ke``; + } + }; + + // node_modules/@material/web/button/internal/filled-tonal-styles.js + var styles7 = i`:host{--_container-color: var(--md-filled-tonal-button-container-color, var(--md-sys-color-secondary-container, #e8def8));--_container-elevation: var(--md-filled-tonal-button-container-elevation, 0);--_container-height: var(--md-filled-tonal-button-container-height, 40px);--_container-shadow-color: var(--md-filled-tonal-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-tonal-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-tonal-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-tonal-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-tonal-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-tonal-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-tonal-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-tonal-button-focus-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-container-elevation: var(--md-filled-tonal-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-tonal-button-hover-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-color: var(--md-filled-tonal-button-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-opacity: var(--md-filled-tonal-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-tonal-button-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_label-text-font: var(--md-filled-tonal-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-tonal-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-tonal-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-tonal-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-tonal-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-tonal-button-pressed-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-color: var(--md-filled-tonal-button-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-opacity: var(--md-filled-tonal-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-tonal-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-tonal-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-tonal-button-focus-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-icon-color: var(--md-filled-tonal-button-hover-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-color: var(--md-filled-tonal-button-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-size: var(--md-filled-tonal-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-tonal-button-pressed-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_container-shape-start-start: var(--md-filled-tonal-button-container-shape-start-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-tonal-button-container-shape-start-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-tonal-button-container-shape-end-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-tonal-button-container-shape-end-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-tonal-button-leading-space, 24px);--_trailing-space: var(--md-filled-tonal-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-tonal-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-tonal-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-tonal-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-tonal-button-with-trailing-icon-trailing-space, 16px)} +`; + + // node_modules/@material/web/button/filled-tonal-button.js + var MdFilledTonalButton = class MdFilledTonalButton2 extends FilledTonalButton { + }; + MdFilledTonalButton.styles = [ + styles6, + styles5, + styles7 + ]; + MdFilledTonalButton = __decorate([ + t2("md-filled-tonal-button") + ], MdFilledTonalButton); + + // node_modules/@material/web/button/internal/text-button.js + var TextButton = class extends Button { + }; + + // node_modules/@material/web/button/internal/text-styles.js + var styles8 = i`:host{--_container-height: var(--md-text-button-container-height, 40px);--_disabled-label-text-color: var(--md-text-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-text-button-disabled-label-text-opacity, 0.38);--_focus-label-text-color: var(--md-text-button-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-text-button-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-text-button-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-text-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-text-button-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-text-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-text-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-text-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-text-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-text-button-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-text-button-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-text-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-text-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-text-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-text-button-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-icon-color: var(--md-text-button-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-color: var(--md-text-button-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-text-button-icon-size, 18px);--_pressed-icon-color: var(--md-text-button-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-text-button-container-shape-start-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-text-button-container-shape-start-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-text-button-container-shape-end-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-text-button-container-shape-end-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-text-button-leading-space, 12px);--_trailing-space: var(--md-text-button-trailing-space, 12px);--_with-leading-icon-leading-space: var(--md-text-button-with-leading-icon-leading-space, 12px);--_with-leading-icon-trailing-space: var(--md-text-button-with-leading-icon-trailing-space, 16px);--_with-trailing-icon-leading-space: var(--md-text-button-with-trailing-icon-leading-space, 16px);--_with-trailing-icon-trailing-space: var(--md-text-button-with-trailing-icon-trailing-space, 12px);--_container-color: none;--_disabled-container-color: none;--_disabled-container-opacity: 0} +`; + + // node_modules/@material/web/button/text-button.js + var MdTextButton = class MdTextButton2 extends TextButton { + }; + MdTextButton.styles = [styles6, styles8]; + MdTextButton = __decorate([ + t2("md-text-button") + ], MdTextButton); + + // node_modules/@material/web/divider/internal/divider.js + var Divider = class extends h3 { + constructor() { + super(...arguments); + this.inset = false; + this.insetStart = false; + this.insetEnd = false; + } + }; + __decorate([ + n4({ type: Boolean, reflect: true }) + ], Divider.prototype, "inset", void 0); + __decorate([ + n4({ type: Boolean, reflect: true, attribute: "inset-start" }) + ], Divider.prototype, "insetStart", void 0); + __decorate([ + n4({ type: Boolean, reflect: true, attribute: "inset-end" }) + ], Divider.prototype, "insetEnd", void 0); + + // node_modules/@material/web/divider/internal/divider-styles.js + var styles9 = i`:host{box-sizing:border-box;color:var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));display:flex;height:var(--md-divider-thickness, 1px);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:"";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}} +`; + + // node_modules/@material/web/divider/divider.js + var MdDivider = class MdDivider2 extends Divider { + }; + MdDivider.styles = [styles9]; + MdDivider = __decorate([ + t2("md-divider") + ], MdDivider); + + // node_modules/@material/web/internal/events/redispatch-event.js + function redispatchEvent(element, event) { + if (event.bubbles && (!element.shadowRoot || event.composed)) { + event.stopPropagation(); + } + const copy = Reflect.construct(event.constructor, [event.type, event]); + const dispatched = element.dispatchEvent(copy); + if (!dispatched) { + event.preventDefault(); + } + return dispatched; + } + + // node_modules/@material/web/dialog/internal/animations.js + var DIALOG_DEFAULT_OPEN_ANIMATION = { + dialog: [ + [ + // Dialog slide down + [{ "transform": "translateY(-50px)" }, { "transform": "translateY(0)" }], + { duration: 500, easing: EASING.EMPHASIZED } + ] + ], + scrim: [ + [ + // Scrim fade in + [{ "opacity": 0 }, { "opacity": 0.32 }], + { duration: 500, easing: "linear" } + ] + ], + container: [ + [ + // Container fade in + [{ "opacity": 0 }, { "opacity": 1 }], + { duration: 50, easing: "linear", pseudoElement: "::before" } + ], + [ + // Container grow + // Note: current spec says to grow from 0dp->100% and shrink from + // 100%->35%. We change this to 35%->100% to simplify the animation that + // is supposed to clip content as it grows. From 0dp it's possible to see + // text/actions appear before the container has fully grown. + [{ "height": "35%" }, { "height": "100%" }], + { duration: 500, easing: EASING.EMPHASIZED, pseudoElement: "::before" } + ] + ], + headline: [ + [ + // Headline fade in + [{ "opacity": 0 }, { "opacity": 0, offset: 0.2 }, { "opacity": 1 }], + { duration: 250, easing: "linear", fill: "forwards" } + ] + ], + content: [ + [ + // Content fade in + [{ "opacity": 0 }, { "opacity": 0, offset: 0.2 }, { "opacity": 1 }], + { duration: 250, easing: "linear", fill: "forwards" } + ] + ], + actions: [ + [ + // Actions fade in + [{ "opacity": 0 }, { "opacity": 0, offset: 0.5 }, { "opacity": 1 }], + { duration: 300, easing: "linear", fill: "forwards" } + ] + ] + }; + var DIALOG_DEFAULT_CLOSE_ANIMATION = { + dialog: [ + [ + // Dialog slide up + [{ "transform": "translateY(0)" }, { "transform": "translateY(-50px)" }], + { duration: 150, easing: EASING.EMPHASIZED_ACCELERATE } + ] + ], + scrim: [ + [ + // Scrim fade out + [{ "opacity": 0.32 }, { "opacity": 0 }], + { duration: 150, easing: "linear" } + ] + ], + container: [ + [ + // Container shrink + [{ "height": "100%" }, { "height": "35%" }], + { + duration: 150, + easing: EASING.EMPHASIZED_ACCELERATE, + pseudoElement: "::before" + } + ], + [ + // Container fade out + [{ "opacity": "1" }, { "opacity": "0" }], + { delay: 100, duration: 50, easing: "linear", pseudoElement: "::before" } + ] + ], + headline: [ + [ + // Headline fade out + [{ "opacity": 1 }, { "opacity": 0 }], + { duration: 100, easing: "linear", fill: "forwards" } + ] + ], + content: [ + [ + // Content fade out + [{ "opacity": 1 }, { "opacity": 0 }], + { duration: 100, easing: "linear", fill: "forwards" } + ] + ], + actions: [ + [ + // Actions fade out + [{ "opacity": 1 }, { "opacity": 0 }], + { duration: 100, easing: "linear", fill: "forwards" } + ] + ] + }; + + // node_modules/@material/web/dialog/internal/dialog.js + var dialogBaseClass = mixinDelegatesAria(h3); + var Dialog = class extends dialogBaseClass { + // We do not use `delegatesFocus: true` due to a Chromium bug with + // selecting text. + // See https://bugs.chromium.org/p/chromium/issues/detail?id=950357 + /** + * Opens the dialog when set to `true` and closes it when set to `false`. + */ + get open() { + return this.isOpen; + } + set open(open) { + if (open === this.isOpen) { + return; + } + this.isOpen = open; + if (open) { + this.setAttribute("open", ""); + this.show(); + } else { + this.removeAttribute("open"); + this.close(); + } + } + constructor() { + super(); + this.quick = false; + this.returnValue = ""; + this.noFocusTrap = false; + this.getOpenAnimation = () => DIALOG_DEFAULT_OPEN_ANIMATION; + this.getCloseAnimation = () => DIALOG_DEFAULT_CLOSE_ANIMATION; + this.isOpen = false; + this.isOpening = false; + this.isConnectedPromise = this.getIsConnectedPromise(); + this.isAtScrollTop = false; + this.isAtScrollBottom = false; + this.nextClickIsFromContent = false; + this.hasHeadline = false; + this.hasActions = false; + this.hasIcon = false; + this.escapePressedWithoutCancel = false; + this.treewalker = co ? null : document.createTreeWalker(this, NodeFilter.SHOW_ELEMENT); + if (!co) { + this.addEventListener("submit", this.handleSubmit); + } + } + /** + * Opens the dialog and fires a cancelable `open` event. After a dialog's + * animation, an `opened` event is fired. + * + * Add an `autofocus` attribute to a child of the dialog that should + * receive focus after opening. + * + * @return A Promise that resolves after the animation is finished and the + * `opened` event was fired. + */ + async show() { + this.isOpening = true; + await this.isConnectedPromise; + await this.updateComplete; + const dialog = this.dialog; + if (dialog.open || !this.isOpening) { + this.isOpening = false; + return; + } + const preventOpen = !this.dispatchEvent(new Event("open", { cancelable: true })); + if (preventOpen) { + this.open = false; + this.isOpening = false; + return; + } + dialog.showModal(); + this.open = true; + if (this.scroller) { + this.scroller.scrollTop = 0; + } + this.querySelector("[autofocus]")?.focus(); + await this.animateDialog(this.getOpenAnimation()); + this.dispatchEvent(new Event("opened")); + this.isOpening = false; + } + /** + * Closes the dialog and fires a cancelable `close` event. After a dialog's + * animation, a `closed` event is fired. + * + * @param returnValue A return value usually indicating which button was used + * to close a dialog. If a dialog is canceled by clicking the scrim or + * pressing Escape, it will not change the return value after closing. + * @return A Promise that resolves after the animation is finished and the + * `closed` event was fired. + */ + async close(returnValue = this.returnValue) { + this.isOpening = false; + if (!this.isConnected) { + this.open = false; + return; + } + await this.updateComplete; + const dialog = this.dialog; + if (!dialog.open || this.isOpening) { + this.open = false; + return; + } + const prevReturnValue = this.returnValue; + this.returnValue = returnValue; + const preventClose = !this.dispatchEvent(new Event("close", { cancelable: true })); + if (preventClose) { + this.returnValue = prevReturnValue; + return; + } + await this.animateDialog(this.getCloseAnimation()); + dialog.close(returnValue); + this.open = false; + this.dispatchEvent(new Event("closed")); + } + connectedCallback() { + super.connectedCallback(); + this.isConnectedPromiseResolve(); + } + disconnectedCallback() { + super.disconnectedCallback(); + this.isConnectedPromise = this.getIsConnectedPromise(); + } + render() { + const scrollable = this.open && !(this.isAtScrollTop && this.isAtScrollBottom); + const classes = { + "has-headline": this.hasHeadline, + "has-actions": this.hasActions, + "has-icon": this.hasIcon, + "scrollable": scrollable, + "show-top-divider": scrollable && !this.isAtScrollTop, + "show-bottom-divider": scrollable && !this.isAtScrollBottom + }; + const showFocusTrap = this.open && !this.noFocusTrap; + const focusTrap = ke` + + `; + const { ariaLabel } = this; + return ke` +
    + + ${showFocusTrap ? focusTrap : D} +
    +
    + +

    + +

    + +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    + ${showFocusTrap ? focusTrap : D} +
    + `; + } + firstUpdated() { + this.intersectionObserver = new IntersectionObserver((entries) => { + for (const entry of entries) { + this.handleAnchorIntersection(entry); + } + }, { root: this.scroller }); + this.intersectionObserver.observe(this.topAnchor); + this.intersectionObserver.observe(this.bottomAnchor); + } + handleDialogClick() { + if (this.nextClickIsFromContent) { + this.nextClickIsFromContent = false; + return; + } + const preventDefault = !this.dispatchEvent(new Event("cancel", { cancelable: true })); + if (preventDefault) { + return; + } + this.close(); + } + handleContentClick() { + this.nextClickIsFromContent = true; + } + handleSubmit(event) { + const form = event.target; + const { submitter } = event; + if (form.method !== "dialog" || !submitter) { + return; + } + this.close(submitter.getAttribute("value") ?? this.returnValue); + } + handleCancel(event) { + if (event.target !== this.dialog) { + return; + } + this.escapePressedWithoutCancel = false; + const preventDefault = !redispatchEvent(this, event); + event.preventDefault(); + if (preventDefault) { + return; + } + this.close(); + } + handleClose() { + if (!this.escapePressedWithoutCancel) { + return; + } + this.escapePressedWithoutCancel = false; + this.dialog?.dispatchEvent(new Event("cancel", { cancelable: true })); + } + handleKeydown(event) { + if (event.key !== "Escape") { + return; + } + this.escapePressedWithoutCancel = true; + setTimeout(() => { + this.escapePressedWithoutCancel = false; + }); + } + async animateDialog(animation) { + this.cancelAnimations?.abort(); + this.cancelAnimations = new AbortController(); + if (this.quick) { + return; + } + const { dialog, scrim, container, headline, content, actions } = this; + if (!dialog || !scrim || !container || !headline || !content || !actions) { + return; + } + const { container: containerAnimate, dialog: dialogAnimate, scrim: scrimAnimate, headline: headlineAnimate, content: contentAnimate, actions: actionsAnimate } = animation; + const elementAndAnimation = [ + [dialog, dialogAnimate ?? []], + [scrim, scrimAnimate ?? []], + [container, containerAnimate ?? []], + [headline, headlineAnimate ?? []], + [content, contentAnimate ?? []], + [actions, actionsAnimate ?? []] + ]; + const animations = []; + for (const [element, animation2] of elementAndAnimation) { + for (const animateArgs of animation2) { + const animation3 = element.animate(...animateArgs); + this.cancelAnimations.signal.addEventListener("abort", () => { + animation3.cancel(); + }); + animations.push(animation3); + } + } + await Promise.all(animations.map((animation2) => animation2.finished.catch(() => { + }))); + } + handleHeadlineChange(event) { + const slot = event.target; + this.hasHeadline = slot.assignedElements().length > 0; + } + handleActionsChange(event) { + const slot = event.target; + this.hasActions = slot.assignedElements().length > 0; + } + handleIconChange(event) { + const slot = event.target; + this.hasIcon = slot.assignedElements().length > 0; + } + handleAnchorIntersection(entry) { + const { target, isIntersecting } = entry; + if (target === this.topAnchor) { + this.isAtScrollTop = isIntersecting; + } + if (target === this.bottomAnchor) { + this.isAtScrollBottom = isIntersecting; + } + } + getIsConnectedPromise() { + return new Promise((resolve) => { + this.isConnectedPromiseResolve = resolve; + }); + } + handleFocusTrapFocus(event) { + const [firstFocusableChild, lastFocusableChild] = this.getFirstAndLastFocusableChildren(); + if (!firstFocusableChild || !lastFocusableChild) { + this.dialog?.focus(); + return; + } + const isFirstFocusTrap = event.target === this.firstFocusTrap; + const isLastFocusTrap = !isFirstFocusTrap; + const focusCameFromFirstChild = event.relatedTarget === firstFocusableChild; + const focusCameFromLastChild = event.relatedTarget === lastFocusableChild; + const focusCameFromOutsideDialog = !focusCameFromFirstChild && !focusCameFromLastChild; + const shouldFocusFirstChild = isLastFocusTrap && focusCameFromLastChild || isFirstFocusTrap && focusCameFromOutsideDialog; + if (shouldFocusFirstChild) { + firstFocusableChild.focus(); + return; + } + const shouldFocusLastChild = isFirstFocusTrap && focusCameFromFirstChild || isLastFocusTrap && focusCameFromOutsideDialog; + if (shouldFocusLastChild) { + lastFocusableChild.focus(); + return; + } + } + getFirstAndLastFocusableChildren() { + if (!this.treewalker) { + return [null, null]; + } + let firstFocusableChild = null; + let lastFocusableChild = null; + this.treewalker.currentNode = this.treewalker.root; + while (this.treewalker.nextNode()) { + const nextChild = this.treewalker.currentNode; + if (!isFocusable(nextChild)) { + continue; + } + if (!firstFocusableChild) { + firstFocusableChild = nextChild; + } + lastFocusableChild = nextChild; + } + return [firstFocusableChild, lastFocusableChild]; + } + }; + __decorate([ + n4({ type: Boolean }) + ], Dialog.prototype, "open", null); + __decorate([ + n4({ type: Boolean }) + ], Dialog.prototype, "quick", void 0); + __decorate([ + n4({ attribute: false }) + ], Dialog.prototype, "returnValue", void 0); + __decorate([ + n4() + ], Dialog.prototype, "type", void 0); + __decorate([ + n4({ type: Boolean, attribute: "no-focus-trap" }) + ], Dialog.prototype, "noFocusTrap", void 0); + __decorate([ + e4("dialog") + ], Dialog.prototype, "dialog", void 0); + __decorate([ + e4(".scrim") + ], Dialog.prototype, "scrim", void 0); + __decorate([ + e4(".container") + ], Dialog.prototype, "container", void 0); + __decorate([ + e4(".headline") + ], Dialog.prototype, "headline", void 0); + __decorate([ + e4(".content") + ], Dialog.prototype, "content", void 0); + __decorate([ + e4(".actions") + ], Dialog.prototype, "actions", void 0); + __decorate([ + r4() + ], Dialog.prototype, "isAtScrollTop", void 0); + __decorate([ + r4() + ], Dialog.prototype, "isAtScrollBottom", void 0); + __decorate([ + e4(".scroller") + ], Dialog.prototype, "scroller", void 0); + __decorate([ + e4(".top.anchor") + ], Dialog.prototype, "topAnchor", void 0); + __decorate([ + e4(".bottom.anchor") + ], Dialog.prototype, "bottomAnchor", void 0); + __decorate([ + e4(".focus-trap") + ], Dialog.prototype, "firstFocusTrap", void 0); + __decorate([ + r4() + ], Dialog.prototype, "hasHeadline", void 0); + __decorate([ + r4() + ], Dialog.prototype, "hasActions", void 0); + __decorate([ + r4() + ], Dialog.prototype, "hasIcon", void 0); + function isFocusable(element) { + const knownFocusableElements = ":is(button,input,select,textarea,object,:is(a,area)[href],[tabindex],[contenteditable=true])"; + const notDisabled = ":not(:disabled,[disabled])"; + const notNegativeTabIndex = ':not([tabindex^="-"])'; + if (element.matches(knownFocusableElements + notDisabled + notNegativeTabIndex)) { + return true; + } + const isCustomElement = element.localName.includes("-"); + if (!isCustomElement) { + return false; + } + if (!element.matches(notDisabled)) { + return false; + } + return element.shadowRoot?.delegatesFocus ?? false; + } + + // node_modules/@material/web/dialog/internal/dialog-styles.js + var styles10 = i`:host{border-start-start-radius:var(--md-dialog-container-shape-start-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-start-end-radius:var(--md-dialog-container-shape-start-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-end-radius:var(--md-dialog-container-shape-end-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-start-radius:var(--md-dialog-container-shape-end-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));display:contents;margin:auto;max-height:min(560px,100% - 48px);max-width:min(560px,100% - 48px);min-height:140px;min-width:280px;position:fixed;height:fit-content;width:fit-content}dialog{background:rgba(0,0,0,0);border:none;border-radius:inherit;flex-direction:column;height:inherit;margin:inherit;max-height:inherit;max-width:inherit;min-height:inherit;min-width:inherit;outline:none;overflow:visible;padding:0;width:inherit}dialog[open]{display:flex}::backdrop{background:none}.scrim{background:var(--md-sys-color-scrim, #000);display:none;inset:0;opacity:32%;pointer-events:none;position:fixed;z-index:1}:host([open]) .scrim{display:flex}h2{all:unset;align-self:stretch}.headline{align-items:center;color:var(--md-dialog-headline-color, var(--md-sys-color-on-surface, #1d1b20));display:flex;flex-direction:column;font-family:var(--md-dialog-headline-font, var(--md-sys-typescale-headline-small-font, var(--md-ref-typeface-brand, Roboto)));font-size:var(--md-dialog-headline-size, var(--md-sys-typescale-headline-small-size, 1.5rem));line-height:var(--md-dialog-headline-line-height, var(--md-sys-typescale-headline-small-line-height, 2rem));font-weight:var(--md-dialog-headline-weight, var(--md-sys-typescale-headline-small-weight, var(--md-ref-typeface-weight-regular, 400)));position:relative}slot[name=headline]::slotted(*){align-items:center;align-self:stretch;box-sizing:border-box;display:flex;gap:8px;padding:24px 24px 0}.icon{display:flex}slot[name=icon]::slotted(*){color:var(--md-dialog-icon-color, var(--md-sys-color-secondary, #625b71));fill:currentColor;font-size:var(--md-dialog-icon-size, 24px);margin-top:24px;height:var(--md-dialog-icon-size, 24px);width:var(--md-dialog-icon-size, 24px)}.has-icon slot[name=headline]::slotted(*){justify-content:center;padding-top:16px}.scrollable slot[name=headline]::slotted(*){padding-bottom:16px}.scrollable.has-headline slot[name=content]::slotted(*){padding-top:8px}.container{border-radius:inherit;display:flex;flex-direction:column;flex-grow:1;overflow:hidden;position:relative;transform-origin:top}.container::before{background:var(--md-dialog-container-color, var(--md-sys-color-surface-container-high, #ece6f0));border-radius:inherit;content:"";inset:0;position:absolute}.scroller{display:flex;flex:1;flex-direction:column;overflow:hidden;z-index:1}.scrollable .scroller{overflow-y:scroll}.content{color:var(--md-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-dialog-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-dialog-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-dialog-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));flex:1;font-weight:var(--md-dialog-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)));height:min-content;position:relative}slot[name=content]::slotted(*){box-sizing:border-box;padding:24px}.anchor{position:absolute}.top.anchor{top:0}.bottom.anchor{bottom:0}.actions{position:relative}slot[name=actions]::slotted(*){box-sizing:border-box;display:flex;gap:8px;justify-content:flex-end;padding:16px 24px 24px}.has-actions slot[name=content]::slotted(*){padding-bottom:8px}md-divider{display:none;position:absolute}.has-headline.show-top-divider .headline md-divider,.has-actions.show-bottom-divider .actions md-divider{display:flex}.headline md-divider{bottom:0}.actions md-divider{top:0}@media(forced-colors: active){dialog{outline:2px solid WindowText}} +`; + + // node_modules/@material/web/dialog/dialog.js + var MdDialog = class MdDialog2 extends Dialog { + }; + MdDialog.styles = [styles10]; + MdDialog = __decorate([ + t2("md-dialog") + ], MdDialog); + + // node_modules/@material/web/icon/internal/icon.js + var Icon = class extends h3 { + render() { + return ke``; + } + connectedCallback() { + super.connectedCallback(); + const ariaHidden = this.getAttribute("aria-hidden"); + if (ariaHidden === "false") { + this.removeAttribute("aria-hidden"); + return; + } + this.setAttribute("aria-hidden", "true"); + } + }; + + // node_modules/@material/web/icon/internal/icon-styles.js + var styles11 = i`:host{font-size:var(--md-icon-size, 24px);width:var(--md-icon-size, 24px);height:var(--md-icon-size, 24px);color:inherit;font-variation-settings:inherit;font-weight:400;font-family:var(--md-icon-font, Material Symbols Outlined);display:inline-flex;font-style:normal;place-items:center;place-content:center;line-height:1;overflow:hidden;letter-spacing:normal;text-transform:none;user-select:none;white-space:nowrap;word-wrap:normal;flex-shrink:0;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale}::slotted(svg){fill:currentColor}::slotted(*){height:100%;width:100%} +`; + + // node_modules/@material/web/icon/icon.js + var MdIcon = class MdIcon2 extends Icon { + }; + MdIcon.styles = [styles11]; + MdIcon = __decorate([ + t2("md-icon") + ], MdIcon); + + // node_modules/lit-html/static.js + var $e = Symbol.for(""); + var xe = (t4) => { + if (t4?.r === $e) + return t4?._$litStatic$; + }; + var er = (t4, ...r5) => ({ _$litStatic$: r5.reduce((r6, e6, a2) => r6 + ((t5) => { + if (void 0 !== t5._$litStatic$) + return t5._$litStatic$; + throw Error(`Value passed to 'literal' function must be a 'literal' result: ${t5}. Use 'unsafeStatic' to pass non-literal values, but + take care to ensure page security.`); + })(e6) + t4[a2 + 1], t4[0]), r: $e }); + var Te = /* @__PURE__ */ new Map(); + var Ee = (t4) => (r5, ...e6) => { + const a2 = e6.length; + let o5, s2; + const i4 = [], l2 = []; + let n5, u2 = 0, c4 = false; + for (; u2 < a2; ) { + for (n5 = r5[u2]; u2 < a2 && void 0 !== (s2 = e6[u2], o5 = xe(s2)); ) + n5 += o5 + r5[++u2], c4 = true; + u2 !== a2 && l2.push(s2), i4.push(n5), u2++; + } + if (u2 === a2 && i4.push(r5[a2]), c4) { + const t5 = i4.join("$$lit$$"); + void 0 === (r5 = Te.get(t5)) && (i4.raw = i4, Te.set(t5, r5 = i4)), e6 = l2; + } + return t4(r5, ...e6); + }; + var ke2 = Ee(ke); + var Oe2 = Ee(Oe); + var Se2 = Ee(Se); + + // node_modules/@material/web/internal/controller/is-rtl.js + function isRtl(el, shouldCheck = true) { + return shouldCheck && getComputedStyle(el).getPropertyValue("direction").trim() === "rtl"; + } + + // node_modules/@material/web/iconbutton/internal/icon-button.js + var iconButtonBaseClass = mixinDelegatesAria(mixinElementInternals(h3)); + var IconButton = class extends iconButtonBaseClass { + get name() { + return this.getAttribute("name") ?? ""; + } + set name(name) { + this.setAttribute("name", name); + } + /** + * The associated form element with which this element's value will submit. + */ + get form() { + return this[internals].form; + } + /** + * The labels this element is associated with. + */ + get labels() { + return this[internals].labels; + } + constructor() { + super(); + this.disabled = false; + this.softDisabled = false; + this.flipIconInRtl = false; + this.href = ""; + this.target = ""; + this.ariaLabelSelected = ""; + this.toggle = false; + this.selected = false; + this.type = "submit"; + this.value = ""; + this.flipIcon = isRtl(this, this.flipIconInRtl); + if (!co) { + this.addEventListener("click", this.handleClick.bind(this)); + } + } + willUpdate() { + if (this.href) { + this.disabled = false; + this.softDisabled = false; + } + } + render() { + const tag = this.href ? er`div` : er`button`; + const { ariaLabel, ariaHasPopup, ariaExpanded } = this; + const hasToggledAriaLabel = ariaLabel && this.ariaLabelSelected; + const ariaPressedValue = !this.toggle ? D : this.selected; + let ariaLabelValue = D; + if (!this.href) { + ariaLabelValue = hasToggledAriaLabel && this.selected ? this.ariaLabelSelected : ariaLabel; + } + return ke2`<${tag} + class="icon-button ${Rt(this.getRenderClasses())}" + id="button" + aria-label="${ariaLabelValue || D}" + aria-haspopup="${!this.href && ariaHasPopup || D}" + aria-expanded="${!this.href && ariaExpanded || D}" + aria-pressed="${ariaPressedValue}" + aria-disabled=${!this.href && this.softDisabled || D} + ?disabled="${!this.href && this.disabled}" + @click="${this.handleClickOnChild}"> + ${this.renderFocusRing()} + ${this.renderRipple()} + ${!this.selected ? this.renderIcon() : D} + ${this.selected ? this.renderSelectedIcon() : D} + ${this.renderTouchTarget()} + ${this.href && this.renderLink()} + `; + } + renderLink() { + const { ariaLabel } = this; + return ke` + + `; + } + getRenderClasses() { + return { + "flip-icon": this.flipIcon, + "selected": this.toggle && this.selected + }; + } + renderIcon() { + return ke``; + } + renderSelectedIcon() { + return ke``; + } + renderTouchTarget() { + return ke``; + } + renderFocusRing() { + return ke``; + } + renderRipple() { + const isRippleDisabled = !this.href && (this.disabled || this.softDisabled); + return ke``; + } + connectedCallback() { + this.flipIcon = isRtl(this, this.flipIconInRtl); + super.connectedCallback(); + } + /** Handles a click on this element. */ + handleClick(event) { + if (!this.href && this.softDisabled) { + event.stopImmediatePropagation(); + event.preventDefault(); + return; + } + } + /** + * Handles a click on the child
    or
    `; + }); + return import_nanohtml6.default` +
    + ${list} +
    + `; + } + function blockSvg() { + return import_nanohtml6.default` + + + + + `; + } + + // v2/components/key-insights.jsx + function KeyInsights() { + const data = useData(); + return /* @__PURE__ */ y("div", { id: "key-insight" }, /* @__PURE__ */ y(DomNode, { key: data.count }, renderKeyInsight(data))); + } + function KeyInsightsMain({ title, children, icon = "chat" }) { + return /* @__PURE__ */ y("div", { className: "key-insight key-insight--main" }, /* @__PURE__ */ y("div", { className: `key-insight__icon hero-icon--${icon}` }), /* @__PURE__ */ y("h1", { className: "token-title-3-em" }, title), /* @__PURE__ */ y("div", { className: "token-title-3" }, /* @__PURE__ */ y("span", null, children))); + } + + // shared/js/ui/templates/protection-header.js + var import_nanohtml7 = __toESM(require_browser()); + + // shared/js/ui/components/text-link.jsx + function TextLink(props) { + const { onClick, rounded = false } = props; + const ref = _(null); + useRipple({ ref }); + let classNames = [`link-action`, `link-action--text`]; + if (rounded) + classNames.push(`link-action--rounded`); + return /* @__PURE__ */ y("a", { href: "javascript:void(0)", className: classNames.join(" "), draggable: false, ref, onClick }, props.children); + } + function PlainTextLink({ children, className, ...rest }) { + const classes = ["text-link-as-button"]; + if (className) + classes.push(className); + return /* @__PURE__ */ y("a", { href: "javascript:void(0)", className: classes.join(" "), draggable: false, ...rest }, children); + } + + // shared/js/ui/components/toggle.jsx + function ProtectionToggle(props) { + const [toggleState, toggle] = useToggleState(props.model, props.toggle); + const altText = ns.site("updatingProtectionList.title"); + return /* @__PURE__ */ y("div", { class: `site-info-toggle ${toggleState.active ? "is-active" : ""}` }, /* @__PURE__ */ y("p", { class: "site-info__protection" }, /* @__PURE__ */ y("span", { role: "textbox", dangerouslySetInnerHTML: { __html: toggleState.text } })), /* @__PURE__ */ y("div", { class: "site-info__toggle-container" }, toggleState.toggled && /* @__PURE__ */ y("img", { src: "../img/spinner.svg", className: "toggle-spinner", alt: altText }), !toggleState.toggled && /* @__PURE__ */ y(ToggleButton, { toggleState, onToggle: toggle }))); + } + function useToggleState(model, toggle) { + const [state, setState] = h2(() => { + const toggleState = { + text: ns.site("protectionsEnabled.title"), + active: true, + disabled: false, + label: "", + toggled: false, + sideEffects: false + }; + if (!model.protectionsEnabled) { + toggleState.text = ns.site("protectionsDisabled.title"); + toggleState.active = false; + } + if (model.isBroken) { + if (!isBrowser()) { + toggleState.active = false; + toggleState.disabled = true; + } + } + const labelEnabled = ns.site("enableProtectionsSwitch.title"); + const labelDisabled = ns.site("disableProtectionsSwitch.title"); + toggleState.label = toggleState.active ? labelDisabled : labelEnabled; + return toggleState; + }); + p2(() => { + if (!state.sideEffects) + return; + const isReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches === true; + const timeout = isReducedMotion ? 0 : 300; + const int = setTimeout(() => { + toggle(); + if (model.features.spinnerFollowingProtectionsToggle) { + setState((prev) => { + return { ...prev, toggled: true }; + }); + } + }, timeout); + return () => { + clearTimeout(int); + }; + }, [state.active, state.sideEffects]); + function toggleInternal() { + setState((prev) => { + return { ...prev, active: !prev.active, sideEffects: true }; + }); + } + return [state, toggleInternal]; + } + function ToggleButton(props) { + const { toggleState } = props; + const labelEnabled = ns.site("enableProtectionsSwitch.title"); + const labelDisabled = ns.site("disableProtectionsSwitch.title"); + const label = toggleState.active ? labelDisabled : labelEnabled; + return /* @__PURE__ */ y(DefaultToggleButton, { toggleState, label, onToggle: props.onToggle }); + } + function DefaultToggleButton(props) { + const { toggleState, label } = props; + return /* @__PURE__ */ y( + "button", + { + class: "toggle-button", + type: "button", + role: "switch", + "aria-checked": toggleState.active, + "aria-label": label, + disabled: toggleState.disabled, + onClick: props.onToggle + }, + /* @__PURE__ */ y("div", { class: "toggle-button__track" }), + /* @__PURE__ */ y("div", { class: "toggle-button__handle" }) + ); + } + + // shared/js/ui/templates/protection-header.js + var ProtectionContext = G( + /** @type {{state: UIState, setState: (st: UIState) => void; model: MigrationModel}} */ + {} + ); + function ProtectionHeader({ model, initialState, toggle, children, ...rest }) { + let initial; + if (initialState) { + initial = initialState; + } else { + if (model.isBroken || model.isAllowlisted) { + initial = "form-trigger"; + } else { + initial = "help-trigger"; + } + } + const [state, setState] = h2( + /** @type {UIState} */ + initial + ); + return /* @__PURE__ */ y("div", { ...rest }, /* @__PURE__ */ y("div", { class: "card-list--bordered" }, model.isBroken && /* @__PURE__ */ y(HeaderDisabled, { model, state, toggle }), !model.isBroken && /* @__PURE__ */ y(HeaderDefault, { model, state, toggle })), /* @__PURE__ */ y( + ProtectionContext.Provider, + { + value: { + state, + setState, + model + } + }, + children + )); + } + function HeaderDefault(props) { + const text = ns.site("websiteNotWorkingAdvice.title"); + const showHelp = props.state === "site-not-working" && !props.model.isAllowlisted; + return /* @__PURE__ */ y("div", { className: "protection-toggle" }, /* @__PURE__ */ y("div", { className: "protection-toggle__row" }, /* @__PURE__ */ y(ProtectionToggle, { model: props.model, toggle: props.toggle })), showHelp && /* @__PURE__ */ y("div", { className: "protection-toggle__row protection-toggle__row--alt" }, text)); + } + function HeaderDisabled(props) { + let text = i18n.t("site:protectionsDisabledRemote.title"); + if (props.model.isDenylisted) { + text = i18n.t("site:protectionsDisabledRemoteOverride.title"); + } + return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y("div", { className: "padding-x padding-y--reduced" }, /* @__PURE__ */ y(ProtectionToggle, { model: props.model, toggle: props.toggle })), /* @__PURE__ */ y("div", { className: "note note--nested" }, text)); + } + + // v2/components/protection-header.jsx + function ProtectionHeader2() { + const { push } = useNav(); + const data = useData(); + const onToggle = useToggle(); + const fetcher = useFetcher(); + const { breakageScreen } = useFeatures(); + const featureSettings2 = useFeatureSettings(); + return /* @__PURE__ */ y("div", { "data-testid": "protectionHeader" }, /* @__PURE__ */ y(ProtectionHeader, { model: data, toggle: onToggle }, /* @__PURE__ */ y("div", { className: "text--center" }, /* @__PURE__ */ y( + TextLink, + { + onClick: () => { + fetcher(new CheckBrokenSiteReportHandledMessage()).then(() => { + if (featureSettings2.webBreakageForm.state === "enabled") { + push(breakageScreen); + } + }).catch(console.error); + }, + rounded: true + }, + ns.site("websiteNotWorkingPrompt.title") + )))); + } + + // shared/js/ui/views/fire-dialog.js + var import_nanohtml8 = __toESM(require_browser()); + var import_raw3 = __toESM(require_raw_browser()); + function fireSummaryTemplate(selectedOption) { + const { descriptionStats } = selectedOption; + let template2 = "firebutton:summary"; + if (descriptionStats.clearHistory && descriptionStats.openTabs) { + template2 += "ClearTabsHistory"; + } else if (descriptionStats.clearHistory && !descriptionStats.openTabs) { + template2 += "ClearHistory"; + } else if (!descriptionStats.clearHistory && descriptionStats.openTabs) { + template2 += "ClearTabs"; + } else { + template2 += "ClearCookies"; + } + if (descriptionStats.site) { + template2 += "Site"; + } else if (descriptionStats.duration === "all") { + template2 += "All"; + } else { + template2 += "Duration"; + } + template2 += ".title"; + return import_nanohtml8.default`
    +

    + ${(0, import_raw3.default)( + i18n.t(template2, { + durationDesc: i18n.t("firebutton:historyDuration.title", { duration: descriptionStats.duration }), + ...descriptionStats + }) + )} +

    + ${descriptionStats.site && descriptionStats.clearHistory ? import_nanohtml8.default`

    ${i18n.t("firebutton:historyAndDownloadsNotAffected.title")}

    ` : null} + ${descriptionStats.openTabs && descriptionStats.pinnedTabs ? import_nanohtml8.default`

    + ${(0, import_raw3.default)(i18n.t("firebutton:summaryPinnedIgnored.title", { tabs: descriptionStats.pinnedTabs }))} +

    ` : null} +
    `; + } + + // v2/components/fire-dialog.jsx + function FireProvider({ onCancel }) { + const [fireOptions, setFireOptions] = h2( + /** @type {null | FireOption[]} */ + null + ); + const fetcher = useFetcher(); + p2(() => { + const msg = new FetchBurnOptions(); + fetcher(msg).then((resp) => { + setFireOptions(resp.options); + }).catch(console.error); + }, [fetcher]); + function onUpdate(index) { + if (!fireOptions) + return; + const selectedOption = index; + const opts = fireOptions[selectedOption]; + fetcher(new SetBurnDefaultOption(opts.name)).catch(console.error); + } + function onBurn(index) { + if (!fireOptions) + return; + const selectedOption = index; + const opts = fireOptions[selectedOption].options; + fetcher(new BurnMessage( + /** @type {any} */ + opts + )).then(() => { + onCancel(); + }); + } + if (fireOptions === null) + return null; + return /* @__PURE__ */ y(FireDialog, { fireOptions, onUpdate, onCancel, onBurn }); + } + function FireDialog({ fireOptions, onUpdate, onCancel, onBurn }) { + if (!fireOptions) { + return /* @__PURE__ */ y("dialog", { id: "fire-button-container" }); + } + let selectedOptionIndex = fireOptions.findIndex(({ selected }) => selected); + if (selectedOptionIndex < 0) { + selectedOptionIndex = 0; + } + const [value, setValue] = h2(selectedOptionIndex); + const selectedOption = fireOptions[value]; + const selectOptions = fireOptions.map(({ name }, index) => /* @__PURE__ */ y("option", { value: index }, i18n.t(`firebutton:option${name}.title`))); + const summary = fireSummaryTemplate(selectedOption); + function onChange(e3) { + setValue(Number(e3.target.value)); + onUpdate(Number(e3.target.value)); + } + return /* @__PURE__ */ y("dialog", { id: "fire-button-container", open: true }, /* @__PURE__ */ y("div", { id: "fire-button-content" }, /* @__PURE__ */ y("span", { id: "fire-button-header" }, /* @__PURE__ */ y("img", { src: "../img/fire-button-header.svg" }), /* @__PURE__ */ y("h3", null, selectedOption.descriptionStats.openTabs > 0 ? i18n.t("firebutton:fireDialogHeader.title") : i18n.t("firebutton:fireDialogHeaderNoTabs.title"))), /* @__PURE__ */ y("select", { id: "fire-button-opts", onChange, value }, selectOptions), /* @__PURE__ */ y(DomNode, null, summary), /* @__PURE__ */ y("div", { id: "fire-button-row" }, /* @__PURE__ */ y("button", { id: "fire-button-cancel", onClick: onCancel }, i18n.t("firebutton:cancel.title")), /* @__PURE__ */ y("button", { id: "fire-button-burn", onClick: () => onBurn(value) }, i18n.t("firebutton:clearData.title"))))); + } + + // v2/components/search-bar.jsx + function SearchBar() { + const data = useData(); + const fetcher = useFetcher(); + const showFireButton = data.fireButton?.enabled === true; + const [focussed, setFocussed] = h2(false); + const [fireDialogOpen, setFireDialogOpen] = h2(false); + function openSettings() { + const msg = new OpenOptionsMessage(); + fetcher(msg).catch(console.error); + } + function openFire() { + setFireDialogOpen(true); + } + function doSearch(e3) { + e3.preventDefault(); + const values = Object.fromEntries(new FormData(e3.target)); + if (!values.q || !(typeof values.q === "string")) { + return console.warn("missing value"); + } + const msg = new SearchMessage({ term: values.q }); + fetcher(msg).catch(console.error); + } + const fireButton = showFireButton ? /* @__PURE__ */ y("button", { type: "button", class: "fire-button", onClick: openFire }, /* @__PURE__ */ y(FireIcon, null)) : null; + if (!data.tab.search) + return null; + return /* @__PURE__ */ y("div", { className: "search token-search-input" }, /* @__PURE__ */ y("form", { className: "search-form", name: "x", "data-test-id": "search-form", "data-focussed": focussed, onSubmit: doSearch }, /* @__PURE__ */ y( + "input", + { + type: "text", + autoComplete: "off", + autoFocus: true, + placeholder: ns.site("searchPlaceholder.title"), + name: "q", + className: "search-form__input", + defaultValue: "", + onInput: (e3) => setFocussed(e3.target.value.length > 0), + onBlur: () => setFocussed(false), + onFocus: (e3) => setFocussed(e3.target.value.length > 0) + } + ), /* @__PURE__ */ y("button", { className: "search-form__go", type: "submit", "aria-label": ns.site("searchGoButton.title") }, /* @__PURE__ */ y(LoupeIcon, null))), fireButton, fireDialogOpen ? /* @__PURE__ */ y(FireProvider, { onCancel: () => setFireDialogOpen(false) }) : null, /* @__PURE__ */ y("button", { type: "button", className: "cog-button", "aria-label": ns.site("optionsButton.title"), onClick: openSettings }, /* @__PURE__ */ y(CogIcon, null))); + } + function LoupeIcon() { + return /* @__PURE__ */ y("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y("rect", { class: "loupe-handle", x: "11.5", y: "12.9142", width: "2", height: "6", rx: "1", transform: "rotate(-45 11.5 12.9142)" }), /* @__PURE__ */ y( + "path", + { + class: "loupe-glass", + d: "M12.6976 5.27292C14.7478 7.32317 14.7478 10.6473 12.6976 12.6975C10.6473 14.7478 7.32322 14.7478 5.27297 12.6975C3.22272 10.6473 3.22272 7.32317 5.27297 5.27292C7.32322 3.22267 10.6473 3.22267 12.6976 5.27292Z", + "stroke-width": "1.5" + } + )); + } + function CogIcon() { + return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y( + "path", + { + class: "settings-cog", + "fill-rule": "evenodd", + "clip-rule": "evenodd", + d: "M3.43351 13.1462C3.06364 14.0391 3.48767 15.0628 4.3806 15.4327L5.30448 15.8154C6.19741 16.1853 7.2211 15.7612 7.59096 14.8683L7.84778 14.2483C7.89842 14.2495 7.94918 14.2501 8.00007 14.2501C8.05068 14.2501 8.10118 14.2495 8.15154 14.2483L8.40831 14.8682C8.77818 15.7611 9.80187 16.1852 10.6948 15.8153L11.6187 15.4326C12.5116 15.0628 12.9356 14.0391 12.5658 13.1461L12.3093 12.527C12.3828 12.457 12.4546 12.3853 12.5247 12.3118L13.1437 12.5682C14.0366 12.9381 15.0603 12.514 15.4302 11.6211L15.8129 10.6972C16.1827 9.8043 15.7587 8.7806 14.8658 8.41074L14.2482 8.15493C14.2494 8.10345 14.2501 8.05185 14.2501 8.00011C14.2501 7.94964 14.2495 7.89928 14.2483 7.84905L14.8659 7.59324C15.7588 7.22337 16.1828 6.19968 15.8129 5.30675L15.4303 4.38287C15.0604 3.48994 14.0367 3.06592 13.1438 3.43578L12.5273 3.69115C12.4568 3.61712 12.3845 3.54482 12.3105 3.47432L12.5658 2.85787C12.9357 1.96494 12.5117 0.94124 11.6188 0.571378L10.6949 0.188694C9.80195 -0.181168 8.77825 0.242858 8.40839 1.13579L8.15316 1.75196C8.10226 1.75073 8.05122 1.75011 8.00007 1.75011C7.94864 1.75011 7.89734 1.75074 7.84616 1.75198L7.59089 1.13569C7.22102 0.242766 6.19733 -0.181263 5.3044 0.1886L4.38052 0.571284C3.4876 0.941146 3.06357 1.96484 3.43343 2.85777L3.68905 3.47488C3.61513 3.54532 3.54293 3.61755 3.47254 3.69151L2.85533 3.43585C1.9624 3.06599 0.938705 3.49002 0.568843 4.38295L0.186159 5.30683C-0.183704 6.19975 0.240324 7.22345 1.13325 7.59331L1.75185 7.84955C1.75067 7.89961 1.75007 7.9498 1.75007 8.00011C1.75007 8.05168 1.7507 8.10312 1.75194 8.15443L1.13335 8.41066C0.240417 8.78052 -0.18361 9.80422 0.186252 10.6971L0.568936 11.621C0.938798 12.514 1.96249 12.938 2.85542 12.5681L3.47512 12.3114C3.54507 12.3848 3.6168 12.4565 3.69022 12.5265L3.43351 13.1462ZM1.61161 6.43846C1.35648 6.33279 1.23533 6.0403 1.34101 5.78518L1.72369 4.8613C1.82937 4.60618 2.12185 4.48503 2.37697 4.5907L3.47809 5.0468C3.69752 5.13769 3.94855 5.05988 4.09713 4.87459C4.32641 4.58865 4.58647 4.32845 4.87227 4.099C5.05738 3.95039 5.13507 3.69948 5.04422 3.48016L4.58828 2.37941C4.4826 2.12429 4.60375 1.83181 4.85888 1.72613L5.78276 1.34345C6.03788 1.23777 6.33036 1.35893 6.43604 1.61405L6.89159 2.71385C6.98246 2.93322 7.21488 3.05571 7.45092 3.02993C7.63126 3.01022 7.81448 3.00011 8.00007 3.00011C8.18541 3.00011 8.3684 3.0102 8.54851 3.02985C8.78452 3.0556 9.01691 2.93311 9.10776 2.71377L9.56324 1.61414C9.66891 1.35902 9.9614 1.23787 10.2165 1.34354L11.1404 1.72623C11.3955 1.8319 11.5167 2.12439 11.411 2.37951L10.9553 3.47967C10.8644 3.69901 10.9422 3.94995 11.1273 4.09856C11.4132 4.32802 11.6734 4.58826 11.9027 4.87425C12.0513 5.05952 12.3023 5.13731 12.5217 5.04642L13.6221 4.59063C13.8773 4.48495 14.1697 4.6061 14.2754 4.86122L14.6581 5.7851C14.7638 6.04023 14.6426 6.33271 14.3875 6.43839L13.2866 6.89438C13.0674 6.98521 12.9449 7.21748 12.9705 7.45343C12.99 7.63298 13.0001 7.81537 13.0001 8.00011C13.0001 8.18597 12.9899 8.36945 12.9702 8.55005C12.9443 8.78611 13.0668 9.01859 13.2862 9.10947L14.3874 9.56559C14.6425 9.67126 14.7637 9.96375 14.658 10.2189L14.2753 11.1427C14.1696 11.3979 13.8772 11.519 13.622 11.4133L12.5195 10.9566C12.3002 10.8658 12.0493 10.9435 11.9007 11.1285C11.6715 11.4139 11.4117 11.6736 11.1262 11.9026C10.941 12.0511 10.8632 12.3021 10.9541 12.5215L11.4109 13.6245C11.5166 13.8796 11.3954 14.1721 11.1403 14.2778L10.2164 14.6604C9.96132 14.7661 9.66884 14.645 9.56316 14.3898L9.1062 13.2866C9.01536 13.0673 8.78307 12.9449 8.54711 12.9705C8.36745 12.9901 8.18493 13.0001 8.00007 13.0001C7.81497 13.0001 7.63221 12.9901 7.45233 12.9705C7.21634 12.9447 6.984 13.0672 6.89316 13.2865L6.43611 14.3899C6.33044 14.6451 6.03796 14.7662 5.78283 14.6605L4.85895 14.2779C4.60383 14.1722 4.48268 13.8797 4.58836 13.6246L5.04545 12.521C5.13632 12.3017 5.05857 12.0507 4.87337 11.9021C4.58799 11.6731 4.32826 11.4135 4.09918 11.1282C3.95057 10.9431 3.69967 10.8654 3.48037 10.9563L2.37707 11.4133C2.12194 11.5189 1.82946 11.3978 1.72379 11.1427L1.3411 10.2188C1.23543 9.96367 1.35658 9.67119 1.6117 9.56551L2.71385 9.10898C2.93323 9.01811 3.05572 8.78566 3.02992 8.54962C3.01019 8.36916 3.00007 8.18582 3.00007 8.00011C3.00007 7.81552 3.01007 7.63327 3.02957 7.45386C3.0552 7.21793 2.93271 6.98568 2.71345 6.89486L1.61161 6.43846ZM6.12508 8.00008C6.12508 6.96455 6.96455 6.12508 8.00008 6.12508C9.03562 6.12508 9.87508 6.96455 9.87508 8.00008C9.87508 9.03562 9.03562 9.87508 8.00008 9.87508C6.96455 9.87508 6.12508 9.03562 6.12508 8.00008ZM8.00008 4.87508C6.27419 4.87508 4.87508 6.27419 4.87508 8.00008C4.87508 9.72597 6.27419 11.1251 8.00008 11.1251C9.72597 11.1251 11.1251 9.72597 11.1251 8.00008C11.1251 6.27419 9.72597 4.87508 8.00008 4.87508Z", + "fill-opacity": "0.8" + } + )); + } + function FireIcon() { + return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y( + "path", + { + class: "fire-icon", + "fill-rule": "evenodd", + "clip-rule": "evenodd", + d: "M6.51018 15.53C5.52187 15.1832 4.62831 14.6102 3.90082 13.8566C3.17333 13.1031 2.63205 12.1899 2.32018 11.19C2.00674 10.2021 1.95815 9.14927 2.17926 8.1367C2.40038 7.12413 2.88345 6.18736 3.58018 5.42005C3.55105 5.89155 3.6297 6.36349 3.81018 6.80005C4.02356 7.25295 4.32236 7.6604 4.69018 8.00005C4.69018 8.00005 4.12018 6.49005 5.50018 4.00005C6.05384 3.11404 6.78312 2.35083 7.64306 1.75747C8.50299 1.16412 9.47535 0.7532 10.5002 0.550049C9.98701 1.37608 9.80819 2.36673 10.0002 3.32005C10.3002 4.32005 10.7902 4.86005 11.3402 6.32005C11.6533 7.02128 11.8102 7.78217 11.8002 8.55005C11.8926 8.00549 12.0787 7.48106 12.3502 7.00005C12.8054 6.23481 13.5124 5.65154 14.3502 5.35005C13.9624 6.24354 13.8043 7.21983 13.8902 8.19005C14.1302 9.57207 14.0026 10.9929 13.5202 12.31C13.1428 13.1433 12.5799 13.8792 11.8745 14.4616C11.1691 15.0439 10.3398 15.4573 9.45018 15.67C10.0364 15.44 10.5354 15.0313 10.8765 14.5018C11.2175 13.9723 11.3832 13.349 11.3502 12.72C11.252 11.9769 10.8985 11.2911 10.3502 10.78C10.0002 12.67 9.00018 12.89 9.00018 12.89C9.38752 12.0753 9.62788 11.1985 9.71018 10.3C9.76455 9.73167 9.71025 9.15813 9.55018 8.61005C9.35806 7.62829 8.80504 6.75416 8.00018 6.16005C8.05821 6.68407 8.0102 7.21441 7.85902 7.7195C7.70784 8.22458 7.45657 8.69408 7.12018 9.10005C6.31018 10.36 4.94018 11.29 5.00018 13.17C5.02637 13.6604 5.17925 14.1356 5.44391 14.5492C5.70856 14.9628 6.07594 15.3008 6.51018 15.53Z", + "fill-opacity": "0.84" + } + )); + } + + // v2/components/email.jsx + init_lib(); + var formatAddress = (address) => address + "@duck.com"; + var EmailContext = G({ + /** @type {EmailState} */ + state: { + state: "unknown", + alias: null + }, + /** @type {() => void} */ + copyAlias: () => { + throw new Error("todo: implement refresh"); + } + }); + function EmailProvider({ children }) { + const data = useData(); + const fetcher = useFetcher(); + const hasAlias = typeof data.emailProtectionUserData?.nextAlias === "string"; + const initialState = { + state: hasAlias ? "idle" : "unknown", + alias: hasAlias ? data.emailProtectionUserData?.nextAlias : null + }; + const [state, dispatch] = s2((state2, action) => { + switch (state2.state) { + case "added": { + switch (action.type) { + case "update": { + return { + ...state2, + alias: action.alias + }; + } + case "reset": { + return { + ...state2, + state: ( + /** @type {const} */ + "idle" + ) + }; + } + default: + return state2; + } + } + case "idle": + case "unknown": + switch (action.type) { + case "copy": { + return { + ...state2, + state: ( + /** @type {const} */ + "added" + ) + }; + } + } + break; + } + return state2; + }, initialState); + function copyAlias() { + dispatch({ type: "copy" }); + if (!state.alias) { + return console.warn("missing state.alias"); + } + navigator.clipboard?.writeText(formatAddress(state.alias)); + const msg = new RefreshEmailAliasMessage(); + fetcher(msg).then((resp) => { + console.log("--", resp); + const response = z3.object({ + privateAddress: z3.string().optional() + }); + const parsed = response.safeParse(resp); + if (!parsed.success) { + console.warn("response did not contain a valid private address", resp); + dispatch({ + type: "update", + alias: null + }); + } else { + if (!parsed.data.privateAddress) { + return console.warn("missing `privateAddress`"); + } + dispatch({ + type: "update", + alias: parsed.data.privateAddress + }); + } + }).catch((e3) => console.error("error refreshing", e3)).finally(() => { + setTimeout(() => { + dispatch({ type: "reset" }); + }, 2e3); + }); + } + if (state.state === "unknown") + return null; + return /* @__PURE__ */ y(EmailContext.Provider, { value: { state, copyAlias } }, children); + } + function EmailBar() { + const { state, copyAlias } = q2(EmailContext); + const text = state.state === "idle" ? i18n.t("site:createNewDuckAddress.title") : i18n.t("site:createNewDuckAddressCopied.title"); + const icon = state.state === "idle" ? /* @__PURE__ */ y(WandIcon, null) : /* @__PURE__ */ y(CheckMarkIcon, null); + return /* @__PURE__ */ y("div", { id: "email-alias-container" }, /* @__PURE__ */ y("div", { className: "js-email-alias email-alias token-body-em" }, /* @__PURE__ */ y( + "button", + { + className: "email-alias__button", + type: "button", + "data-state": state.state, + disabled: state.state === "added", + onClick: copyAlias + }, + icon, + /* @__PURE__ */ y("span", { className: "email-alias__text" }, text) + ))); + } + function WandIcon() { + return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ y("path", { d: "M10.4998 0.75C10.4998 0.335786 10.164 0 9.74976 0C9.33554 0 8.99976 0.335786 8.99976 0.75V3.25C8.99976 3.66421 9.33554 4 9.74976 4C10.164 4 10.4998 3.66421 10.4998 3.25V0.75Z" }), /* @__PURE__ */ y("path", { d: "M10.4998 9.75C10.4998 9.33579 10.164 9 9.74976 9C9.33554 9 8.99976 9.33579 8.99976 9.75V12.25C8.99976 12.6642 9.33554 13 9.74976 13C10.164 13 10.4998 12.6642 10.4998 12.25V9.75Z" }), /* @__PURE__ */ y("path", { d: "M15.9998 6.25C15.9998 6.66421 15.664 7 15.2498 7H12.7498C12.3355 7 11.9998 6.66421 11.9998 6.25C11.9998 5.83579 12.3355 5.5 12.7498 5.5H15.2498C15.664 5.5 15.9998 5.83579 15.9998 6.25Z" }), /* @__PURE__ */ y("path", { d: "M6.24976 7C6.66397 7 6.99976 6.66421 6.99976 6.25C6.99976 5.83579 6.66397 5.5 6.24976 5.5H3.74976C3.33554 5.5 2.99976 5.83579 2.99976 6.25C2.99976 6.66421 3.33554 7 3.74976 7H6.24976Z" }), /* @__PURE__ */ y("path", { d: "M14.2801 10.7803C13.9872 11.0732 13.5123 11.0732 13.2194 10.7803L11.4694 9.03033C11.1765 8.73744 11.1765 8.26256 11.4694 7.96967C11.7623 7.67678 12.2372 7.67678 12.5301 7.96967L14.2801 9.71967C14.573 10.0126 14.573 10.4874 14.2801 10.7803Z" }), /* @__PURE__ */ y("path", { d: "M6.71942 4.28033C7.01231 4.57322 7.48719 4.57322 7.78008 4.28033C8.07297 3.98744 8.07297 3.51256 7.78008 3.21967L6.03008 1.46967C5.73719 1.17678 5.26231 1.17678 4.96942 1.46967C4.67653 1.76256 4.67653 2.23744 4.96942 2.53033L6.71942 4.28033Z" }), /* @__PURE__ */ y("path", { d: "M11.4694 4.53032C11.1765 4.23743 11.1765 3.76256 11.4694 3.46966L13.2194 1.71966C13.5123 1.42677 13.9872 1.42677 14.2801 1.71966C14.573 2.01256 14.573 2.48743 14.2801 2.78032L12.5301 4.53032C12.2372 4.82322 11.7623 4.82322 11.4694 4.53032Z" }), /* @__PURE__ */ y("path", { d: "M2.28296 12.658L9.24784 5.69307C9.54074 5.40018 10.0156 5.40018 10.3085 5.69307V5.69307C10.6014 5.98597 10.6014 6.46084 10.3085 6.75373L3.34362 13.7186L2.28296 12.658Z" }), /* @__PURE__ */ y("path", { d: "M0.243221 15.7588C-0.0496725 15.466 -0.0496726 14.9911 0.243221 14.6982L1.75195 13.1895L2.81261 14.2501L1.30388 15.7588C1.01099 16.0517 0.536114 16.0517 0.243221 15.7588V15.7588Z" })); + } + function CheckMarkIcon() { + return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ y("path", { d: "M11.809 6.2501C12.0851 5.94141 12.0588 5.46727 11.7501 5.19108C11.4414 4.91488 10.9673 4.94122 10.6911 5.24991L7.0255 9.34675L5.33049 7.27508C5.06819 6.9545 4.59568 6.90724 4.27509 7.16954C3.95451 7.43183 3.90726 7.90435 4.16955 8.22494L6.41955 10.9749C6.55833 11.1446 6.76436 11.245 6.98346 11.2498C7.20256 11.2547 7.41282 11.1634 7.55895 11.0001L11.809 6.2501Z" }), /* @__PURE__ */ y( + "path", + { + "fill-rule": "evenodd", + "clip-rule": "evenodd", + d: "M8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0ZM1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8C14.5 11.5899 11.5899 14.5 8 14.5C4.41015 14.5 1.5 11.5899 1.5 8Z" + } + )); + } + + // shared/js/ui/templates/site.js + var import_nanohtml9 = __toESM(require_browser()); + function localizePermissions(permissions) { + if (!Array.isArray(permissions) || permissions.length === 0) { + return []; + } + const updatedPermissions = JSON.parse(JSON.stringify(permissions)); + return updatedPermissions.map((perm) => { + const permKey = `permissions:${perm.key}.title`; + if (i18n.exists(permKey)) { + perm.title = i18n.t(permKey); + } + perm.options = perm.options.map((option) => { + const optionKey = `permissions:${option.id}.title`; + if (i18n.exists(optionKey)) { + option.title = i18n.t(optionKey); + } + return option; + }); + return perm; + }); + } + + // v2/components/page-outer.jsx + function PageOuter({ children }) { + return /* @__PURE__ */ y("div", { class: "page-outer" }, children); + } + + // v2/components/permissions.jsx + function Permissions() { + const data = useData(); + if (!data.permissions || data.permissions.length === 0) { + return null; + } + const localizedPerms = localizePermissions(data.permissions); + const fetcher = useFetcher(); + function update(id, value) { + console.log(id, value); + fetcher(new UpdatePermissionMessage({ id, value })).catch((e3) => console.error(e3)); + } + return /* @__PURE__ */ y(PageOuter, null, /* @__PURE__ */ y("div", { className: "site-info__li--manage-permissions" }, localizedPerms.map(({ key: permissionId, title, permission, options }) => { + return /* @__PURE__ */ y("div", { className: "site-info__page-permission" }, /* @__PURE__ */ y("label", null, /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("div", { className: "site-info__page-permission__icon", "data-icon": permissionId }), title), /* @__PURE__ */ y("select", { name: permissionId, onChange: (e3) => update( + permissionId, + /** @type {any} */ + e3.target.value + ) }, options.map(({ id, title: title2 }) => /* @__PURE__ */ y("option", { value: id, selected: permission === id }, title2))))); + }))); + } + + // v2/screens/cta-screen.jsx + function CtaScreen() { + const data = useData(); + const ctas = { + spread: { + title: i18n.t("ctascreens:spreadTitle.title"), + text: i18n.t("ctascreens:spreadText.title"), + icon: heartArrowSvg, + action: /* @__PURE__ */ y("a", { href: "https://duckduckgo.com/spread", target: "_blank", class: "cta__button" }, i18n.t("ctascreens:spreadButton.title")) + }, + email: { + title: i18n.t("ctascreens:emailTitle.title"), + text: i18n.t("ctascreens:emailText.title"), + icon: emailSvg, + action: /* @__PURE__ */ y("a", { href: "https://duckduckgo.com/email", target: "_blank", class: "cta__button" }, i18n.t("ctascreens:spreadButton.title")) + } + }; + const keys = Object.keys(ctas); + const ctaKey = data.emailProtectionUserData?.nextAlias ? "spread" : keys[Math.floor(Math.random() * keys.length)]; + const cta = ctas[ctaKey]; + return /* @__PURE__ */ y("div", { className: "cta-screen page-inner" }, /* @__PURE__ */ y("p", { className: "note token-title-3 text--center" }, i18n.t("ctascreens:protectionsUnavailableNote.title")), /* @__PURE__ */ y("div", { className: "cta text--center" }, /* @__PURE__ */ y("div", { className: "cta__icon", dangerouslySetInnerHTML: { __html: cta.icon() } }), /* @__PURE__ */ y("h1", { className: "cta__title" }, cta.title), /* @__PURE__ */ y("h2", { className: "cta__text" }, cta.text), /* @__PURE__ */ y("div", { className: "cta__action" }, cta.action))); + } + function heartArrowSvg() { + return ` + + + + + + + + + + + + + + + + +`; + } + function emailSvg() { + return ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +`; + } + + // v2/screens/primary-screen.jsx + function PrimaryScreen() { + const status = usePrimaryStatus(); + return /* @__PURE__ */ y("div", { class: "site-info page" }, /* @__PURE__ */ y("div", { className: "page-inner" }, /* @__PURE__ */ y(SearchBar, null), /* @__PURE__ */ y(PrimaryScreenTopNav, null), status === "error" && /* @__PURE__ */ y(ErrorInner, null), status === "cta" && /* @__PURE__ */ y(CtaScreenInner, null), status === "ready" && /* @__PURE__ */ y(PrimaryScreenInner, null), /* @__PURE__ */ y(Footer, null), /* @__PURE__ */ y(Permissions, null))); + } + function Footer() { + return /* @__PURE__ */ y("footer", { className: "footer" }, /* @__PURE__ */ y("div", { className: "padding-x" }, isBrowser() && /* @__PURE__ */ y(EmailProvider, null, /* @__PURE__ */ y(EmailBar, null)))); + } + function PrimaryScreenInner() { + return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y("header", { class: "header" }, /* @__PURE__ */ y(ProtectionHeader2, null)), /* @__PURE__ */ y("div", { class: "header-spacer" }), /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(KeyInsights, null)), /* @__PURE__ */ y("div", { class: "padding-x" }, /* @__PURE__ */ y(MainNav, null))); + } + function PrimaryScreenTopNav() { + const onClose = useClose(); + if (isAndroid()) + return /* @__PURE__ */ y(TopNav, { back: /* @__PURE__ */ y(Back, { onClick: onClose }) }); + if (isIOS()) + return /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Done, { onClick: onClose }) }); + return null; + } + function CtaScreenInner() { + return /* @__PURE__ */ y("div", { class: "padding-x" }, /* @__PURE__ */ y(CtaScreen, null)); + } + function ErrorInner() { + const errorText = i18n.t("site:errorMessage.title"); + return /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y("div", { className: "cta-screen" }, /* @__PURE__ */ y("p", { className: "note token-title-3 text--center" }, errorText))); + } + + // v2/breakage-categories.js + var defaultCategories = () => { + return { + blocked: ns.report("blocked.title"), + layout: ns.report("layout.title"), + "empty-spaces": ns.report("emptySpaces.title"), + paywall: ns.report("paywall.title"), + videos: ns.report("videos.title"), + comments: ns.report("comments.title"), + login: ns.report("login.title"), + shopping: ns.report("shopping.title"), + other: ns.report("other.title") + }; + }; + function createBreakageFeaturesFrom(platformFeatures) { + return { + /** + * @param {Record} [additional] + * @return {[key: string, description: string][]} + */ + categoryList(additional = {}) { + const items = { + ...defaultCategories(), + ...additional + }; + const list = Object.entries(items); + if (platformFeatures.randomisedCategories) { + return shuffle(list); + } + return list; + } + }; + } + function shuffle(arr2) { + let len = arr2.length; + let temp; + let index; + while (len > 0) { + index = Math.floor(Math.random() * len); + len--; + temp = arr2[len]; + arr2[len] = arr2[index]; + arr2[index] = temp; + } + return arr2; + } + + // v2/components/custom-element-loader.jsx + function CustomElementLoader(props) { + const [state, dispatch] = s2(reducer, { status: "idle" }); + p2(() => { + if (state.status === "idle") { + if (window.__ddg_did_load && window.__ddg_did_load.includes(props.element)) { + dispatch({ kind: "skip-loading" }); + } else { + dispatch({ kind: "load-script", element: props.element }); + } + return; + } + if (state.status === "script-ready") { + dispatch({ kind: "load-element" }); + customElements.whenDefined(props.element).then(() => { + if (!window.__ddg_did_load) + window.__ddg_did_load = []; + window.__ddg_did_load.push(props.element); + dispatch({ kind: "element-loaded" }); + }); + } + }, [state.status, props.src, props.element]); + if (state.status === "element-ready") { + return props.children; + } + if (state.status === "script-pending") { + return /* @__PURE__ */ y("script", { src: props.src, onLoad: () => dispatch({ kind: "script-loaded" }) }); + } + return ( + /** @type {any} */ + null + ); + } + function reducer(state, event) { + console.log("incoming", event, "current", state); + switch (state.status) { + case "idle": { + switch (event.kind) { + case "load-script": { + return { ...state, status: ( + /** @type {const} */ + "script-pending" + ) }; + } + case "skip-loading": { + return { ...state, status: ( + /** @type {const} */ + "element-ready" + ) }; + } + } + break; + } + case "script-pending": { + switch (event.kind) { + case "script-loaded": { + return { ...state, status: ( + /** @type {const} */ + "script-ready" + ) }; + } + } + break; + } + case "script-ready": { + switch (event.kind) { + case "load-element": { + return { ...state, status: ( + /** @type {const} */ + "element-pending" + ) }; + } + } + break; + } + case "element-pending": { + switch (event.kind) { + case "element-loaded": { + return { ...state, status: ( + /** @type {const} */ + "element-ready" + ) }; + } + } + } + } + return state; + } + + // v2/components/android-breakage-modal-wrapper.jsx + var DDG_DIALOG_NAME = "ddg-android-breakage-dialog"; + var DDG_DIALOG_PATH = "../public/js/android-breakage-dialog.js"; + function FormSelectElementWithDialog() { + const platformFeatures = useFeatures(); + const randomised = F(() => { + const f3 = createBreakageFeaturesFrom(platformFeatures); + return f3.categoryList(); + }, [platformFeatures]); + const selectRef = _(null); + function onClick(e3) { + e3.preventDefault(); + e3.stopImmediatePropagation(); + const elem = document.querySelector(DDG_DIALOG_NAME); + if (!elem) + return console.warn("could not find custom element", "ddg-android-breakage-dialog"); + if (!selectRef.current) + return console.warn("could not find select ref"); + elem.show(selectRef.current.value); + } + return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y(CustomElementLoader, { src: DDG_DIALOG_PATH, element: DDG_DIALOG_NAME }, /* @__PURE__ */ y( + AndroidBreakageDialogWrapper, + { + items: randomised, + onSelect: (value) => { + if (!selectRef.current) + return; + selectRef.current.value = value; + } + } + )), /* @__PURE__ */ y("div", { className: "form__select breakage-form__input--dropdown", onClick, "data-testid": "select-click-capture" }, /* @__PURE__ */ y("select", { name: "category", ref: selectRef }, /* @__PURE__ */ y("option", { value: "", selected: true, disabled: true }, ns.report("pickYourIssueFromTheList.title")), randomised.map(([key, value]) => { + return /* @__PURE__ */ y("option", { value: key }, value); + })))); + } + function AndroidBreakageDialogWrapper({ items, onSelect }) { + const ref = _(null); + p2(() => { + const controller = new AbortController(); + ref.current?.addEventListener( + "did-select", + (e3) => { + const selection = ( + /** @type {{value: string}} */ + e3.detail + ); + const matched = items.find(([name]) => name === selection.value); + if (!matched) + throw new Error("value did not match a variant"); + const [value] = matched; + onSelect(value); + }, + { signal: controller.signal } + ); + return () => { + return controller.abort(); + }; + }, []); + return /* @__PURE__ */ y( + "ddg-android-breakage-dialog", + { + items, + ref, + title: ns.report("pickYourIssueFromTheList.title"), + cancelText: ns.site("navigationCancel.title"), + okText: ns.site("okDialogAction.title") + } + ); + } + + // v2/screens/breakage-form-screen.jsx + function BreakageFormScreen({ includeToggle }) { + const data = useData(); + const onToggle = useToggle(); + const onClose = useClose(); + const nav = useNav(); + const canPop = nav.canPop(); + const sendReport = useSendReport(); + const platformFeatures = useFeatures(); + const [state, setState] = h2( + /** @type {"idle" | "sent"} */ + "idle" + ); + const icon = largeHeroIcon({ + status: "breakage-form" + }); + let headerText = includeToggle ? ns.report("selectTheOptionDesc.title") : ns.report("selectTheOptionDescV2.title"); + function submit(e3) { + e3.preventDefault(); + const values = Object.fromEntries(new FormData(e3.target)); + sendReport({ + category: String(values.category || ""), + description: String(values.description || "") + }); + setState("sent"); + } + let topNav2 = platformSwitch({ + android: () => /* @__PURE__ */ y(SecondaryTopNav, null, /* @__PURE__ */ y(Title, null, ns.site("websiteNotWorkingCta.title"))), + default: () => /* @__PURE__ */ y(SecondaryTopNav, null) + }); + if (!canPop) { + topNav2 = platformSwitch({ + ios: () => /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Done, { onClick: onClose }) }), + android: () => /* @__PURE__ */ y(TopNav, { back: /* @__PURE__ */ y(Back, { onClick: onClose }) }, /* @__PURE__ */ y(Title, null, ns.site("websiteNotWorkingCta.title"))), + default: () => /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Close, { onClick: onClose }) }) + }); + } + return /* @__PURE__ */ y("div", { className: "breakage-form page-inner" }, topNav2, /* @__PURE__ */ y("div", { className: "breakage-form__inner", "data-state": state }, includeToggle && /* @__PURE__ */ y("div", { class: "header header--breakage" }, /* @__PURE__ */ y( + ProtectionHeader, + { + model: data, + initialState: "site-not-working", + toggle: onToggle, + "data-testid": "breakage-form-protection-header" + } + )), /* @__PURE__ */ y("div", { className: "key-insight key-insight--breakage padding-x-double" }, /* @__PURE__ */ y(DomNode, null, icon), /* @__PURE__ */ y("div", { className: "breakage-form__advise" }, /* @__PURE__ */ y("p", { className: "token-title-3" }, headerText)), /* @__PURE__ */ y("div", { className: "thanks" }, /* @__PURE__ */ y("p", { className: "thanks__primary" }, ns.report("thankYou.title")), /* @__PURE__ */ y("p", { className: "thanks__secondary" }, ns.report("yourReportWillHelpDesc.title")))), /* @__PURE__ */ y("div", { className: "breakage-form__content padding-x-double" }, /* @__PURE__ */ y( + FormElement, + { + onSubmit: submit, + before: platformFeatures.breakageFormCategorySelect === "material-web-dialog" ? /* @__PURE__ */ y(FormSelectElementWithDialog, null) : /* @__PURE__ */ y(DefaultSelectElement, null) + } + )), /* @__PURE__ */ y("div", { className: "breakage-form__footer padding-x-double token-breakage-form-body" }, ns.report("reportsAreAnonymousDesc.title")))); + } + function DefaultSelectElement() { + const platformFeatures = useFeatures(); + const randomised = F(() => { + const f3 = createBreakageFeaturesFrom(platformFeatures); + return f3.categoryList(); + }, [platformFeatures]); + return /* @__PURE__ */ y("div", { className: "form__select breakage-form__input--dropdown" }, /* @__PURE__ */ y("select", { name: "category" }, /* @__PURE__ */ y("option", { value: "", selected: true, disabled: true }, ns.report("pickYourIssueFromTheList.title")), randomised.map(([key, value]) => { + return /* @__PURE__ */ y("option", { value: key }, value); + }))); + } + function FormElement({ onSubmit, before, after, placeholder }) { + let bullet = "\n \u2022 "; + placeholder = placeholder || ns.report("tellUsMoreDesc.title", { bullet }); + return /* @__PURE__ */ y("form", { className: "breakage-form__element", onSubmit }, /* @__PURE__ */ y("div", { className: "form__group" }, before, /* @__PURE__ */ y("textarea", { className: "form__textarea", placeholder, maxLength: 2500, name: "description" }), after), /* @__PURE__ */ y("button", { className: "form__submit token-label-em", type: "submit" }, ns.report("sendReport.title"))); + } + + // shared/js/ui/templates/page-trackers.js + var import_nanohtml11 = __toESM(require_browser()); + + // shared/js/ui/templates/shared/platform-limitations.js + var import_nanohtml10 = __toESM(require_browser()); + function platformLimitations() { + return import_nanohtml10.default`

    ${ns.site("trackerLimitationsNote.title")}

    `; + } + + // shared/js/ui/templates/page-trackers.js + function trackerListWrapper(name, heading, companiesList, bordered) { + return import_nanohtml11.default` +
      + ${heading ? import_nanohtml11.default`
    1. ${heading}
    2. ` : import_nanohtml11.default``} ${companiesList} +
    + `; + } + function renderCompany(company) { + if (company.displayName && company.displayName === "unknown") { + company.displayName = `(${i18n.t("site:trackerNetworkUnknown.title")})`; + } + const slug = company.normalizedName; + const title = company.name || company.displayName; + const titleClasses = [ + "site-info__tracker__icon", + "site-info__tracker__icon--company", + slug[0].toUpperCase(), + "color-" + getColorId(slug), + slug + ]; + const listLabel = i18n.t("site:trackerDomainsForCompany.title", { + companyName: company.displayName + }); + return import_nanohtml11.default`
  • +

    + + ${company.displayName} +

    +
      + ${Object.keys(company.urls).map((urlHostname) => { + const url = company.urls[urlHostname]; + const matched = displayCategories[url.category]; + return import_nanohtml11.default`
    1. +

      ${urlHostname}

      + ${matched ? import_nanohtml11.default`
      ${i18n.t(matched)}
      ` : ""} +
    2. `; + })} +
    +
  • `; + } + function renderSections(sections) { + const output2 = sections.filter((section) => section.companies.length > 0).map((section) => { + const companiesList = section.companies.map((company) => renderCompany(company)); + const sectionHeading = section.heading(); + return trackerListWrapper(section.name, sectionHeading, companiesList, section.bordered); + }); + return output2; + } + function sectionsFromSiteTrackers(site2) { + const { blocked } = site2.tab.requestDetails; + const sections = renderSections([ + { + name: "blocked", + heading: () => null, + companies: blocked.sortedByPrevalence(), + bordered: true + } + ]); + return sections; + } + + // v2/screens/trackers-screen.jsx + function TrackersScreen() { + const data = useData(); + const ref = useRippleChildren(data.count); + return /* @__PURE__ */ y("div", { className: "site-info card page-inner", "data-page": "trackers" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double", ref }, /* @__PURE__ */ y(DomNode, { key: data.count }, heroFromTabTrackers(data.tab.requestDetails, data.protectionsEnabled))), /* @__PURE__ */ y("div", { className: "padding-x-double", "aria-label": "List of Tracker Companies" }, sectionsFromSiteTrackers(data).map((el, index) => { + return /* @__PURE__ */ y(DomNode, { key: String(data.count) + String(index) }, el); + })), data.tab.platformLimitations ? /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, platformLimitations())) : /* @__PURE__ */ y("div", null)); + } + + // shared/js/ui/templates/page-non-trackers.js + var import_nanohtml12 = __toESM(require_browser()); + function sectionsFromSiteNonTracker(site2) { + const requestDetails = site2.tab.requestDetails; + const onlyAllowedNonTrackers = requestDetails.matches(site2.protectionsEnabled, [ + states.protectionsOn_allowedNonTrackers, + states.protectionsOff_allowedNonTrackers, + states.protectionsOn_blocked_allowedNonTrackers + ]); + if (!site2.protectionsEnabled) { + return renderSections([ + { + name: "protectionsDisabled", + heading: () => ns.site("sectionHeadingProtectionsDisabled.title"), + companies: requestDetails.all.sortedByPrevalence(), + bordered: false + } + ]); + } + return renderSections([ + { + name: "adAttribution", + heading: () => import_nanohtml12.default` +
    +

    ${ns.site("sectionHeadingAdAttribution.title", { domain: site2.tab.domain })}

    + ${adAttributionLink()} +
    + `, + companies: requestDetails.allowed.adClickAttribution.sortedByPrevalence() + }, + { + name: "ignored (rule exceptions)", + heading: () => ns.site("sectionHeadingIgnore.title"), + companies: requestDetails.allowed.ruleException.sortedByPrevalence() + }, + { + name: "firstParty", + heading: () => ns.site("sectionHeadingFirstParty.title", { domain: site2.tab.domain }), + companies: requestDetails.allowed.ownedByFirstParty.sortedByPrevalence() + }, + { + name: "thirdParty", + heading: () => { + if (onlyAllowedNonTrackers) { + return null; + } + return ns.site("sectionHeadingThirdParty.title"); + }, + companies: requestDetails.allowed.otherThirdPartyRequest.sortedByPrevalence(), + bordered: onlyAllowedNonTrackers + } + ]); + } + + // v2/screens/non-trackers-screen.jsx + function NonTrackersScreen() { + const data = useData(); + const ref = useRippleChildren(data.count); + return /* @__PURE__ */ y("div", { className: "site-info card page-inner", "data-page": "non-trackers" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double", ref }, /* @__PURE__ */ y(DomNode, { key: data.count }, heroFromTabNonTrackers(data.tab.requestDetails, data.protectionsEnabled))), /* @__PURE__ */ y("div", { className: "padding-x-double", "aria-label": "List of Tracker Companies" }, sectionsFromSiteNonTracker(data).map((el, index) => { + return /* @__PURE__ */ y(DomNode, { key: String(data.count) + String(index) }, el); + })), data.tab.platformLimitations && /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, platformLimitations()))); + } + + // v2/screens/consent-managed-screen.jsx + function ConsentManagedScreen({ cosmetic }) { + const data = useData(); + const fetcher = useFetcher(); + const summary = cosmetic ? ns.site("cookiesHiddenSummary.title") : ns.site("cookiesMinimizedSummary.title"); + const icon = largeHeroIcon({ + status: cosmetic ? "cookies-hidden" : "cookies-managed" + }); + const hero = heroTemplate({ + icon, + summary, + suffix: "none" + }); + function disable() { + const msg = new OpenSettingsMessages({ + target: "cpm" + }); + fetcher(msg).catch(console.error); + } + return /* @__PURE__ */ y("div", { className: "card page-inner", "data-page": "cookie-prompt" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, hero)), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y("div", { className: "padding-y border--top--inner text--center" }, /* @__PURE__ */ y(DomNode, { key: data.count }, disableInSettingsLink(disable))))); + } + + // shared/js/ui/components/toggle-report/toggle-report-provider.jsx + init_schema_parsers(); + var ToggleReportContext = G({ + value: ( + /** @type {import('../../../../../schema/__generated__/schema.types').ToggleReportScreen} */ + {} + ), + /** @type {() => void} */ + send: () => { + throw new Error("todo implement send"); + }, + /** @type {() => void} */ + reject: () => { + throw new Error("todo implement reject"); + }, + /** @type {() => void} */ + didShowWhatIsSent: () => { + throw new Error("todo implement didShowWhatIsSent"); + }, + /** @type {() => void} */ + didClickSuccessScreen: () => { + throw new Error("todo implement didClickSuccessScreen"); + } + }); + function ToggleReportProvider({ children, model, screen }) { + const initial = { status: "pending" }; + const [state, dispatch] = s2((state2, action) => action, initial); + p2(() => { + const msg = new FetchToggleReportOptions(); + model.fetch(msg)?.then((data) => { + const parsed = toggleReportScreenSchema.safeParse(data); + if (parsed.success) { + dispatch({ status: "ready", value: data }); + } else { + console.group("ToggleReportProvider"); + console.error("the response for FetchToggleReportOptions did not match the schema"); + console.error("response:", data); + console.error("error:", parsed.error.toString()); + console.groupEnd(); + dispatch({ status: "error", error: parsed.error.toString() }); + } + }).catch((e3) => { + dispatch({ status: "error", error: e3.toString() }); + }); + }, [model]); + function send() { + useConnectionCount.pause(); + model.fetch(new SendToggleBreakageReport()); + } + function reject() { + model.fetch(new RejectToggleBreakageReport()); + } + function didShowWhatIsSent() { + model.fetch(new SeeWhatIsSent()); + } + function didClickSuccessScreen() { + model.fetch(new CloseMessage({ eventOrigin: { screen } })); + } + if (state.status === "ready") { + return /* @__PURE__ */ y( + ToggleReportContext.Provider, + { + value: { + value: state.value, + send, + reject, + didShowWhatIsSent, + didClickSuccessScreen + } + }, + children + ); + } + if (state.status === "error") + return /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("p", null, "Something went wrong"), /* @__PURE__ */ y("pre", null, /* @__PURE__ */ y("code", null, state.error))); + return null; + } + + // shared/js/ui/components/toggle-report/use-toggle-report-state.js + function useToggleReportState() { + const { send, reject, didShowWhatIsSent } = q2(ToggleReportContext); + return s2( + (state, action) => { + switch (action) { + case "toggle-ios": { + didShowWhatIsSent(); + return { + ...state, + value: ( + /** @type {const} */ + "animating" + ) + }; + } + case "animation-complete": { + return { + ...state, + value: ( + /** @type {const} */ + "showing" + ) + }; + } + case "toggle": { + const next = state.value === "hiding" ? ( + /** @type {const} */ + "showing" + ) : ( + /** @type {const} */ + "hiding" + ); + if (next === "showing") { + didShowWhatIsSent(); + } + return { + ...state, + value: next + }; + } + case "send": { + send(); + return { + ...state, + value: ( + /** @type {const} */ + "sent" + ) + }; + } + case "reject": { + reject(); + return state; + } + } + return state; + }, + { value: ( + /** @type {'hiding' | 'showing' | 'sent' | 'rejected' | 'animating'} */ + "hiding" + ) } + ); + } + + // shared/js/ui/components/toggle-report.jsx + var import_classnames2 = __toESM(require_classnames()); + + // shared/js/ui/components/button.jsx + function Button({ children, btnSize, variant = "desktop-vibrancy", ...rest }) { + return /* @__PURE__ */ y("button", { type: "button", className: "button token-body", ...rest, "data-variant": variant, "data-size": btnSize }, children); + } + function ButtonBar({ children, layout = "horizontal", ...rest }) { + return /* @__PURE__ */ y("div", { className: "button-bar", "data-layout": layout, ...rest }, children); + } + + // shared/js/ui/components/stack.jsx + var import_classnames = __toESM(require_classnames()); + function Stack({ children, gap, className, ...rest }) { + return /* @__PURE__ */ y("div", { ...rest, className: (0, import_classnames.default)(["stack", className]), style: { gap } }, children); + } + function Scrollable({ children, ...rest }) { + return /* @__PURE__ */ y("div", { className: "scrollable fade-in", ...rest }, children); + } + + // shared/js/ui/components/toggle-report/use-ios-animation.js + function useIosAnimation(state, dispatch) { + p2(() => { + if (platform.name !== "ios" && platform.name !== "android") + return; + if (state.value === "animating") { + const child = ( + /** @type {HTMLDivElement | null} */ + document.querySelector('[data-toggle-report="child"]') + ); + if (!child) + return; + child.addEventListener("transitionend", () => { + dispatch("animation-complete"); + }); + child.style.transform = "translateY(0)"; + } + }, [state.value]); + p2(() => { + if (platform.name !== "ios" && platform.name !== "android") + return; + const child = ( + /** @type {HTMLDivElement | null} */ + document.querySelector('[data-toggle-report="child"]') + ); + const parent = ( + /** @type {HTMLDivElement | null} */ + document.querySelector('[data-toggle-report="parent"]') + ); + if (!child || !parent) + return; + const rs = new ResizeObserver((r3) => { + for (const resizeObserverEntry of r3) { + if (resizeObserverEntry.contentRect.height === 0) + continue; + const childSize = child.clientHeight; + const parentHeight = resizeObserverEntry.contentRect.height - 56; + const offset2 = (parentHeight - childSize) / 2; + child.style.transform = "translateY(" + offset2 + "px)"; + child.dataset.ready = "true"; + setTimeout(() => { + child.style.transition = "all .3s"; + }, 0); + } + }); + rs.observe(parent); + return () => { + rs.disconnect(); + }; + }, []); + } + + // shared/data/text.js + function namedString(item) { + switch (item.id) { + case "openerContext": + return ns.toggleReport("dynamic_openerContext.title"); + case "userRefreshCount": + return ns.toggleReport("dynamic_userRefreshCount.title"); + case "jsPerformance": + return ns.toggleReport("dynamic_jsPerformance.title"); + case "wvVersion": + return ns.toggleReport("dynamic_wvVersion.title"); + case "requests": + return ns.toggleReport("dynamic_requests.title"); + case "features": + return ns.toggleReport("dynamic_features.title"); + case "appVersion": + return ns.toggleReport("dynamic_appVersion.title"); + case "atb": + return ns.toggleReport("dynamic_atb.title"); + case "errorDescriptions": + return ns.toggleReport("dynamic_errorDescriptions.title"); + case "extensionVersion": + return ns.toggleReport("dynamic_extensionVersion.title"); + case "httpErrorCodes": + return ns.toggleReport("dynamic_httpErrorCodes.title"); + case "lastSentDay": + return ns.toggleReport("dynamic_lastSentDay.title"); + case "device": + return ns.toggleReport("dynamic_device.title"); + case "os": + return ns.toggleReport("dynamic_os.title"); + case "reportFlow": + return ns.toggleReport("dynamic_reportFlow.title"); + case "siteUrl": + return ns.toggleReport("dynamic_siteUrl.title"); + case "listVersions": + return ns.toggleReport("dynamic_listVersions.title"); + case "didOpenReportInfo": + return ns.toggleReport("dynamic_didOpenReportInfo.title"); + case "toggleReportCounter": + return ns.toggleReport("dynamic_toggleReportCounter.title"); + case "locale": + return ns.toggleReport("dynamic_locale.title"); + case "description": + return ns.toggleReport("dynamic_description.title"); + } + } + + // shared/js/ui/components/toggle-report/toggle-report-data-list.jsx + function ToggleReportDataList({ rows }) { + return /* @__PURE__ */ y(Stack, { gap: "4px", className: "data-list__content" }, /* @__PURE__ */ y("p", { className: "data-list__heading" }, ns.toggleReport("reportsNoInfoSent.title")), /* @__PURE__ */ y("ul", { className: "data-list" }, rows.map((item) => { + const string = namedString(item); + const additional = item.id === "siteUrl" ? "[" + item.additional?.url + "]" : null; + return /* @__PURE__ */ y("li", { className: "data-list__item" }, /* @__PURE__ */ y("span", { dangerouslySetInnerHTML: { __html: `` } }), string, additional && /* @__PURE__ */ y("strong", { className: "block" }, additional)); + }))); + } + + // shared/js/ui/components/toggle-report/toggle-report-sent.jsx + function ToggleReportSent({ onClick }) { + return /* @__PURE__ */ y("div", { onClick }, /* @__PURE__ */ y(ToggleReportIcon, { variant: "sent" }), /* @__PURE__ */ y(Stack, { gap: "8px" }, /* @__PURE__ */ y("h1", { className: "token-title-2-em text--center" }, ns.report("thankYou.title")), /* @__PURE__ */ y("h2", { className: "token-title-3 text--center text--balance" }, ns.toggleReport("yourReportWillHelpToggleReport.title")))); + } + + // shared/js/ui/components/toggle-report/toggle-report-wrapper.jsx + function ToggleReportWrapper({ children, state }) { + switch (platform.name) { + case "android": + return /* @__PURE__ */ y("div", { className: "padding-x-xl padding-y-third" }, children); + case "ios": + return /* @__PURE__ */ y("div", { className: "padding-x-xl vertically-centered", "data-state": state, "data-toggle-report": "child" }, children); + case "windows": + case "browser": + case "macos": + return /* @__PURE__ */ y("div", { className: "padding-x-double" }, children, state === "sent" ? /* @__PURE__ */ y("div", { style: "height: 40px" }) : /* @__PURE__ */ y("div", { style: "height: 32px" })); + default: + return null; + } + } + + // shared/js/ui/components/toggle-report/toggle-report-title.jsx + function ToggleReportTitle({ children }) { + switch (platform.name) { + case "android": + return /* @__PURE__ */ y("h1", { className: "token-headline-2 text--center" }, children); + case "ios": + return /* @__PURE__ */ y("h1", { className: "token-ios-title-3 text--center" }, children); + case "windows": + return /* @__PURE__ */ y("h1", { className: "token-title-3-em text--center" }, children); + case "browser": + case "macos": + return /* @__PURE__ */ y("h1", { className: "token-title-2-em text--center" }, children); + default: + return null; + } + } + + // shared/js/ui/components/toggle-report.jsx + function ToggleReportIcon({ variant = "standard" }) { + const classes = (0, import_classnames2.default)({ + "hero-icon--toggle-report": variant === "standard", + "hero-icon--toggle-report-sent": variant === "sent", + "large-icon-container": platform.name === "browser" || platform.name === "windows", + "medium-icon-container": platform.name === "macos" || platform.name === "ios" || platform.name === "android" + }); + return /* @__PURE__ */ y("div", { className: classes }); + } + function ToggleReport() { + const mobile = platform.name === "android" || platform.name === "ios"; + const innerGap = mobile ? "24px" : "16px"; + const desktop = platform.name === "macos" || platform.name === "windows"; + const extension = platform.name === "browser"; + const { value, didClickSuccessScreen } = q2(ToggleReportContext); + const [state, dispatch] = useToggleReportState(); + useIosAnimation(state, dispatch); + if (state.value === "sent" && (desktop || extension)) { + return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(ToggleReportSent, { onClick: didClickSuccessScreen })); + } + if (desktop || extension) { + return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y(ToggleReportIcon, null), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")), /* @__PURE__ */ y(DesktopRevealText, { state, toggle: () => dispatch("toggle") }))), state.value === "showing" && /* @__PURE__ */ y(Scrollable, null, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") })))); + } + if (mobile) { + return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y(ToggleReportIcon, null), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")))), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") }), state.value !== "showing" && /* @__PURE__ */ y(RevealText, { toggle: () => dispatch(platform.name === "ios" ? "toggle-ios" : "toggle") })), state.value === "showing" && /* @__PURE__ */ y("div", { className: "ios-separator" }, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })))); + } + return /* @__PURE__ */ y("p", null, "unsupported platform: ", platform.name); + } + function SetAutoHeight() { + p2(() => { + const inner = ( + /** @type {HTMLElement} */ + document.querySelector('[data-screen="toggleReport"] .page-inner') + ); + if (inner) { + inner.style.height = "auto"; + const height = getContentHeight(); + document.body.style.setProperty("--height", `${height}px`); + const unsub = setupMutationObserverForExtensions((height2) => { + document.body.style.setProperty("--height", `${height2}px`); + }); + return () => { + unsub(); + }; + } else { + console.warn("Could not select the required element"); + } + }, []); + return null; + } + function getButtonStyles() { + switch (platform.name) { + case "ios": + case "android": + return { variant: "ios-secondary", size: "big", layout: "vertical" }; + case "windows": + return { variant: "desktop-standard", size: "desktop-large", layout: "horizontal" }; + default: + return { variant: "desktop-vibrancy", size: "desktop-large", layout: "horizontal" }; + } + } + function ToggleReportButtons({ send, reject }) { + const { variant, size, layout } = getButtonStyles(); + return /* @__PURE__ */ y(ButtonBar, { layout }, /* @__PURE__ */ y(Button, { variant, btnSize: size, onClick: reject }, ns.toggleReport("dontSendReport.title")), /* @__PURE__ */ y(Button, { variant, btnSize: size, onClick: send }, ns.report("sendReport.title"))); + } + function RevealText({ toggle }) { + return /* @__PURE__ */ y("p", { className: "text--center token-title-3" }, /* @__PURE__ */ y(PlainTextLink, { onClick: toggle, className: "token-bold" }, ns.toggleReport("siteNotWorkingInfoReveal.title"))); + } + function DesktopRevealText({ state, toggle }) { + if (state.value === "showing") + return null; + return /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("p", { className: "text--center token-title-3" }, /* @__PURE__ */ y(PlainTextLink, { onClick: toggle }, ns.toggleReport("siteNotWorkingInfoReveal.title")))); + } + + // v2/screens/toggle-report-screen.jsx + function ToggleReportScreen() { + const fetcher = useFetcher(); + const features = useFeatures(); + const { count } = useConnectionCount(); + const connectionId = `connection-${count}`; + p2(() => { + document.body.dataset.screen = "toggleReport"; + return () => { + document.body.dataset.screen = ""; + }; + }, []); + return /* @__PURE__ */ y(ToggleReportProvider, { key: connectionId, model: { fetch: fetcher }, screen: features.initialScreen }, /* @__PURE__ */ y(ToggleReportWrapper2, null, /* @__PURE__ */ y(ToggleReport, null))); + } + function ToggleReportWrapper2({ children }) { + const features = useFeatures(); + const onClose = useClose(); + const [_24, dispatch] = useToggleReportState(); + p2(() => { + document.body.dataset.screen = "toggleReport"; + return () => { + document.body.dataset.screen = ""; + }; + }, []); + const done = platformSwitch({ + ios: () => /* @__PURE__ */ y(Done, { onClick: onClose }), + macos: () => /* @__PURE__ */ y(Close, { onClick: onClose }), + default: () => null + }); + const back = platformSwitch({ + android: () => /* @__PURE__ */ y(Back, { onClick: () => dispatch("reject") }), + default: () => null + }); + return /* @__PURE__ */ y("div", { "data-toggle-report": "parent", class: "toggle-report page-inner", "data-opener": features.opener }, features.opener === "menu" ? /* @__PURE__ */ y(TopNav, { back, done }) : /* @__PURE__ */ y(TopNav, { back }), /* @__PURE__ */ y("div", { "data-testid": "toggle-report" }, children)); + } + + // v2/components/nav.jsx + function Nav({ children }) { + return /* @__PURE__ */ y("ul", { className: "default-list main-nav token-body-em" }, children); + } + function NavItem({ children, label, onClick }) { + return /* @__PURE__ */ y("li", { className: "main-nav__row" }, /* @__PURE__ */ y( + "a", + { + href: "javascript:void(0)", + role: "button", + draggable: false, + "aria-label": typeof children === "string" ? children : label, + className: "main-nav__item main-nav__item--link link-action link-action--dark", + onClick + }, + /* @__PURE__ */ y("span", { className: "main-nav__text" }, children), + /* @__PURE__ */ y("span", { className: "main-nav__chev" }) + )); + } + + // v2/screens/choice-problem.jsx + function CategoryTypeSelection() { + const description = ns.report("selectTheCategoryType.title"); + const { push } = useNav(); + const send = useTelemetry(); + const { tab } = useData(); + const showNativeFeedback2 = useShowNativeFeedback(); + return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-problem" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: tab.domain }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y(Nav, null, /* @__PURE__ */ y( + NavItem, + { + onClick: () => { + send({ name: "categoryTypeSelected", value: "notWorking" }); + push("categorySelection"); + } + }, + ns.report("categoryType1.title") + ), /* @__PURE__ */ y( + NavItem, + { + onClick: () => { + send({ name: "categoryTypeSelected", value: "dislike" }); + push("choiceBreakageForm", { category: "dislike" }); + } + }, + ns.report("categoryType2.title") + ), /* @__PURE__ */ y( + NavItem, + { + onClick: () => { + send({ name: "categoryTypeSelected", value: "general" }); + showNativeFeedback2(); + } + }, + ns.report("categoryType3.title") + )))); + } + function CategorySelection() { + const description = ns.report("selectTheCategory.title"); + const { push } = useNav(); + const send = useTelemetry(); + const { protectionsEnabled, tab } = useData(); + const text = tab.domain; + const platformFeatures = useFeatures(); + const showToggle = protectionsEnabled && (platformFeatures.breakageScreen === "categoryTypeSelection" || platformFeatures.initialScreen === "categoryTypeSelection"); + const randomised = F(() => { + const f3 = createBreakageFeaturesFrom(platformFeatures); + return f3.categoryList({ + login: ns.report("loginV2.title") + }); + }, [platformFeatures]); + return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: text }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y(Nav, null, randomised.map(([value, title]) => { + return /* @__PURE__ */ y( + NavItem, + { + key: value, + onClick: () => { + send({ name: "categorySelected", value: ( + /** @type {any} */ + value + ) }); + if (showToggle) { + push("choiceToggle", { category: value }); + } else { + push("choiceBreakageForm", { category: value }); + } + } + }, + title + ); + })))); + } + function ChoiceToggleScreen() { + const description = ns.report("tryTurningProtectionsOff.title"); + const { push } = useNav(); + const data = useData(); + const text = data.tab.domain; + const onToggle = useToggle(); + const send = useTelemetry(); + return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: text, icon: "switch-shield" }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y("div", { class: "card-list--bordered" }, /* @__PURE__ */ y("div", { className: "protection-toggle" }, /* @__PURE__ */ y("div", { className: "protection-toggle__row" }, /* @__PURE__ */ y(ProtectionToggle, { model: data, toggle: onToggle })))), /* @__PURE__ */ y("div", { class: "text--center" }, /* @__PURE__ */ y( + TextLink, + { + onClick: () => { + push("choiceBreakageForm"); + send({ name: "toggleSkipped" }); + } + }, + ns.report("skipThisStep.title") + )))); + } + var validCategories = () => { + return { + ...defaultCategories(), + dislike: ns.report("dislike.title") + }; + }; + function ChoiceBreakageForm() { + const { tab } = useData(); + const sendReport = useSendReport(); + const nav = useNav(); + const showAlert = useShowAlert(); + const categories = validCategories(); + let category = nav.params.get("category"); + if (!category || !Object.hasOwnProperty.call(categories, category)) { + category = "other"; + } + const description = categories[category]; + const placeholder = category === "other" ? ns.report("otherRequired.title") : ns.report("otherOptional.title"); + function submit(e3) { + e3.preventDefault(); + const values = Object.fromEntries(new FormData(e3.target)); + const desc = String(values.description).trim(); + if (category === "other" && desc.length === 0) { + showAlert(); + } else { + sendReport({ + category, + description: desc + }); + } + } + return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-third" }, /* @__PURE__ */ y(KeyInsightsMain, { title: tab.domain }, description)), /* @__PURE__ */ y("div", { className: "padding-x-third" }, /* @__PURE__ */ y( + FormElement, + { + placeholder, + after: /* @__PURE__ */ y("ul", { class: "padding-x" }, /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened.title")), /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened2.title")), /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened3.title"))), + onSubmit: submit + } + ))); + } + function NavWrapper() { + return /* @__PURE__ */ y(SecondaryTopNavAlt, null, /* @__PURE__ */ y(Title, null, ns.report("reportTitle.title"))); + } + + // v2/navigation.jsx + init_schema_parsers(); + var availableScreens = { + primaryScreen: { kind: "root", component: () => /* @__PURE__ */ y(PrimaryScreen, null) }, + // screens that would load immediately + breakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(BreakageFormScreen, { includeToggle: true }) }, + promptBreakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(BreakageFormScreen, { includeToggle: false }) }, + toggleReport: { kind: "subview", component: () => /* @__PURE__ */ y(ToggleReportScreen, null) }, + // + categoryTypeSelection: { kind: "subview", component: () => /* @__PURE__ */ y(CategoryTypeSelection, null) }, + categorySelection: { kind: "subview", component: () => /* @__PURE__ */ y(CategorySelection, null) }, + choiceToggle: { kind: "subview", component: () => /* @__PURE__ */ y(ChoiceToggleScreen, null) }, + choiceBreakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(ChoiceBreakageForm, null) }, + connection: { kind: "subview", component: () => /* @__PURE__ */ y(ConnectionScreen, null) }, + trackers: { kind: "subview", component: () => /* @__PURE__ */ y(TrackersScreen, null) }, + nonTrackers: { kind: "subview", component: () => /* @__PURE__ */ y(NonTrackersScreen, null) }, + consentManaged: { kind: "subview", component: () => /* @__PURE__ */ y(ConsentManagedScreen, { cosmetic: false }) }, + cookieHidden: { kind: "subview", component: () => /* @__PURE__ */ y(ConsentManagedScreen, { cosmetic: true }) } + }; + var entries = ( + /** @type {[ScreenName, { kind: 'subview' | 'root', component: () => any}][]} */ + Object.entries(availableScreens) + ); + var NavContext = G({ + /** @type {(name: ScreenName, params?: Record) => void} */ + push() { + throw new Error("not implemented"); + }, + /** @type {() => void} */ + pop() { + throw new Error("not implemented"); + }, + params: new URLSearchParams(""), + /** @type {() => boolean} */ + canPop: () => false, + /** @type {(screen: import('../schema/__generated__/schema.types').EventOrigin['screen']) => boolean} */ + canPopFrom: (screen) => false, + /** @type {() => ScreenName} */ + screen: () => { + throw new Error("screen() not implemented"); + } + }); + var ScreenContext = G({ + /** @type {import('../schema/__generated__/schema.types').EventOrigin['screen']} */ + screen: ( + /** @type {const} */ + "primaryScreen" + ) + }); + function useNav() { + return q2(NavContext); + } + function useCanPop() { + const { screen } = q2(ScreenContext); + const { canPopFrom } = useNav(); + return canPopFrom(screen); + } + function isScreenName(input) { + return screenKindSchema.safeParse(input).success; + } + function navReducer(state, event) { + if (!window.__ddg_integration_test) { + console.log("\u{1F4E9}", event, state); + } + switch (state.state) { + case "transitioning": { + switch (event.type) { + case "end": { + return { + ...state, + commit: [], + state: ( + /** @type {const} */ + "settled" + ) + }; + } + } + return state; + } + case "initial": + case "settled": { + switch (event.type) { + case "goto": { + if (!event.opts.animate) { + return { + ...state, + stack: event.stack, + state: ( + /** @type {const} */ + "settled" + ) + }; + } + return { + ...state, + stack: event.stack, + state: ( + /** @type {const} */ + "transitioning" + ) + }; + } + case "push": { + if (!event.opts.animate) { + return { + ...state, + stack: state.stack.concat(event.name), + state: ( + /** @type {const} */ + "settled" + ), + via: "push" + }; + } + return { + ...state, + stack: state.stack.concat(event.name), + state: ( + /** @type {const} */ + "transitioning" + ), + via: "push" + }; + } + case "pop": { + if (state.stack.length < 2) { + if (!window.__ddg_integration_test) { + console.warn("ignoring a `pop` event", window.location.search); + } + return state; + } + if (!event.opts.animate) { + const next = state.stack.slice(0, -1); + return { + ...state, + commit: next, + stack: next, + state: ( + /** @type {const} */ + "settled" + ), + via: "pop" + }; + } + return { + ...state, + commit: state.stack, + stack: state.stack.slice(0, -1), + state: ( + /** @type {const} */ + "transitioning" + ), + via: "pop" + }; + } + default: { + console.warn("ignoring", event, "state", state); + return state; + } + } + } + default: + throw new Error("unreachable"); + } + } + function Navigation(props) { + const [state, dispatch] = s2(navReducer, { + stack: props.stack, + state: "initial", + commit: [], + via: void 0 + }); + const parentRef = _(null); + p2(() => { + const curr = parentRef.current; + if (!curr) + return; + const handler = (e3) => { + if (e3.target !== parentRef.current) + return; + dispatch({ type: "end" }); + }; + curr.addEventListener("transitionend", handler); + return () => { + curr.removeEventListener("transitionend", handler); + }; + }, [state.state]); + p2(() => { + function popstateHandler() { + const currentUrlParams = new URLSearchParams(location.search); + const currentURLStack = currentUrlParams.getAll("stack"); + const navigationIntentionIsForwards = currentURLStack.length > state.stack.length; + if (navigationIntentionIsForwards) { + const lastEntry = currentURLStack[currentURLStack.length - 1]; + if (isScreenName(lastEntry)) { + dispatch({ type: "push", name: lastEntry, opts: { animate: props.animate && isAndroid() } }); + } + } else { + dispatch({ type: "pop", opts: { animate: props.animate && isAndroid() } }); + } + } + window.addEventListener("popstate", popstateHandler); + return () => { + window.removeEventListener("popstate", popstateHandler); + }; + }, [state.state, state.stack, state.via, props.animate]); + const canPop = T2(() => { + if (state.state === "transitioning") { + return state.commit.length > 1 || state.stack.length > 1; + } + return state.stack.length > 1; + }, [state.state, state.stack, state.commit]); + const canPopFrom = T2( + (screen2) => { + if (state.stack[0] === screen2) + return false; + return canPop(); + }, + [state.state, state.stack, state.commit] + ); + const screen = T2(() => { + const v3 = ( + /** @type {ScreenName} */ + state.stack[state.stack.length - 1] + ); + return v3; + }, [state.state, state.stack, state.commit]); + const api = { + /** + * @param {ScreenName} name + * @param {Record} params + */ + push: (name, params = {}) => { + const url = new URL(window.location.href); + for (let [key, value] of Object.entries(params)) { + url.searchParams.set(key, value); + } + url.searchParams.delete("stack"); + for (let string of state.stack) { + url.searchParams.append("stack", string); + } + url.searchParams.append("stack", name); + window.history.pushState({}, "", url); + dispatch({ type: "push", name, opts: { animate: props.animate } }); + }, + pop: () => { + window.history.go(-1); + dispatch({ type: "pop", opts: { animate: props.animate } }); + }, + canPop, + canPopFrom, + screen, + get params() { + return new URLSearchParams(location.search); + } + }; + return /* @__PURE__ */ y(NavContext.Provider, { value: api }, /* @__PURE__ */ y( + "div", + { + id: "popup-container", + ref: parentRef, + className: (0, import_classnames3.default)({ + "sliding-subview-v2": true, + "sliding-subview-v2--root": true, + "sliding-subview-v2--animating": state.state === "transitioning" + }), + style: { + transform: `translateX(` + -((state.stack.length - 1) * 100) + "%)" + } + }, + entries.map(([screenName, item]) => { + const inStack = state.stack.includes(screenName); + const commiting = state.commit.includes(screenName); + const current = state.stack[state.stack.length - 1] === screenName; + if (!inStack && !commiting) + return null; + if (item.kind === "root") { + return /* @__PURE__ */ y(ScreenContext.Provider, { value: { screen: screenName } }, /* @__PURE__ */ y("section", { className: "app-height", key: screenName, "data-testid": `subview-${screenName}` }, item.component())); + } + const translateValue = state.stack.includes(screenName) ? state.stack.indexOf(screenName) : state.commit.includes(screenName) ? state.commit.indexOf(screenName) : 0; + const cssProp = `translateX(${translateValue * 100}%)`; + return /* @__PURE__ */ y(ScreenContext.Provider, { value: { screen: screenName } }, /* @__PURE__ */ y( + "section", + { + "data-current": String(current), + className: "sliding-subview-v2", + key: screenName, + style: { transform: cssProp } + }, + item.component() + )); + }) + )); + } + + // v2/settings.jsx + var SettingsContext = G({ + /** @type {boolean} */ + reducedMotion: false + }); + function SettingsProvider({ children }) { + const [reducedMotion, setReducedMotion] = h2(window.matchMedia("(prefers-reduced-motion: reduce)").matches); + p2(() => { + const mediaQueryList = window.matchMedia("(prefers-reduced-motion: reduce)"); + const listener = (event) => setReducedMotion(event.matches); + mediaQueryList.addEventListener("change", listener); + return () => { + mediaQueryList.removeEventListener("change", listener); + }; + }, []); + return /* @__PURE__ */ y(SettingsContext.Provider, { value: { reducedMotion } }, children); + } + function useGlobalSettings() { + return q2(SettingsContext); + } + + // v2/app.jsx + function App() { + const { reducedMotion } = useGlobalSettings(); + const data = useFeatures(); + const stack = initialStack(data); + return /* @__PURE__ */ y(Navigation, { stack, animate: !reducedMotion, params: new URLSearchParams(window.location.search) }); + } + function initialStack(features) { + if (features.initialScreen === "breakageForm") { + return ["breakageForm"]; + } + if (features.initialScreen === "promptBreakageForm") { + return ["promptBreakageForm"]; + } + if (features.initialScreen === "toggleReport") { + return ["toggleReport"]; + } + if (features.initialScreen === "choiceBreakageForm") { + return ["choiceBreakageForm"]; + } + if (features.initialScreen === "categoryTypeSelection") { + return ["categoryTypeSelection"]; + } + if (features.initialScreen === "categorySelection") { + return ["categorySelection"]; + } + return ["primaryScreen"]; + } + + // v2/index.jsx + window.onunhandledrejection = (event) => { + console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`); + }; + async function init2() { + const app = document.querySelector("#app"); + if (!app) + throw new Error("unreachable"); + B( + /* @__PURE__ */ y(SettingsProvider, null, /* @__PURE__ */ y(DataProvider, null, /* @__PURE__ */ y(App, null))), + app + ); + } + init2().catch((e3) => { + console.error("start up error", e3); + }); +})(); +/*! Bundled license information: + +classnames/index.js: + (*! + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames + *) + +@material/base/foundation.js: + (** + * @license + * Copyright 2016 Google Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *) + +@material/base/component.js: + (** + * @license + * Copyright 2016 Google Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *) + +@material/dom/events.js: + (** + * @license + * Copyright 2019 Google Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *) + +@material/dom/ponyfill.js: + (** + * @license + * Copyright 2018 Google Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *) + +@material/ripple/constants.js: + (** + * @license + * Copyright 2016 Google Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *) + +@material/ripple/foundation.js: + (** + * @license + * Copyright 2016 Google Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *) + +@material/ripple/component.js: + (** + * @license + * Copyright 2016 Google Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + *) +*/ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js new file mode 100644 index 000000000000..341914af7d7b --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js @@ -0,0 +1,21 @@ +/** + * https://bugs.chromium.org/p/v8/issues/detail?id=10682 + */ +function hasIntlGetCanonicalLocalesBug() { + try { + return new Intl.Locale('und-x-private').toString() === 'x-private'; + } catch (e) { + return true; + } +} +function shouldPolyfill() { + return !('Locale' in Intl) || hasIntlGetCanonicalLocalesBug(); +} +/** + * Load the Intl.Locale polyfill if needed + */ +if (shouldPolyfill()) { + const script = document.createElement('script'); + script.src = '../public/js/polyfills.js'; + document.head.appendChild(script); +} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js new file mode 100644 index 000000000000..363804777119 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js @@ -0,0 +1,6801 @@ +"use strict"; +(() => { + var __create = Object.create; + var __defProp = Object.defineProperty; + var __getOwnPropDesc = Object.getOwnPropertyDescriptor; + var __getOwnPropNames = Object.getOwnPropertyNames; + var __getProtoOf = Object.getPrototypeOf; + var __hasOwnProp = Object.prototype.hasOwnProperty; + var __esm = (fn, res) => function __init() { + return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; + }; + var __commonJS = (cb, mod) => function __require() { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + }; + var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); + }; + var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; + }; + var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod + )); + var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + + // node_modules/tslib/tslib.es6.js + var tslib_es6_exports = {}; + __export(tslib_es6_exports, { + __assign: () => __assign, + __asyncDelegator: () => __asyncDelegator, + __asyncGenerator: () => __asyncGenerator, + __asyncValues: () => __asyncValues, + __await: () => __await, + __awaiter: () => __awaiter, + __classPrivateFieldGet: () => __classPrivateFieldGet, + __classPrivateFieldIn: () => __classPrivateFieldIn, + __classPrivateFieldSet: () => __classPrivateFieldSet, + __createBinding: () => __createBinding, + __decorate: () => __decorate, + __exportStar: () => __exportStar, + __extends: () => __extends, + __generator: () => __generator, + __importDefault: () => __importDefault, + __importStar: () => __importStar, + __makeTemplateObject: () => __makeTemplateObject, + __metadata: () => __metadata, + __param: () => __param, + __read: () => __read, + __rest: () => __rest, + __spread: () => __spread, + __spreadArray: () => __spreadArray, + __spreadArrays: () => __spreadArrays, + __values: () => __values + }); + function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { + this.constructor = d; + } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + function __rest(s, e) { + var t = {}; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; + } + function __decorate(decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") + r = Reflect.decorate(decorators, target, key, desc); + else + for (var i = decorators.length - 1; i >= 0; i--) + if (d = decorators[i]) + r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + } + function __param(paramIndex, decorator) { + return function(target, key) { + decorator(target, key, paramIndex); + }; + } + function __metadata(metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") + return Reflect.metadata(metadataKey, metadataValue); + } + function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { + return value instanceof P ? value : new P(function(resolve) { + resolve(value); + }); + } + return new (P || (P = Promise))(function(resolve, reject) { + function fulfilled(value) { + try { + step(generator.next(value)); + } catch (e) { + reject(e); + } + } + function rejected(value) { + try { + step(generator["throw"](value)); + } catch (e) { + reject(e); + } + } + function step(result) { + result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); + } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + } + function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { + if (t[0] & 1) + throw t[1]; + return t[1]; + }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { + return this; + }), g; + function verb(n) { + return function(v) { + return step([n, v]); + }; + } + function step(op) { + if (f) + throw new TypeError("Generator is already executing."); + while (_) + try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) + return t; + if (y = 0, t) + op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: + case 1: + t = op; + break; + case 4: + _.label++; + return { value: op[1], done: false }; + case 5: + _.label++; + y = op[1]; + op = [0]; + continue; + case 7: + op = _.ops.pop(); + _.trys.pop(); + continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { + _ = 0; + continue; + } + if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { + _.label = op[1]; + break; + } + if (op[0] === 6 && _.label < t[1]) { + _.label = t[1]; + t = op; + break; + } + if (t && _.label < t[2]) { + _.label = t[2]; + _.ops.push(op); + break; + } + if (t[2]) + _.ops.pop(); + _.trys.pop(); + continue; + } + op = body.call(thisArg, _); + } catch (e) { + op = [6, e]; + y = 0; + } finally { + f = t = 0; + } + if (op[0] & 5) + throw op[1]; + return { value: op[0] ? op[1] : void 0, done: true }; + } + } + function __exportStar(m, o) { + for (var p in m) + if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) + __createBinding(o, m, p); + } + function __values(o) { + var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; + if (m) + return m.call(o); + if (o && typeof o.length === "number") + return { + next: function() { + if (o && i >= o.length) + o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); + } + function __read(o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) + return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) + ar.push(r.value); + } catch (error) { + e = { error }; + } finally { + try { + if (r && !r.done && (m = i["return"])) + m.call(i); + } finally { + if (e) + throw e.error; + } + } + return ar; + } + function __spread() { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + } + function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) + s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; + } + function __spreadArray(to, from, pack) { + if (pack || arguments.length === 2) + for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) + ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); + } + function __await(v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); + } + function __asyncGenerator(thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) + throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i; + function verb(n) { + if (g[n]) + i[n] = function(v) { + return new Promise(function(a, b) { + q.push([n, v, a, b]) > 1 || resume(n, v); + }); + }; + } + function resume(n, v) { + try { + step(g[n](v)); + } catch (e) { + settle(q[0][3], e); + } + } + function step(r) { + r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); + } + function fulfill(value) { + resume("next", value); + } + function reject(value) { + resume("throw", value); + } + function settle(f, v) { + if (f(v), q.shift(), q.length) + resume(q[0][0], q[0][1]); + } + } + function __asyncDelegator(o) { + var i, p; + return i = {}, verb("next"), verb("throw", function(e) { + throw e; + }), verb("return"), i[Symbol.iterator] = function() { + return this; + }, i; + function verb(n, f) { + i[n] = o[n] ? function(v) { + return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; + } : f; + } + } + function __asyncValues(o) { + if (!Symbol.asyncIterator) + throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator], i; + return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { + return this; + }, i); + function verb(n) { + i[n] = o[n] && function(v) { + return new Promise(function(resolve, reject) { + v = o[n](v), settle(resolve, reject, v.done, v.value); + }); + }; + } + function settle(resolve, reject, d, v) { + Promise.resolve(v).then(function(v2) { + resolve({ value: v2, done: d }); + }, reject); + } + } + function __makeTemplateObject(cooked, raw) { + if (Object.defineProperty) { + Object.defineProperty(cooked, "raw", { value: raw }); + } else { + cooked.raw = raw; + } + return cooked; + } + function __importStar(mod) { + if (mod && mod.__esModule) + return mod; + var result = {}; + if (mod != null) { + for (var k in mod) + if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) + __createBinding(result, mod, k); + } + __setModuleDefault(result, mod); + return result; + } + function __importDefault(mod) { + return mod && mod.__esModule ? mod : { default: mod }; + } + function __classPrivateFieldGet(receiver, state, kind, f) { + if (kind === "a" && !f) + throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) + throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); + } + function __classPrivateFieldSet(receiver, state, value, kind, f) { + if (kind === "m") + throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) + throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) + throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; + } + function __classPrivateFieldIn(state, receiver) { + if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") + throw new TypeError("Cannot use 'in' operator on non-object"); + return typeof state === "function" ? receiver === state : state.has(receiver); + } + var extendStatics, __assign, __createBinding, __setModuleDefault; + var init_tslib_es6 = __esm({ + "node_modules/tslib/tslib.es6.js"() { + extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { + d2.__proto__ = b2; + } || function(d2, b2) { + for (var p in b2) + if (Object.prototype.hasOwnProperty.call(b2, p)) + d2[p] = b2[p]; + }; + return extendStatics(d, b); + }; + __assign = function() { + __assign = Object.assign || function __assign2(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) + if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); + }; + __createBinding = Object.create ? function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { + return m[k]; + } }; + } + Object.defineProperty(o, k2, desc); + } : function(o, m, k, k2) { + if (k2 === void 0) + k2 = k; + o[k2] = m[k]; + }; + __setModuleDefault = Object.create ? function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); + } : function(o, v) { + o["default"] = v; + }; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeLocaleList.js + var require_CanonicalizeLocaleList = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeLocaleList.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.CanonicalizeLocaleList = void 0; + function CanonicalizeLocaleList(locales) { + return Intl.getCanonicalLocales(locales); + } + exports.CanonicalizeLocaleList = CanonicalizeLocaleList; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeTimeZoneName.js + var require_CanonicalizeTimeZoneName = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeTimeZoneName.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.CanonicalizeTimeZoneName = void 0; + function CanonicalizeTimeZoneName(tz, _a) { + var tzData = _a.tzData, uppercaseLinks = _a.uppercaseLinks; + var uppercasedTz = tz.toUpperCase(); + var uppercasedZones = Object.keys(tzData).reduce(function(all, z) { + all[z.toUpperCase()] = z; + return all; + }, {}); + var ianaTimeZone = uppercaseLinks[uppercasedTz] || uppercasedZones[uppercasedTz]; + if (ianaTimeZone === "Etc/UTC" || ianaTimeZone === "Etc/GMT") { + return "UTC"; + } + return ianaTimeZone; + } + exports.CanonicalizeTimeZoneName = CanonicalizeTimeZoneName; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/262.js + var require__ = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/262.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.msFromTime = exports.OrdinaryHasInstance = exports.SecFromTime = exports.MinFromTime = exports.HourFromTime = exports.DateFromTime = exports.MonthFromTime = exports.InLeapYear = exports.DayWithinYear = exports.DaysInYear = exports.YearFromTime = exports.TimeFromYear = exports.DayFromYear = exports.WeekDay = exports.Day = exports.Type = exports.HasOwnProperty = exports.ArrayCreate = exports.SameValue = exports.ToObject = exports.TimeClip = exports.ToNumber = exports.ToString = void 0; + function ToString(o) { + if (typeof o === "symbol") { + throw TypeError("Cannot convert a Symbol value to a string"); + } + return String(o); + } + exports.ToString = ToString; + function ToNumber(val) { + if (val === void 0) { + return NaN; + } + if (val === null) { + return 0; + } + if (typeof val === "boolean") { + return val ? 1 : 0; + } + if (typeof val === "number") { + return val; + } + if (typeof val === "symbol" || typeof val === "bigint") { + throw new TypeError("Cannot convert symbol/bigint to number"); + } + return Number(val); + } + exports.ToNumber = ToNumber; + function ToInteger(n) { + var number = ToNumber(n); + if (isNaN(number) || SameValue(number, -0)) { + return 0; + } + if (isFinite(number)) { + return number; + } + var integer = Math.floor(Math.abs(number)); + if (number < 0) { + integer = -integer; + } + if (SameValue(integer, -0)) { + return 0; + } + return integer; + } + function TimeClip(time) { + if (!isFinite(time)) { + return NaN; + } + if (Math.abs(time) > 8.64 * 1e15) { + return NaN; + } + return ToInteger(time); + } + exports.TimeClip = TimeClip; + function ToObject(arg) { + if (arg == null) { + throw new TypeError("undefined/null cannot be converted to object"); + } + return Object(arg); + } + exports.ToObject = ToObject; + function SameValue(x, y) { + if (Object.is) { + return Object.is(x, y); + } + if (x === y) { + return x !== 0 || 1 / x === 1 / y; + } + return x !== x && y !== y; + } + exports.SameValue = SameValue; + function ArrayCreate(len) { + return new Array(len); + } + exports.ArrayCreate = ArrayCreate; + function HasOwnProperty(o, prop) { + return Object.prototype.hasOwnProperty.call(o, prop); + } + exports.HasOwnProperty = HasOwnProperty; + function Type(x) { + if (x === null) { + return "Null"; + } + if (typeof x === "undefined") { + return "Undefined"; + } + if (typeof x === "function" || typeof x === "object") { + return "Object"; + } + if (typeof x === "number") { + return "Number"; + } + if (typeof x === "boolean") { + return "Boolean"; + } + if (typeof x === "string") { + return "String"; + } + if (typeof x === "symbol") { + return "Symbol"; + } + if (typeof x === "bigint") { + return "BigInt"; + } + } + exports.Type = Type; + var MS_PER_DAY = 864e5; + function mod(x, y) { + return x - Math.floor(x / y) * y; + } + function Day(t) { + return Math.floor(t / MS_PER_DAY); + } + exports.Day = Day; + function WeekDay(t) { + return mod(Day(t) + 4, 7); + } + exports.WeekDay = WeekDay; + function DayFromYear(y) { + return Date.UTC(y, 0) / MS_PER_DAY; + } + exports.DayFromYear = DayFromYear; + function TimeFromYear(y) { + return Date.UTC(y, 0); + } + exports.TimeFromYear = TimeFromYear; + function YearFromTime(t) { + return new Date(t).getUTCFullYear(); + } + exports.YearFromTime = YearFromTime; + function DaysInYear(y) { + if (y % 4 !== 0) { + return 365; + } + if (y % 100 !== 0) { + return 366; + } + if (y % 400 !== 0) { + return 365; + } + return 366; + } + exports.DaysInYear = DaysInYear; + function DayWithinYear(t) { + return Day(t) - DayFromYear(YearFromTime(t)); + } + exports.DayWithinYear = DayWithinYear; + function InLeapYear(t) { + return DaysInYear(YearFromTime(t)) === 365 ? 0 : 1; + } + exports.InLeapYear = InLeapYear; + function MonthFromTime(t) { + var dwy = DayWithinYear(t); + var leap = InLeapYear(t); + if (dwy >= 0 && dwy < 31) { + return 0; + } + if (dwy < 59 + leap) { + return 1; + } + if (dwy < 90 + leap) { + return 2; + } + if (dwy < 120 + leap) { + return 3; + } + if (dwy < 151 + leap) { + return 4; + } + if (dwy < 181 + leap) { + return 5; + } + if (dwy < 212 + leap) { + return 6; + } + if (dwy < 243 + leap) { + return 7; + } + if (dwy < 273 + leap) { + return 8; + } + if (dwy < 304 + leap) { + return 9; + } + if (dwy < 334 + leap) { + return 10; + } + if (dwy < 365 + leap) { + return 11; + } + throw new Error("Invalid time"); + } + exports.MonthFromTime = MonthFromTime; + function DateFromTime(t) { + var dwy = DayWithinYear(t); + var mft = MonthFromTime(t); + var leap = InLeapYear(t); + if (mft === 0) { + return dwy + 1; + } + if (mft === 1) { + return dwy - 30; + } + if (mft === 2) { + return dwy - 58 - leap; + } + if (mft === 3) { + return dwy - 89 - leap; + } + if (mft === 4) { + return dwy - 119 - leap; + } + if (mft === 5) { + return dwy - 150 - leap; + } + if (mft === 6) { + return dwy - 180 - leap; + } + if (mft === 7) { + return dwy - 211 - leap; + } + if (mft === 8) { + return dwy - 242 - leap; + } + if (mft === 9) { + return dwy - 272 - leap; + } + if (mft === 10) { + return dwy - 303 - leap; + } + if (mft === 11) { + return dwy - 333 - leap; + } + throw new Error("Invalid time"); + } + exports.DateFromTime = DateFromTime; + var HOURS_PER_DAY = 24; + var MINUTES_PER_HOUR = 60; + var SECONDS_PER_MINUTE = 60; + var MS_PER_SECOND = 1e3; + var MS_PER_MINUTE = MS_PER_SECOND * SECONDS_PER_MINUTE; + var MS_PER_HOUR = MS_PER_MINUTE * MINUTES_PER_HOUR; + function HourFromTime(t) { + return mod(Math.floor(t / MS_PER_HOUR), HOURS_PER_DAY); + } + exports.HourFromTime = HourFromTime; + function MinFromTime(t) { + return mod(Math.floor(t / MS_PER_MINUTE), MINUTES_PER_HOUR); + } + exports.MinFromTime = MinFromTime; + function SecFromTime(t) { + return mod(Math.floor(t / MS_PER_SECOND), SECONDS_PER_MINUTE); + } + exports.SecFromTime = SecFromTime; + function IsCallable(fn) { + return typeof fn === "function"; + } + function OrdinaryHasInstance(C, O, internalSlots) { + if (!IsCallable(C)) { + return false; + } + if (internalSlots === null || internalSlots === void 0 ? void 0 : internalSlots.boundTargetFunction) { + var BC = internalSlots === null || internalSlots === void 0 ? void 0 : internalSlots.boundTargetFunction; + return O instanceof BC; + } + if (typeof O !== "object") { + return false; + } + var P = C.prototype; + if (typeof P !== "object") { + throw new TypeError("OrdinaryHasInstance called on an object with an invalid prototype property."); + } + return Object.prototype.isPrototypeOf.call(P, O); + } + exports.OrdinaryHasInstance = OrdinaryHasInstance; + function msFromTime(t) { + return mod(t, MS_PER_SECOND); + } + exports.msFromTime = msFromTime; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CoerceOptionsToObject.js + var require_CoerceOptionsToObject = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CoerceOptionsToObject.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.CoerceOptionsToObject = void 0; + var _262_1 = require__(); + function CoerceOptionsToObject(options) { + if (typeof options === "undefined") { + return /* @__PURE__ */ Object.create(null); + } + return (0, _262_1.ToObject)(options); + } + exports.CoerceOptionsToObject = CoerceOptionsToObject; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/DefaultNumberOption.js + var require_DefaultNumberOption = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/DefaultNumberOption.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.DefaultNumberOption = void 0; + function DefaultNumberOption(val, min, max, fallback) { + if (val !== void 0) { + val = Number(val); + if (isNaN(val) || val < min || val > max) { + throw new RangeError("".concat(val, " is outside of range [").concat(min, ", ").concat(max, "]")); + } + return Math.floor(val); + } + return fallback; + } + exports.DefaultNumberOption = DefaultNumberOption; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetNumberOption.js + var require_GetNumberOption = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetNumberOption.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.GetNumberOption = void 0; + var DefaultNumberOption_1 = require_DefaultNumberOption(); + function GetNumberOption(options, property, minimum, maximum, fallback) { + var val = options[property]; + return (0, DefaultNumberOption_1.DefaultNumberOption)(val, minimum, maximum, fallback); + } + exports.GetNumberOption = GetNumberOption; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOption.js + var require_GetOption = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOption.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.GetOption = void 0; + var _262_1 = require__(); + function GetOption(opts, prop, type, values, fallback) { + if (typeof opts !== "object") { + throw new TypeError("Options must be an object"); + } + var value = opts[prop]; + if (value !== void 0) { + if (type !== "boolean" && type !== "string") { + throw new TypeError("invalid type"); + } + if (type === "boolean") { + value = Boolean(value); + } + if (type === "string") { + value = (0, _262_1.ToString)(value); + } + if (values !== void 0 && !values.filter(function(val) { + return val == value; + }).length) { + throw new RangeError("".concat(value, " is not within ").concat(values.join(", "))); + } + return value; + } + return fallback; + } + exports.GetOption = GetOption; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOptionsObject.js + var require_GetOptionsObject = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOptionsObject.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.GetOptionsObject = void 0; + function GetOptionsObject(options) { + if (typeof options === "undefined") { + return /* @__PURE__ */ Object.create(null); + } + if (typeof options === "object") { + return options; + } + throw new TypeError("Options must be an object"); + } + exports.GetOptionsObject = GetOptionsObject; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetStringOrBooleanOption.js + var require_GetStringOrBooleanOption = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetStringOrBooleanOption.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.GetStringOrBooleanOption = void 0; + var _262_1 = require__(); + function GetStringOrBooleanOption(opts, prop, values, trueValue, falsyValue, fallback) { + var value = opts[prop]; + if (value === void 0) { + return fallback; + } + if (value === true) { + return trueValue; + } + var valueBoolean = Boolean(value); + if (valueBoolean === false) { + return falsyValue; + } + value = (0, _262_1.ToString)(value); + if (value === "true" || value === "false") { + return fallback; + } + if ((values || []).indexOf(value) === -1) { + throw new RangeError("Invalid value ".concat(value)); + } + return value; + } + exports.GetStringOrBooleanOption = GetStringOrBooleanOption; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsSanctionedSimpleUnitIdentifier.js + var require_IsSanctionedSimpleUnitIdentifier = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsSanctionedSimpleUnitIdentifier.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.IsSanctionedSimpleUnitIdentifier = exports.SIMPLE_UNITS = exports.removeUnitNamespace = exports.SANCTIONED_UNITS = void 0; + exports.SANCTIONED_UNITS = [ + "angle-degree", + "area-acre", + "area-hectare", + "concentr-percent", + "digital-bit", + "digital-byte", + "digital-gigabit", + "digital-gigabyte", + "digital-kilobit", + "digital-kilobyte", + "digital-megabit", + "digital-megabyte", + "digital-petabyte", + "digital-terabit", + "digital-terabyte", + "duration-day", + "duration-hour", + "duration-millisecond", + "duration-minute", + "duration-month", + "duration-second", + "duration-week", + "duration-year", + "length-centimeter", + "length-foot", + "length-inch", + "length-kilometer", + "length-meter", + "length-mile-scandinavian", + "length-mile", + "length-millimeter", + "length-yard", + "mass-gram", + "mass-kilogram", + "mass-ounce", + "mass-pound", + "mass-stone", + "temperature-celsius", + "temperature-fahrenheit", + "volume-fluid-ounce", + "volume-gallon", + "volume-liter", + "volume-milliliter" + ]; + function removeUnitNamespace(unit) { + return unit.slice(unit.indexOf("-") + 1); + } + exports.removeUnitNamespace = removeUnitNamespace; + exports.SIMPLE_UNITS = exports.SANCTIONED_UNITS.map(removeUnitNamespace); + function IsSanctionedSimpleUnitIdentifier(unitIdentifier) { + return exports.SIMPLE_UNITS.indexOf(unitIdentifier) > -1; + } + exports.IsSanctionedSimpleUnitIdentifier = IsSanctionedSimpleUnitIdentifier; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsValidTimeZoneName.js + var require_IsValidTimeZoneName = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsValidTimeZoneName.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.IsValidTimeZoneName = void 0; + function IsValidTimeZoneName(tz, _a) { + var tzData = _a.tzData, uppercaseLinks = _a.uppercaseLinks; + var uppercasedTz = tz.toUpperCase(); + var zoneNames = /* @__PURE__ */ new Set(); + var linkNames = /* @__PURE__ */ new Set(); + Object.keys(tzData).map(function(z) { + return z.toUpperCase(); + }).forEach(function(z) { + return zoneNames.add(z); + }); + Object.keys(uppercaseLinks).forEach(function(linkName) { + linkNames.add(linkName.toUpperCase()); + zoneNames.add(uppercaseLinks[linkName].toUpperCase()); + }); + return zoneNames.has(uppercasedTz) || linkNames.has(uppercasedTz); + } + exports.IsValidTimeZoneName = IsValidTimeZoneName; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedCurrencyCode.js + var require_IsWellFormedCurrencyCode = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedCurrencyCode.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.IsWellFormedCurrencyCode = void 0; + function toUpperCase(str) { + return str.replace(/([a-z])/g, function(_, c) { + return c.toUpperCase(); + }); + } + var NOT_A_Z_REGEX = /[^A-Z]/; + function IsWellFormedCurrencyCode(currency) { + currency = toUpperCase(currency); + if (currency.length !== 3) { + return false; + } + if (NOT_A_Z_REGEX.test(currency)) { + return false; + } + return true; + } + exports.IsWellFormedCurrencyCode = IsWellFormedCurrencyCode; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedUnitIdentifier.js + var require_IsWellFormedUnitIdentifier = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedUnitIdentifier.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.IsWellFormedUnitIdentifier = void 0; + var IsSanctionedSimpleUnitIdentifier_1 = require_IsSanctionedSimpleUnitIdentifier(); + function toLowerCase(str) { + return str.replace(/([A-Z])/g, function(_, c) { + return c.toLowerCase(); + }); + } + function IsWellFormedUnitIdentifier(unit) { + unit = toLowerCase(unit); + if ((0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(unit)) { + return true; + } + var units = unit.split("-per-"); + if (units.length !== 2) { + return false; + } + var numerator = units[0], denominator = units[1]; + if (!(0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(numerator) || !(0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(denominator)) { + return false; + } + return true; + } + exports.IsWellFormedUnitIdentifier = IsWellFormedUnitIdentifier; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ApplyUnsignedRoundingMode.js + var require_ApplyUnsignedRoundingMode = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ApplyUnsignedRoundingMode.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ApplyUnsignedRoundingMode = void 0; + function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) { + if (x === r1) + return r1; + if (unsignedRoundingMode === void 0) { + throw new Error("unsignedRoundingMode is mandatory"); + } + if (unsignedRoundingMode === "zero") { + return r1; + } + if (unsignedRoundingMode === "infinity") { + return r2; + } + var d1 = x - r1; + var d2 = r2 - x; + if (d1 < d2) { + return r1; + } + if (d2 < d1) { + return r2; + } + if (d1 !== d2) { + throw new Error("Unexpected error"); + } + if (unsignedRoundingMode === "half-zero") { + return r1; + } + if (unsignedRoundingMode === "half-infinity") { + return r2; + } + if (unsignedRoundingMode !== "half-even") { + throw new Error("Unexpected value for unsignedRoundingMode: ".concat(unsignedRoundingMode)); + } + var cardinality = r1 / (r2 - r1) % 2; + if (cardinality === 0) { + return r1; + } + return r2; + } + exports.ApplyUnsignedRoundingMode = ApplyUnsignedRoundingMode; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CollapseNumberRange.js + var require_CollapseNumberRange = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CollapseNumberRange.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.CollapseNumberRange = void 0; + function CollapseNumberRange(result) { + return result; + } + exports.CollapseNumberRange = CollapseNumberRange; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/utils.js + var require_utils = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = exports.defineProperty = exports.isLiteralPart = exports.getMultiInternalSlots = exports.getInternalSlot = exports.setMultiInternalSlots = exports.setInternalSlot = exports.repeat = exports.getMagnitude = void 0; + function getMagnitude(x) { + return Math.floor(Math.log(x) * Math.LOG10E); + } + exports.getMagnitude = getMagnitude; + function repeat(s, times) { + if (typeof s.repeat === "function") { + return s.repeat(times); + } + var arr = new Array(times); + for (var i = 0; i < arr.length; i++) { + arr[i] = s; + } + return arr.join(""); + } + exports.repeat = repeat; + function setInternalSlot(map, pl, field, value) { + if (!map.get(pl)) { + map.set(pl, /* @__PURE__ */ Object.create(null)); + } + var slots = map.get(pl); + slots[field] = value; + } + exports.setInternalSlot = setInternalSlot; + function setMultiInternalSlots(map, pl, props) { + for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) { + var k = _a[_i]; + setInternalSlot(map, pl, k, props[k]); + } + } + exports.setMultiInternalSlots = setMultiInternalSlots; + function getInternalSlot(map, pl, field) { + return getMultiInternalSlots(map, pl, field)[field]; + } + exports.getInternalSlot = getInternalSlot; + function getMultiInternalSlots(map, pl) { + var fields = []; + for (var _i = 2; _i < arguments.length; _i++) { + fields[_i - 2] = arguments[_i]; + } + var slots = map.get(pl); + if (!slots) { + throw new TypeError("".concat(pl, " InternalSlot has not been initialized")); + } + return fields.reduce(function(all, f) { + all[f] = slots[f]; + return all; + }, /* @__PURE__ */ Object.create(null)); + } + exports.getMultiInternalSlots = getMultiInternalSlots; + function isLiteralPart(patternPart) { + return patternPart.type === "literal"; + } + exports.isLiteralPart = isLiteralPart; + function defineProperty(target, name, _a) { + var value = _a.value; + Object.defineProperty(target, name, { + configurable: true, + enumerable: false, + writable: true, + value + }); + } + exports.defineProperty = defineProperty; + exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; + function invariant(condition, message, Err) { + if (Err === void 0) { + Err = Error; + } + if (!condition) { + throw new Err(message); + } + } + exports.invariant = invariant; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponentForMagnitude.js + var require_ComputeExponentForMagnitude = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponentForMagnitude.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ComputeExponentForMagnitude = void 0; + function ComputeExponentForMagnitude(numberFormat, magnitude, _a) { + var getInternalSlots = _a.getInternalSlots; + var internalSlots = getInternalSlots(numberFormat); + var notation = internalSlots.notation, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem; + switch (notation) { + case "standard": + return 0; + case "scientific": + return magnitude; + case "engineering": + return Math.floor(magnitude / 3) * 3; + default: { + var compactDisplay = internalSlots.compactDisplay, style = internalSlots.style, currencyDisplay = internalSlots.currencyDisplay; + var thresholdMap = void 0; + if (style === "currency" && currencyDisplay !== "name") { + var currency = dataLocaleData.numbers.currency[numberingSystem] || dataLocaleData.numbers.currency[dataLocaleData.numbers.nu[0]]; + thresholdMap = currency.short; + } else { + var decimal = dataLocaleData.numbers.decimal[numberingSystem] || dataLocaleData.numbers.decimal[dataLocaleData.numbers.nu[0]]; + thresholdMap = compactDisplay === "long" ? decimal.long : decimal.short; + } + if (!thresholdMap) { + return 0; + } + var num = String(Math.pow(10, magnitude)); + var thresholds = Object.keys(thresholdMap); + if (num < thresholds[0]) { + return 0; + } + if (num > thresholds[thresholds.length - 1]) { + return thresholds[thresholds.length - 1].length - 1; + } + var i = thresholds.indexOf(num); + if (i === -1) { + return 0; + } + var magnitudeKey = thresholds[i]; + var compactPattern = thresholdMap[magnitudeKey].other; + if (compactPattern === "0") { + return 0; + } + return magnitudeKey.length - thresholdMap[magnitudeKey].other.match(/0+/)[0].length; + } + } + } + exports.ComputeExponentForMagnitude = ComputeExponentForMagnitude; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawPrecision.js + var require_ToRawPrecision = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawPrecision.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ToRawPrecision = void 0; + var utils_1 = require_utils(); + function ToRawPrecision(x, minPrecision, maxPrecision) { + var p = maxPrecision; + var m; + var e; + var xFinal; + if (x === 0) { + m = (0, utils_1.repeat)("0", p); + e = 0; + xFinal = 0; + } else { + var xToString = x.toString(); + var xToStringExponentIndex = xToString.indexOf("e"); + var _a = xToString.split("e"), xToStringMantissa = _a[0], xToStringExponent = _a[1]; + var xToStringMantissaWithoutDecimalPoint = xToStringMantissa.replace(".", ""); + if (xToStringExponentIndex >= 0 && xToStringMantissaWithoutDecimalPoint.length <= p) { + e = +xToStringExponent; + m = xToStringMantissaWithoutDecimalPoint + (0, utils_1.repeat)("0", p - xToStringMantissaWithoutDecimalPoint.length); + xFinal = x; + } else { + e = (0, utils_1.getMagnitude)(x); + var decimalPlaceOffset = e - p + 1; + var n = Math.round(adjustDecimalPlace(x, decimalPlaceOffset)); + if (adjustDecimalPlace(n, p - 1) >= 10) { + e = e + 1; + n = Math.floor(n / 10); + } + m = n.toString(); + xFinal = adjustDecimalPlace(n, p - 1 - e); + } + } + var int; + if (e >= p - 1) { + m = m + (0, utils_1.repeat)("0", e - p + 1); + int = e + 1; + } else if (e >= 0) { + m = "".concat(m.slice(0, e + 1), ".").concat(m.slice(e + 1)); + int = e + 1; + } else { + m = "0.".concat((0, utils_1.repeat)("0", -e - 1)).concat(m); + int = 1; + } + if (m.indexOf(".") >= 0 && maxPrecision > minPrecision) { + var cut = maxPrecision - minPrecision; + while (cut > 0 && m[m.length - 1] === "0") { + m = m.slice(0, -1); + cut--; + } + if (m[m.length - 1] === ".") { + m = m.slice(0, -1); + } + } + return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; + function adjustDecimalPlace(x2, magnitude) { + return magnitude < 0 ? x2 * Math.pow(10, -magnitude) : x2 / Math.pow(10, magnitude); + } + } + exports.ToRawPrecision = ToRawPrecision; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawFixed.js + var require_ToRawFixed = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawFixed.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ToRawFixed = void 0; + var utils_1 = require_utils(); + function ToRawFixed(x, minFraction, maxFraction) { + var f = maxFraction; + var n = Math.round(x * Math.pow(10, f)); + var xFinal = n / Math.pow(10, f); + var m; + if (n < 1e21) { + m = n.toString(); + } else { + m = n.toString(); + var _a = m.split("e"), mantissa = _a[0], exponent = _a[1]; + m = mantissa.replace(".", ""); + m = m + (0, utils_1.repeat)("0", Math.max(+exponent - m.length + 1, 0)); + } + var int; + if (f !== 0) { + var k = m.length; + if (k <= f) { + var z = (0, utils_1.repeat)("0", f + 1 - k); + m = z + m; + k = f + 1; + } + var a = m.slice(0, k - f); + var b = m.slice(k - f); + m = "".concat(a, ".").concat(b); + int = a.length; + } else { + int = m.length; + } + var cut = maxFraction - minFraction; + while (cut > 0 && m[m.length - 1] === "0") { + m = m.slice(0, -1); + cut--; + } + if (m[m.length - 1] === ".") { + m = m.slice(0, -1); + } + return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; + } + exports.ToRawFixed = ToRawFixed; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToString.js + var require_FormatNumericToString = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToString.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.FormatNumericToString = void 0; + var _262_1 = require__(); + var ToRawPrecision_1 = require_ToRawPrecision(); + var utils_1 = require_utils(); + var ToRawFixed_1 = require_ToRawFixed(); + function FormatNumericToString(intlObject, x) { + var isNegative = x < 0 || (0, _262_1.SameValue)(x, -0); + if (isNegative) { + x = -x; + } + var result; + var rourndingType = intlObject.roundingType; + switch (rourndingType) { + case "significantDigits": + result = (0, ToRawPrecision_1.ToRawPrecision)(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits); + break; + case "fractionDigits": + result = (0, ToRawFixed_1.ToRawFixed)(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits); + break; + default: + result = (0, ToRawPrecision_1.ToRawPrecision)(x, 1, 2); + if (result.integerDigitsCount > 1) { + result = (0, ToRawFixed_1.ToRawFixed)(x, 0, 0); + } + break; + } + x = result.roundedNumber; + var string = result.formattedString; + var int = result.integerDigitsCount; + var minInteger = intlObject.minimumIntegerDigits; + if (int < minInteger) { + var forwardZeros = (0, utils_1.repeat)("0", minInteger - int); + string = forwardZeros + string; + } + if (isNegative) { + x = -x; + } + return { roundedNumber: x, formattedString: string }; + } + exports.FormatNumericToString = FormatNumericToString; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponent.js + var require_ComputeExponent = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponent.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ComputeExponent = void 0; + var utils_1 = require_utils(); + var ComputeExponentForMagnitude_1 = require_ComputeExponentForMagnitude(); + var FormatNumericToString_1 = require_FormatNumericToString(); + function ComputeExponent(numberFormat, x, _a) { + var getInternalSlots = _a.getInternalSlots; + if (x === 0) { + return [0, 0]; + } + if (x < 0) { + x = -x; + } + var magnitude = (0, utils_1.getMagnitude)(x); + var exponent = (0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(numberFormat, magnitude, { + getInternalSlots + }); + x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent); + var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(getInternalSlots(numberFormat), x); + if (formatNumberResult.roundedNumber === 0) { + return [exponent, magnitude]; + } + var newMagnitude = (0, utils_1.getMagnitude)(formatNumberResult.roundedNumber); + if (newMagnitude === magnitude - exponent) { + return [exponent, magnitude]; + } + return [ + (0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(numberFormat, magnitude + 1, { + getInternalSlots + }), + magnitude + 1 + ]; + } + exports.ComputeExponent = ComputeExponent; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CurrencyDigits.js + var require_CurrencyDigits = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CurrencyDigits.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.CurrencyDigits = void 0; + var _262_1 = require__(); + function CurrencyDigits(c, _a) { + var currencyDigitsData = _a.currencyDigitsData; + return (0, _262_1.HasOwnProperty)(currencyDigitsData, c) ? currencyDigitsData[c] : 2; + } + exports.CurrencyDigits = CurrencyDigits; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatApproximately.js + var require_FormatApproximately = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatApproximately.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.FormatApproximately = void 0; + function FormatApproximately(numberFormat, result, _a) { + var getInternalSlots = _a.getInternalSlots; + var internalSlots = getInternalSlots(numberFormat); + var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]; + var approximatelySign = symbols.approximatelySign; + result.push({ type: "approximatelySign", value: approximatelySign }); + return result; + } + exports.FormatApproximately = FormatApproximately; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/digit-mapping.generated.js + var require_digit_mapping_generated = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/digit-mapping.generated.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.digitMapping = void 0; + exports.digitMapping = { "adlm": ["\u{1E950}", "\u{1E951}", "\u{1E952}", "\u{1E953}", "\u{1E954}", "\u{1E955}", "\u{1E956}", "\u{1E957}", "\u{1E958}", "\u{1E959}"], "ahom": ["\u{11730}", "\u{11731}", "\u{11732}", "\u{11733}", "\u{11734}", "\u{11735}", "\u{11736}", "\u{11737}", "\u{11738}", "\u{11739}"], "arab": ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"], "arabext": ["\u06F0", "\u06F1", "\u06F2", "\u06F3", "\u06F4", "\u06F5", "\u06F6", "\u06F7", "\u06F8", "\u06F9"], "bali": ["\u1B50", "\u1B51", "\u1B52", "\u1B53", "\u1B54", "\u1B55", "\u1B56", "\u1B57", "\u1B58", "\u1B59"], "beng": ["\u09E6", "\u09E7", "\u09E8", "\u09E9", "\u09EA", "\u09EB", "\u09EC", "\u09ED", "\u09EE", "\u09EF"], "bhks": ["\u{11C50}", "\u{11C51}", "\u{11C52}", "\u{11C53}", "\u{11C54}", "\u{11C55}", "\u{11C56}", "\u{11C57}", "\u{11C58}", "\u{11C59}"], "brah": ["\u{11066}", "\u{11067}", "\u{11068}", "\u{11069}", "\u{1106A}", "\u{1106B}", "\u{1106C}", "\u{1106D}", "\u{1106E}", "\u{1106F}"], "cakm": ["\u{11136}", "\u{11137}", "\u{11138}", "\u{11139}", "\u{1113A}", "\u{1113B}", "\u{1113C}", "\u{1113D}", "\u{1113E}", "\u{1113F}"], "cham": ["\uAA50", "\uAA51", "\uAA52", "\uAA53", "\uAA54", "\uAA55", "\uAA56", "\uAA57", "\uAA58", "\uAA59"], "deva": ["\u0966", "\u0967", "\u0968", "\u0969", "\u096A", "\u096B", "\u096C", "\u096D", "\u096E", "\u096F"], "diak": ["\u{11950}", "\u{11951}", "\u{11952}", "\u{11953}", "\u{11954}", "\u{11955}", "\u{11956}", "\u{11957}", "\u{11958}", "\u{11959}"], "fullwide": ["\uFF10", "\uFF11", "\uFF12", "\uFF13", "\uFF14", "\uFF15", "\uFF16", "\uFF17", "\uFF18", "\uFF19"], "gong": ["\u{11DA0}", "\u{11DA1}", "\u{11DA2}", "\u{11DA3}", "\u{11DA4}", "\u{11DA5}", "\u{11DA6}", "\u{11DA7}", "\u{11DA8}", "\u{11DA9}"], "gonm": ["\u{11D50}", "\u{11D51}", "\u{11D52}", "\u{11D53}", "\u{11D54}", "\u{11D55}", "\u{11D56}", "\u{11D57}", "\u{11D58}", "\u{11D59}"], "gujr": ["\u0AE6", "\u0AE7", "\u0AE8", "\u0AE9", "\u0AEA", "\u0AEB", "\u0AEC", "\u0AED", "\u0AEE", "\u0AEF"], "guru": ["\u0A66", "\u0A67", "\u0A68", "\u0A69", "\u0A6A", "\u0A6B", "\u0A6C", "\u0A6D", "\u0A6E", "\u0A6F"], "hanidec": ["\u3007", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"], "hmng": ["\u{16B50}", "\u{16B51}", "\u{16B52}", "\u{16B53}", "\u{16B54}", "\u{16B55}", "\u{16B56}", "\u{16B57}", "\u{16B58}", "\u{16B59}"], "hmnp": ["\u{1E140}", "\u{1E141}", "\u{1E142}", "\u{1E143}", "\u{1E144}", "\u{1E145}", "\u{1E146}", "\u{1E147}", "\u{1E148}", "\u{1E149}"], "java": ["\uA9D0", "\uA9D1", "\uA9D2", "\uA9D3", "\uA9D4", "\uA9D5", "\uA9D6", "\uA9D7", "\uA9D8", "\uA9D9"], "kali": ["\uA900", "\uA901", "\uA902", "\uA903", "\uA904", "\uA905", "\uA906", "\uA907", "\uA908", "\uA909"], "khmr": ["\u17E0", "\u17E1", "\u17E2", "\u17E3", "\u17E4", "\u17E5", "\u17E6", "\u17E7", "\u17E8", "\u17E9"], "knda": ["\u0CE6", "\u0CE7", "\u0CE8", "\u0CE9", "\u0CEA", "\u0CEB", "\u0CEC", "\u0CED", "\u0CEE", "\u0CEF"], "lana": ["\u1A80", "\u1A81", "\u1A82", "\u1A83", "\u1A84", "\u1A85", "\u1A86", "\u1A87", "\u1A88", "\u1A89"], "lanatham": ["\u1A90", "\u1A91", "\u1A92", "\u1A93", "\u1A94", "\u1A95", "\u1A96", "\u1A97", "\u1A98", "\u1A99"], "laoo": ["\u0ED0", "\u0ED1", "\u0ED2", "\u0ED3", "\u0ED4", "\u0ED5", "\u0ED6", "\u0ED7", "\u0ED8", "\u0ED9"], "lepc": ["\u1A90", "\u1A91", "\u1A92", "\u1A93", "\u1A94", "\u1A95", "\u1A96", "\u1A97", "\u1A98", "\u1A99"], "limb": ["\u1946", "\u1947", "\u1948", "\u1949", "\u194A", "\u194B", "\u194C", "\u194D", "\u194E", "\u194F"], "mathbold": ["\u{1D7CE}", "\u{1D7CF}", "\u{1D7D0}", "\u{1D7D1}", "\u{1D7D2}", "\u{1D7D3}", "\u{1D7D4}", "\u{1D7D5}", "\u{1D7D6}", "\u{1D7D7}"], "mathdbl": ["\u{1D7D8}", "\u{1D7D9}", "\u{1D7DA}", "\u{1D7DB}", "\u{1D7DC}", "\u{1D7DD}", "\u{1D7DE}", "\u{1D7DF}", "\u{1D7E0}", "\u{1D7E1}"], "mathmono": ["\u{1D7F6}", "\u{1D7F7}", "\u{1D7F8}", "\u{1D7F9}", "\u{1D7FA}", "\u{1D7FB}", "\u{1D7FC}", "\u{1D7FD}", "\u{1D7FE}", "\u{1D7FF}"], "mathsanb": ["\u{1D7EC}", "\u{1D7ED}", "\u{1D7EE}", "\u{1D7EF}", "\u{1D7F0}", "\u{1D7F1}", "\u{1D7F2}", "\u{1D7F3}", "\u{1D7F4}", "\u{1D7F5}"], "mathsans": ["\u{1D7E2}", "\u{1D7E3}", "\u{1D7E4}", "\u{1D7E5}", "\u{1D7E6}", "\u{1D7E7}", "\u{1D7E8}", "\u{1D7E9}", "\u{1D7EA}", "\u{1D7EB}"], "mlym": ["\u0D66", "\u0D67", "\u0D68", "\u0D69", "\u0D6A", "\u0D6B", "\u0D6C", "\u0D6D", "\u0D6E", "\u0D6F"], "modi": ["\u{11650}", "\u{11651}", "\u{11652}", "\u{11653}", "\u{11654}", "\u{11655}", "\u{11656}", "\u{11657}", "\u{11658}", "\u{11659}"], "mong": ["\u1810", "\u1811", "\u1812", "\u1813", "\u1814", "\u1815", "\u1816", "\u1817", "\u1818", "\u1819"], "mroo": ["\u{16A60}", "\u{16A61}", "\u{16A62}", "\u{16A63}", "\u{16A64}", "\u{16A65}", "\u{16A66}", "\u{16A67}", "\u{16A68}", "\u{16A69}"], "mtei": ["\uABF0", "\uABF1", "\uABF2", "\uABF3", "\uABF4", "\uABF5", "\uABF6", "\uABF7", "\uABF8", "\uABF9"], "mymr": ["\u1040", "\u1041", "\u1042", "\u1043", "\u1044", "\u1045", "\u1046", "\u1047", "\u1048", "\u1049"], "mymrshan": ["\u1090", "\u1091", "\u1092", "\u1093", "\u1094", "\u1095", "\u1096", "\u1097", "\u1098", "\u1099"], "mymrtlng": ["\uA9F0", "\uA9F1", "\uA9F2", "\uA9F3", "\uA9F4", "\uA9F5", "\uA9F6", "\uA9F7", "\uA9F8", "\uA9F9"], "newa": ["\u{11450}", "\u{11451}", "\u{11452}", "\u{11453}", "\u{11454}", "\u{11455}", "\u{11456}", "\u{11457}", "\u{11458}", "\u{11459}"], "nkoo": ["\u07C0", "\u07C1", "\u07C2", "\u07C3", "\u07C4", "\u07C5", "\u07C6", "\u07C7", "\u07C8", "\u07C9"], "olck": ["\u1C50", "\u1C51", "\u1C52", "\u1C53", "\u1C54", "\u1C55", "\u1C56", "\u1C57", "\u1C58", "\u1C59"], "orya": ["\u0B66", "\u0B67", "\u0B68", "\u0B69", "\u0B6A", "\u0B6B", "\u0B6C", "\u0B6D", "\u0B6E", "\u0B6F"], "osma": ["\u{104A0}", "\u{104A1}", "\u{104A2}", "\u{104A3}", "\u{104A4}", "\u{104A5}", "\u{104A6}", "\u{104A7}", "\u{104A8}", "\u{104A9}"], "rohg": ["\u{10D30}", "\u{10D31}", "\u{10D32}", "\u{10D33}", "\u{10D34}", "\u{10D35}", "\u{10D36}", "\u{10D37}", "\u{10D38}", "\u{10D39}"], "saur": ["\uA8D0", "\uA8D1", "\uA8D2", "\uA8D3", "\uA8D4", "\uA8D5", "\uA8D6", "\uA8D7", "\uA8D8", "\uA8D9"], "segment": ["\u{1FBF0}", "\u{1FBF1}", "\u{1FBF2}", "\u{1FBF3}", "\u{1FBF4}", "\u{1FBF5}", "\u{1FBF6}", "\u{1FBF7}", "\u{1FBF8}", "\u{1FBF9}"], "shrd": ["\u{111D0}", "\u{111D1}", "\u{111D2}", "\u{111D3}", "\u{111D4}", "\u{111D5}", "\u{111D6}", "\u{111D7}", "\u{111D8}", "\u{111D9}"], "sind": ["\u{112F0}", "\u{112F1}", "\u{112F2}", "\u{112F3}", "\u{112F4}", "\u{112F5}", "\u{112F6}", "\u{112F7}", "\u{112F8}", "\u{112F9}"], "sinh": ["\u0DE6", "\u0DE7", "\u0DE8", "\u0DE9", "\u0DEA", "\u0DEB", "\u0DEC", "\u0DED", "\u0DEE", "\u0DEF"], "sora": ["\u{110F0}", "\u{110F1}", "\u{110F2}", "\u{110F3}", "\u{110F4}", "\u{110F5}", "\u{110F6}", "\u{110F7}", "\u{110F8}", "\u{110F9}"], "sund": ["\u1BB0", "\u1BB1", "\u1BB2", "\u1BB3", "\u1BB4", "\u1BB5", "\u1BB6", "\u1BB7", "\u1BB8", "\u1BB9"], "takr": ["\u{116C0}", "\u{116C1}", "\u{116C2}", "\u{116C3}", "\u{116C4}", "\u{116C5}", "\u{116C6}", "\u{116C7}", "\u{116C8}", "\u{116C9}"], "talu": ["\u19D0", "\u19D1", "\u19D2", "\u19D3", "\u19D4", "\u19D5", "\u19D6", "\u19D7", "\u19D8", "\u19D9"], "tamldec": ["\u0BE6", "\u0BE7", "\u0BE8", "\u0BE9", "\u0BEA", "\u0BEB", "\u0BEC", "\u0BED", "\u0BEE", "\u0BEF"], "telu": ["\u0C66", "\u0C67", "\u0C68", "\u0C69", "\u0C6A", "\u0C6B", "\u0C6C", "\u0C6D", "\u0C6E", "\u0C6F"], "thai": ["\u0E50", "\u0E51", "\u0E52", "\u0E53", "\u0E54", "\u0E55", "\u0E56", "\u0E57", "\u0E58", "\u0E59"], "tibt": ["\u0F20", "\u0F21", "\u0F22", "\u0F23", "\u0F24", "\u0F25", "\u0F26", "\u0F27", "\u0F28", "\u0F29"], "tirh": ["\u{114D0}", "\u{114D1}", "\u{114D2}", "\u{114D3}", "\u{114D4}", "\u{114D5}", "\u{114D6}", "\u{114D7}", "\u{114D8}", "\u{114D9}"], "vaii": ["\u1620", "\u1621", "\u1622", "\u1623", "\u1624", "\u1625", "\u1626", "\u1627", "\u1628", "\u1629"], "wara": ["\u{118E0}", "\u{118E1}", "\u{118E2}", "\u{118E3}", "\u{118E4}", "\u{118E5}", "\u{118E6}", "\u{118E7}", "\u{118E8}", "\u{118E9}"], "wcho": ["\u{1E2F0}", "\u{1E2F1}", "\u{1E2F2}", "\u{1E2F3}", "\u{1E2F4}", "\u{1E2F5}", "\u{1E2F6}", "\u{1E2F7}", "\u{1E2F8}", "\u{1E2F9}"] }; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/regex.generated.js + var require_regex_generated = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/regex.generated.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.S_UNICODE_REGEX = void 0; + exports.S_UNICODE_REGEX = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20BF\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC1\uFDFC\uFDFD\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEE0-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDD78\uDD7A-\uDDCB\uDDCD-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6\uDF00-\uDF92\uDF94-\uDFCA]/; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/format_to_parts.js + var require_format_to_parts = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/format_to_parts.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var ToRawFixed_1 = require_ToRawFixed(); + var digit_mapping_generated_1 = require_digit_mapping_generated(); + var regex_generated_1 = require_regex_generated(); + var CARET_S_UNICODE_REGEX = new RegExp("^".concat(regex_generated_1.S_UNICODE_REGEX.source)); + var S_DOLLAR_UNICODE_REGEX = new RegExp("".concat(regex_generated_1.S_UNICODE_REGEX.source, "$")); + var CLDR_NUMBER_PATTERN = /[#0](?:[\.,][#0]+)*/g; + function formatToParts(numberResult, data, pl, options) { + var sign = numberResult.sign, exponent = numberResult.exponent, magnitude = numberResult.magnitude; + var notation = options.notation, style = options.style, numberingSystem = options.numberingSystem; + var defaultNumberingSystem = data.numbers.nu[0]; + var compactNumberPattern = null; + if (notation === "compact" && magnitude) { + compactNumberPattern = getCompactDisplayPattern(numberResult, pl, data, style, options.compactDisplay, options.currencyDisplay, numberingSystem); + } + var nonNameCurrencyPart; + if (style === "currency" && options.currencyDisplay !== "name") { + var byCurrencyDisplay = data.currencies[options.currency]; + if (byCurrencyDisplay) { + switch (options.currencyDisplay) { + case "code": + nonNameCurrencyPart = options.currency; + break; + case "symbol": + nonNameCurrencyPart = byCurrencyDisplay.symbol; + break; + default: + nonNameCurrencyPart = byCurrencyDisplay.narrow; + break; + } + } else { + nonNameCurrencyPart = options.currency; + } + } + var numberPattern; + if (!compactNumberPattern) { + if (style === "decimal" || style === "unit" || style === "currency" && options.currencyDisplay === "name") { + var decimalData = data.numbers.decimal[numberingSystem] || data.numbers.decimal[defaultNumberingSystem]; + numberPattern = getPatternForSign(decimalData.standard, sign); + } else if (style === "currency") { + var currencyData = data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]; + numberPattern = getPatternForSign(currencyData[options.currencySign], sign); + } else { + var percentPattern = data.numbers.percent[numberingSystem] || data.numbers.percent[defaultNumberingSystem]; + numberPattern = getPatternForSign(percentPattern, sign); + } + } else { + numberPattern = compactNumberPattern; + } + var decimalNumberPattern = CLDR_NUMBER_PATTERN.exec(numberPattern)[0]; + numberPattern = numberPattern.replace(CLDR_NUMBER_PATTERN, "{0}").replace(/'(.)'/g, "$1"); + if (style === "currency" && options.currencyDisplay !== "name") { + var currencyData = data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]; + var afterCurrency = currencyData.currencySpacing.afterInsertBetween; + if (afterCurrency && !S_DOLLAR_UNICODE_REGEX.test(nonNameCurrencyPart)) { + numberPattern = numberPattern.replace("\xA4{0}", "\xA4".concat(afterCurrency, "{0}")); + } + var beforeCurrency = currencyData.currencySpacing.beforeInsertBetween; + if (beforeCurrency && !CARET_S_UNICODE_REGEX.test(nonNameCurrencyPart)) { + numberPattern = numberPattern.replace("{0}\xA4", "{0}".concat(beforeCurrency, "\xA4")); + } + } + var numberPatternParts = numberPattern.split(/({c:[^}]+}|\{0\}|[¤%\-\+])/g); + var numberParts = []; + var symbols = data.numbers.symbols[numberingSystem] || data.numbers.symbols[defaultNumberingSystem]; + for (var _i = 0, numberPatternParts_1 = numberPatternParts; _i < numberPatternParts_1.length; _i++) { + var part = numberPatternParts_1[_i]; + if (!part) { + continue; + } + switch (part) { + case "{0}": { + numberParts.push.apply(numberParts, paritionNumberIntoParts( + symbols, + numberResult, + notation, + exponent, + numberingSystem, + // If compact number pattern exists, do not insert group separators. + !compactNumberPattern && Boolean(options.useGrouping), + decimalNumberPattern + )); + break; + } + case "-": + numberParts.push({ type: "minusSign", value: symbols.minusSign }); + break; + case "+": + numberParts.push({ type: "plusSign", value: symbols.plusSign }); + break; + case "%": + numberParts.push({ type: "percentSign", value: symbols.percentSign }); + break; + case "\xA4": + numberParts.push({ type: "currency", value: nonNameCurrencyPart }); + break; + default: + if (/^\{c:/.test(part)) { + numberParts.push({ + type: "compact", + value: part.substring(3, part.length - 1) + }); + } else { + numberParts.push({ type: "literal", value: part }); + } + break; + } + } + switch (style) { + case "currency": { + if (options.currencyDisplay === "name") { + var unitPattern = (data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]).unitPattern; + var unitName = void 0; + var currencyNameData = data.currencies[options.currency]; + if (currencyNameData) { + unitName = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), currencyNameData.displayName); + } else { + unitName = options.currency; + } + var unitPatternParts = unitPattern.split(/(\{[01]\})/g); + var result = []; + for (var _a = 0, unitPatternParts_1 = unitPatternParts; _a < unitPatternParts_1.length; _a++) { + var part = unitPatternParts_1[_a]; + switch (part) { + case "{0}": + result.push.apply(result, numberParts); + break; + case "{1}": + result.push({ type: "currency", value: unitName }); + break; + default: + if (part) { + result.push({ type: "literal", value: part }); + } + break; + } + } + return result; + } else { + return numberParts; + } + } + case "unit": { + var unit = options.unit, unitDisplay = options.unitDisplay; + var unitData = data.units.simple[unit]; + var unitPattern = void 0; + if (unitData) { + unitPattern = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), data.units.simple[unit][unitDisplay]); + } else { + var _b = unit.split("-per-"), numeratorUnit = _b[0], denominatorUnit = _b[1]; + unitData = data.units.simple[numeratorUnit]; + var numeratorUnitPattern = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), data.units.simple[numeratorUnit][unitDisplay]); + var perUnitPattern = data.units.simple[denominatorUnit].perUnit[unitDisplay]; + if (perUnitPattern) { + unitPattern = perUnitPattern.replace("{0}", numeratorUnitPattern); + } else { + var perPattern = data.units.compound.per[unitDisplay]; + var denominatorPattern = selectPlural(pl, 1, data.units.simple[denominatorUnit][unitDisplay]); + unitPattern = unitPattern = perPattern.replace("{0}", numeratorUnitPattern).replace("{1}", denominatorPattern.replace("{0}", "")); + } + } + var result = []; + for (var _c = 0, _d = unitPattern.split(/(\s*\{0\}\s*)/); _c < _d.length; _c++) { + var part = _d[_c]; + var interpolateMatch = /^(\s*)\{0\}(\s*)$/.exec(part); + if (interpolateMatch) { + if (interpolateMatch[1]) { + result.push({ type: "literal", value: interpolateMatch[1] }); + } + result.push.apply(result, numberParts); + if (interpolateMatch[2]) { + result.push({ type: "literal", value: interpolateMatch[2] }); + } + } else if (part) { + result.push({ type: "unit", value: part }); + } + } + return result; + } + default: + return numberParts; + } + } + exports.default = formatToParts; + function paritionNumberIntoParts(symbols, numberResult, notation, exponent, numberingSystem, useGrouping, decimalNumberPattern) { + var result = []; + var n = numberResult.formattedString, x = numberResult.roundedNumber; + if (isNaN(x)) { + return [{ type: "nan", value: n }]; + } else if (!isFinite(x)) { + return [{ type: "infinity", value: n }]; + } + var digitReplacementTable = digit_mapping_generated_1.digitMapping[numberingSystem]; + if (digitReplacementTable) { + n = n.replace(/\d/g, function(digit) { + return digitReplacementTable[+digit] || digit; + }); + } + var decimalSepIndex = n.indexOf("."); + var integer; + var fraction; + if (decimalSepIndex > 0) { + integer = n.slice(0, decimalSepIndex); + fraction = n.slice(decimalSepIndex + 1); + } else { + integer = n; + } + if (useGrouping && (notation !== "compact" || x >= 1e4)) { + var groupSepSymbol = symbols.group; + var groups = []; + var integerNumberPattern = decimalNumberPattern.split(".")[0]; + var patternGroups = integerNumberPattern.split(","); + var primaryGroupingSize = 3; + var secondaryGroupingSize = 3; + if (patternGroups.length > 1) { + primaryGroupingSize = patternGroups[patternGroups.length - 1].length; + } + if (patternGroups.length > 2) { + secondaryGroupingSize = patternGroups[patternGroups.length - 2].length; + } + var i = integer.length - primaryGroupingSize; + if (i > 0) { + groups.push(integer.slice(i, i + primaryGroupingSize)); + for (i -= secondaryGroupingSize; i > 0; i -= secondaryGroupingSize) { + groups.push(integer.slice(i, i + secondaryGroupingSize)); + } + groups.push(integer.slice(0, i + secondaryGroupingSize)); + } else { + groups.push(integer); + } + while (groups.length > 0) { + var integerGroup = groups.pop(); + result.push({ type: "integer", value: integerGroup }); + if (groups.length > 0) { + result.push({ type: "group", value: groupSepSymbol }); + } + } + } else { + result.push({ type: "integer", value: integer }); + } + if (fraction !== void 0) { + result.push({ type: "decimal", value: symbols.decimal }, { type: "fraction", value: fraction }); + } + if ((notation === "scientific" || notation === "engineering") && isFinite(x)) { + result.push({ type: "exponentSeparator", value: symbols.exponential }); + if (exponent < 0) { + result.push({ type: "exponentMinusSign", value: symbols.minusSign }); + exponent = -exponent; + } + var exponentResult = (0, ToRawFixed_1.ToRawFixed)(exponent, 0, 0); + result.push({ + type: "exponentInteger", + value: exponentResult.formattedString + }); + } + return result; + } + function getPatternForSign(pattern, sign) { + if (pattern.indexOf(";") < 0) { + pattern = "".concat(pattern, ";-").concat(pattern); + } + var _a = pattern.split(";"), zeroPattern = _a[0], negativePattern = _a[1]; + switch (sign) { + case 0: + return zeroPattern; + case -1: + return negativePattern; + default: + return negativePattern.indexOf("-") >= 0 ? negativePattern.replace(/-/g, "+") : "+".concat(zeroPattern); + } + } + function getCompactDisplayPattern(numberResult, pl, data, style, compactDisplay, currencyDisplay, numberingSystem) { + var _a; + var roundedNumber = numberResult.roundedNumber, sign = numberResult.sign, magnitude = numberResult.magnitude; + var magnitudeKey = String(Math.pow(10, magnitude)); + var defaultNumberingSystem = data.numbers.nu[0]; + var pattern; + if (style === "currency" && currencyDisplay !== "name") { + var byNumberingSystem = data.numbers.currency; + var currencyData = byNumberingSystem[numberingSystem] || byNumberingSystem[defaultNumberingSystem]; + var compactPluralRules = (_a = currencyData.short) === null || _a === void 0 ? void 0 : _a[magnitudeKey]; + if (!compactPluralRules) { + return null; + } + pattern = selectPlural(pl, roundedNumber, compactPluralRules); + } else { + var byNumberingSystem = data.numbers.decimal; + var byCompactDisplay = byNumberingSystem[numberingSystem] || byNumberingSystem[defaultNumberingSystem]; + var compactPlaralRule = byCompactDisplay[compactDisplay][magnitudeKey]; + if (!compactPlaralRule) { + return null; + } + pattern = selectPlural(pl, roundedNumber, compactPlaralRule); + } + if (pattern === "0") { + return null; + } + pattern = getPatternForSign(pattern, sign).replace(/([^\s;\-\+\d¤]+)/g, "{c:$1}").replace(/0+/, "0"); + return pattern; + } + function selectPlural(pl, x, rules) { + return rules[pl.select(x)] || rules.other; + } + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberPattern.js + var require_PartitionNumberPattern = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberPattern.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.PartitionNumberPattern = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var FormatNumericToString_1 = require_FormatNumericToString(); + var _262_1 = require__(); + var ComputeExponent_1 = require_ComputeExponent(); + var format_to_parts_1 = tslib_1.__importDefault(require_format_to_parts()); + function PartitionNumberPattern(numberFormat, x, _a) { + var _b; + var getInternalSlots = _a.getInternalSlots; + var internalSlots = getInternalSlots(numberFormat); + var pl = internalSlots.pl, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem; + var symbols = dataLocaleData.numbers.symbols[numberingSystem] || dataLocaleData.numbers.symbols[dataLocaleData.numbers.nu[0]]; + var magnitude = 0; + var exponent = 0; + var n; + if (isNaN(x)) { + n = symbols.nan; + } else if (x == Number.POSITIVE_INFINITY || x == Number.NEGATIVE_INFINITY) { + n = symbols.infinity; + } else { + if (!(0, _262_1.SameValue)(x, -0)) { + if (!isFinite(x)) { + throw new Error("Input must be a mathematical value"); + } + if (internalSlots.style == "percent") { + x *= 100; + } + ; + _b = (0, ComputeExponent_1.ComputeExponent)(numberFormat, x, { + getInternalSlots + }), exponent = _b[0], magnitude = _b[1]; + x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent); + } + var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(internalSlots, x); + n = formatNumberResult.formattedString; + x = formatNumberResult.roundedNumber; + } + var sign; + var signDisplay = internalSlots.signDisplay; + switch (signDisplay) { + case "never": + sign = 0; + break; + case "auto": + if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) { + sign = 0; + } else { + sign = -1; + } + break; + case "always": + if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) { + sign = 1; + } else { + sign = -1; + } + break; + default: + if (x === 0 || isNaN(x)) { + sign = 0; + } else if (x > 0) { + sign = 1; + } else { + sign = -1; + } + } + return (0, format_to_parts_1.default)({ roundedNumber: x, formattedString: n, exponent, magnitude, sign }, internalSlots.dataLocaleData, pl, internalSlots); + } + exports.PartitionNumberPattern = PartitionNumberPattern; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToParts.js + var require_FormatNumericToParts = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToParts.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.FormatNumericToParts = void 0; + var PartitionNumberPattern_1 = require_PartitionNumberPattern(); + var _262_1 = require__(); + function FormatNumericToParts(nf, x, implDetails) { + var parts = (0, PartitionNumberPattern_1.PartitionNumberPattern)(nf, x, implDetails); + var result = (0, _262_1.ArrayCreate)(0); + for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { + var part = parts_1[_i]; + result.push({ + type: part.type, + value: part.value + }); + } + return result; + } + exports.FormatNumericToParts = FormatNumericToParts; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/GetUnsignedRoundingMode.js + var require_GetUnsignedRoundingMode = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/GetUnsignedRoundingMode.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.GetUnsignedRoundingMode = void 0; + var negativeMapping = { + ceil: "zero", + floor: "infinity", + expand: "infinity", + trunc: "zero", + halfCeil: "half-zero", + halfFloor: "half-infinity", + halfExpand: "half-infinity", + halfTrunc: "half-zero", + halfEven: "half-even" + }; + var positiveMapping = { + ceil: "infinity", + floor: "zero", + expand: "infinity", + trunc: "zero", + halfCeil: "half-infinity", + halfFloor: "half-zero", + halfExpand: "half-infinity", + halfTrunc: "half-zero", + halfEven: "half-even" + }; + function GetUnsignedRoundingMode(roundingMode, isNegative) { + if (isNegative) { + return negativeMapping[roundingMode]; + } + return positiveMapping[roundingMode]; + } + exports.GetUnsignedRoundingMode = GetUnsignedRoundingMode; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/CanonicalizeLocaleList.js + var require_CanonicalizeLocaleList2 = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/CanonicalizeLocaleList.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.CanonicalizeLocaleList = void 0; + function CanonicalizeLocaleList(locales) { + return Intl.getCanonicalLocales(locales); + } + exports.CanonicalizeLocaleList = CanonicalizeLocaleList; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/utils.js + var require_utils2 = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/utils.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = void 0; + exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; + function invariant(condition, message, Err) { + if (Err === void 0) { + Err = Error; + } + if (!condition) { + throw new Err(message); + } + } + exports.invariant = invariant; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestAvailableLocale.js + var require_BestAvailableLocale = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestAvailableLocale.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.BestAvailableLocale = void 0; + function BestAvailableLocale(availableLocales, locale) { + var candidate = locale; + while (true) { + if (availableLocales.has(candidate)) { + return candidate; + } + var pos = candidate.lastIndexOf("-"); + if (!~pos) { + return void 0; + } + if (pos >= 2 && candidate[pos - 2] === "-") { + pos -= 2; + } + candidate = candidate.slice(0, pos); + } + } + exports.BestAvailableLocale = BestAvailableLocale; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupMatcher.js + var require_LookupMatcher = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupMatcher.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.LookupMatcher = void 0; + var utils_1 = require_utils2(); + var BestAvailableLocale_1 = require_BestAvailableLocale(); + function LookupMatcher(availableLocales, requestedLocales, getDefaultLocale) { + var result = { locale: "" }; + for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { + var locale = requestedLocales_1[_i]; + var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); + var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); + if (availableLocale) { + result.locale = availableLocale; + if (locale !== noExtensionLocale) { + result.extension = locale.slice(noExtensionLocale.length + 1, locale.length); + } + return result; + } + } + result.locale = getDefaultLocale(); + return result; + } + exports.LookupMatcher = LookupMatcher; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestFitMatcher.js + var require_BestFitMatcher = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestFitMatcher.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.BestFitMatcher = void 0; + var BestAvailableLocale_1 = require_BestAvailableLocale(); + var utils_1 = require_utils2(); + function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) { + var minimizedAvailableLocaleMap = {}; + var availableLocaleMap = {}; + var canonicalizedLocaleMap = {}; + var minimizedAvailableLocales = /* @__PURE__ */ new Set(); + availableLocales.forEach(function(locale2) { + var minimizedLocale = new Intl.Locale(locale2).minimize().toString(); + var canonicalizedLocale = Intl.getCanonicalLocales(locale2)[0] || locale2; + minimizedAvailableLocaleMap[minimizedLocale] = locale2; + availableLocaleMap[locale2] = locale2; + canonicalizedLocaleMap[canonicalizedLocale] = locale2; + minimizedAvailableLocales.add(minimizedLocale); + minimizedAvailableLocales.add(locale2); + minimizedAvailableLocales.add(canonicalizedLocale); + }); + var foundLocale; + for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { + var l = requestedLocales_1[_i]; + if (foundLocale) { + break; + } + var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); + if (availableLocales.has(noExtensionLocale)) { + foundLocale = noExtensionLocale; + break; + } + if (minimizedAvailableLocales.has(noExtensionLocale)) { + foundLocale = noExtensionLocale; + break; + } + var locale = new Intl.Locale(noExtensionLocale); + var maximizedRequestedLocale = locale.maximize().toString(); + var minimizedRequestedLocale = locale.minimize().toString(); + if (minimizedAvailableLocales.has(minimizedRequestedLocale)) { + foundLocale = minimizedRequestedLocale; + break; + } + foundLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(minimizedAvailableLocales, maximizedRequestedLocale); + } + if (!foundLocale) { + return { locale: getDefaultLocale() }; + } + return { + locale: availableLocaleMap[foundLocale] || canonicalizedLocaleMap[foundLocale] || minimizedAvailableLocaleMap[foundLocale] || foundLocale + }; + } + exports.BestFitMatcher = BestFitMatcher; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/UnicodeExtensionValue.js + var require_UnicodeExtensionValue = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/UnicodeExtensionValue.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.UnicodeExtensionValue = void 0; + var utils_1 = require_utils2(); + function UnicodeExtensionValue(extension, key) { + (0, utils_1.invariant)(key.length === 2, "key must have 2 elements"); + var size = extension.length; + var searchValue = "-".concat(key, "-"); + var pos = extension.indexOf(searchValue); + if (pos !== -1) { + var start = pos + 4; + var end = start; + var k = start; + var done = false; + while (!done) { + var e = extension.indexOf("-", k); + var len = void 0; + if (e === -1) { + len = size - k; + } else { + len = e - k; + } + if (len === 2) { + done = true; + } else if (e === -1) { + end = size; + done = true; + } else { + end = e; + k = e + 1; + } + } + return extension.slice(start, end); + } + searchValue = "-".concat(key); + pos = extension.indexOf(searchValue); + if (pos !== -1 && pos + 3 === size) { + return ""; + } + return void 0; + } + exports.UnicodeExtensionValue = UnicodeExtensionValue; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/ResolveLocale.js + var require_ResolveLocale = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/ResolveLocale.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ResolveLocale = void 0; + var LookupMatcher_1 = require_LookupMatcher(); + var BestFitMatcher_1 = require_BestFitMatcher(); + var utils_1 = require_utils2(); + var UnicodeExtensionValue_1 = require_UnicodeExtensionValue(); + function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) { + var matcher = options.localeMatcher; + var r; + if (matcher === "lookup") { + r = (0, LookupMatcher_1.LookupMatcher)(availableLocales, requestedLocales, getDefaultLocale); + } else { + r = (0, BestFitMatcher_1.BestFitMatcher)(availableLocales, requestedLocales, getDefaultLocale); + } + var foundLocale = r.locale; + var result = { locale: "", dataLocale: foundLocale }; + var supportedExtension = "-u"; + for (var _i = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _i < relevantExtensionKeys_1.length; _i++) { + var key = relevantExtensionKeys_1[_i]; + (0, utils_1.invariant)(foundLocale in localeData, "Missing locale data for ".concat(foundLocale)); + var foundLocaleData = localeData[foundLocale]; + (0, utils_1.invariant)(typeof foundLocaleData === "object" && foundLocaleData !== null, "locale data ".concat(key, " must be an object")); + var keyLocaleData = foundLocaleData[key]; + (0, utils_1.invariant)(Array.isArray(keyLocaleData), "keyLocaleData for ".concat(key, " must be an array")); + var value = keyLocaleData[0]; + (0, utils_1.invariant)(typeof value === "string" || value === null, "value must be string or null but got ".concat(typeof value, " in key ").concat(key)); + var supportedExtensionAddition = ""; + if (r.extension) { + var requestedValue = (0, UnicodeExtensionValue_1.UnicodeExtensionValue)(r.extension, key); + if (requestedValue !== void 0) { + if (requestedValue !== "") { + if (~keyLocaleData.indexOf(requestedValue)) { + value = requestedValue; + supportedExtensionAddition = "-".concat(key, "-").concat(value); + } + } else if (~requestedValue.indexOf("true")) { + value = "true"; + supportedExtensionAddition = "-".concat(key); + } + } + } + if (key in options) { + var optionsValue = options[key]; + (0, utils_1.invariant)(typeof optionsValue === "string" || typeof optionsValue === "undefined" || optionsValue === null, "optionsValue must be String, Undefined or Null"); + if (~keyLocaleData.indexOf(optionsValue)) { + if (optionsValue !== value) { + value = optionsValue; + supportedExtensionAddition = ""; + } + } + } + result[key] = value; + supportedExtension += supportedExtensionAddition; + } + if (supportedExtension.length > 2) { + var privateIndex = foundLocale.indexOf("-x-"); + if (privateIndex === -1) { + foundLocale = foundLocale + supportedExtension; + } else { + var preExtension = foundLocale.slice(0, privateIndex); + var postExtension = foundLocale.slice(privateIndex, foundLocale.length); + foundLocale = preExtension + supportedExtension + postExtension; + } + foundLocale = Intl.getCanonicalLocales(foundLocale)[0]; + } + result.locale = foundLocale; + return result; + } + exports.ResolveLocale = ResolveLocale; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupSupportedLocales.js + var require_LookupSupportedLocales = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupSupportedLocales.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.LookupSupportedLocales = void 0; + var utils_1 = require_utils2(); + var BestAvailableLocale_1 = require_BestAvailableLocale(); + function LookupSupportedLocales(availableLocales, requestedLocales) { + var subset = []; + for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { + var locale = requestedLocales_1[_i]; + var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); + var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); + if (availableLocale) { + subset.push(availableLocale); + } + } + return subset; + } + exports.LookupSupportedLocales = LookupSupportedLocales; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/index.js + var require_intl_localematcher = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/index.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.ResolveLocale = exports.LookupSupportedLocales = exports.match = void 0; + var CanonicalizeLocaleList_1 = require_CanonicalizeLocaleList2(); + var ResolveLocale_1 = require_ResolveLocale(); + function match(requestedLocales, availableLocales, defaultLocale, opts) { + var locales = availableLocales.reduce(function(all, l) { + all.add(l); + return all; + }, /* @__PURE__ */ new Set()); + return (0, ResolveLocale_1.ResolveLocale)(locales, (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(requestedLocales), { + localeMatcher: (opts === null || opts === void 0 ? void 0 : opts.algorithm) || "best fit" + }, [], {}, function() { + return defaultLocale; + }).locale; + } + exports.match = match; + var LookupSupportedLocales_1 = require_LookupSupportedLocales(); + Object.defineProperty(exports, "LookupSupportedLocales", { enumerable: true, get: function() { + return LookupSupportedLocales_1.LookupSupportedLocales; + } }); + var ResolveLocale_2 = require_ResolveLocale(); + Object.defineProperty(exports, "ResolveLocale", { enumerable: true, get: function() { + return ResolveLocale_2.ResolveLocale; + } }); + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatUnitOptions.js + var require_SetNumberFormatUnitOptions = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatUnitOptions.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.SetNumberFormatUnitOptions = void 0; + var GetOption_1 = require_GetOption(); + var IsWellFormedCurrencyCode_1 = require_IsWellFormedCurrencyCode(); + var IsWellFormedUnitIdentifier_1 = require_IsWellFormedUnitIdentifier(); + function SetNumberFormatUnitOptions(nf, options, _a) { + if (options === void 0) { + options = /* @__PURE__ */ Object.create(null); + } + var getInternalSlots = _a.getInternalSlots; + var internalSlots = getInternalSlots(nf); + var style = (0, GetOption_1.GetOption)(options, "style", "string", ["decimal", "percent", "currency", "unit"], "decimal"); + internalSlots.style = style; + var currency = (0, GetOption_1.GetOption)(options, "currency", "string", void 0, void 0); + if (currency !== void 0 && !(0, IsWellFormedCurrencyCode_1.IsWellFormedCurrencyCode)(currency)) { + throw RangeError("Malformed currency code"); + } + if (style === "currency" && currency === void 0) { + throw TypeError("currency cannot be undefined"); + } + var currencyDisplay = (0, GetOption_1.GetOption)(options, "currencyDisplay", "string", ["code", "symbol", "narrowSymbol", "name"], "symbol"); + var currencySign = (0, GetOption_1.GetOption)(options, "currencySign", "string", ["standard", "accounting"], "standard"); + var unit = (0, GetOption_1.GetOption)(options, "unit", "string", void 0, void 0); + if (unit !== void 0 && !(0, IsWellFormedUnitIdentifier_1.IsWellFormedUnitIdentifier)(unit)) { + throw RangeError("Invalid unit argument for Intl.NumberFormat()"); + } + if (style === "unit" && unit === void 0) { + throw TypeError("unit cannot be undefined"); + } + var unitDisplay = (0, GetOption_1.GetOption)(options, "unitDisplay", "string", ["short", "narrow", "long"], "short"); + if (style === "currency") { + internalSlots.currency = currency.toUpperCase(); + internalSlots.currencyDisplay = currencyDisplay; + internalSlots.currencySign = currencySign; + } + if (style === "unit") { + internalSlots.unit = unit; + internalSlots.unitDisplay = unitDisplay; + } + } + exports.SetNumberFormatUnitOptions = SetNumberFormatUnitOptions; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatDigitOptions.js + var require_SetNumberFormatDigitOptions = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatDigitOptions.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.SetNumberFormatDigitOptions = void 0; + var GetNumberOption_1 = require_GetNumberOption(); + var DefaultNumberOption_1 = require_DefaultNumberOption(); + var GetOption_1 = require_GetOption(); + function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefault, notation) { + var mnid = (0, GetNumberOption_1.GetNumberOption)(opts, "minimumIntegerDigits", 1, 21, 1); + var mnfd = opts.minimumFractionDigits; + var mxfd = opts.maximumFractionDigits; + var mnsd = opts.minimumSignificantDigits; + var mxsd = opts.maximumSignificantDigits; + internalSlots.minimumIntegerDigits = mnid; + var roundingPriority = (0, GetOption_1.GetOption)(opts, "roundingPriority", "string", ["auto", "morePrecision", "lessPrecision"], "auto"); + var hasSd = mnsd !== void 0 || mxsd !== void 0; + var hasFd = mnfd !== void 0 || mxfd !== void 0; + var needSd = true; + var needFd = true; + if (roundingPriority === "auto") { + needSd = hasSd; + if (hasSd || !hasFd && notation === "compact") { + needFd = false; + } + } + if (needSd) { + if (hasSd) { + mnsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnsd, 1, 21, 1); + mxsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxsd, mnsd, 21, 21); + internalSlots.minimumSignificantDigits = mnsd; + internalSlots.maximumSignificantDigits = mxsd; + } else { + internalSlots.minimumSignificantDigits = 1; + internalSlots.maximumSignificantDigits = 21; + } + } + if (needFd) { + if (hasFd) { + mnfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnfd, 0, 20, void 0); + mxfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxfd, 0, 20, void 0); + if (mnfd === void 0) { + mnfd = Math.min(mnfdDefault, mxfd); + } else if (mxfd === void 0) { + mxfd = Math.max(mxfdDefault, mnfd); + } else if (mnfd > mxfd) { + throw new RangeError("Invalid range, ".concat(mnfd, " > ").concat(mxfd)); + } + internalSlots.minimumFractionDigits = mnfd; + internalSlots.maximumFractionDigits = mxfd; + } else { + internalSlots.minimumFractionDigits = mnfdDefault; + internalSlots.maximumFractionDigits = mxfdDefault; + } + } + if (needSd || needFd) { + if (roundingPriority === "morePrecision") { + internalSlots.roundingType = "morePrecision"; + } else if (roundingPriority === "lessPrecision") { + internalSlots.roundingType = "lessPrecision"; + } else if (hasSd) { + internalSlots.roundingType = "significantDigits"; + } else { + internalSlots.roundingType = "fractionDigits"; + } + } else { + internalSlots.roundingType = "morePrecision"; + internalSlots.minimumFractionDigits = 0; + internalSlots.maximumFractionDigits = 0; + internalSlots.minimumSignificantDigits = 1; + internalSlots.maximumSignificantDigits = 2; + } + } + exports.SetNumberFormatDigitOptions = SetNumberFormatDigitOptions; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/InitializeNumberFormat.js + var require_InitializeNumberFormat = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/InitializeNumberFormat.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.InitializeNumberFormat = void 0; + var CanonicalizeLocaleList_1 = require_CanonicalizeLocaleList(); + var GetOption_1 = require_GetOption(); + var intl_localematcher_1 = require_intl_localematcher(); + var SetNumberFormatUnitOptions_1 = require_SetNumberFormatUnitOptions(); + var CurrencyDigits_1 = require_CurrencyDigits(); + var SetNumberFormatDigitOptions_1 = require_SetNumberFormatDigitOptions(); + var utils_1 = require_utils(); + var CoerceOptionsToObject_1 = require_CoerceOptionsToObject(); + var GetNumberOption_1 = require_GetNumberOption(); + var GetStringOrBooleanOption_1 = require_GetStringOrBooleanOption(); + var VALID_ROUND_INCREMENT_VALUES = [ + 1, + 2, + 5, + 10, + 20, + 25, + 50, + 100, + 200, + 250, + 500, + 1e3, + 2e3 + ]; + function InitializeNumberFormat(nf, locales, opts, _a) { + var getInternalSlots = _a.getInternalSlots, localeData = _a.localeData, availableLocales = _a.availableLocales, numberingSystemNames = _a.numberingSystemNames, getDefaultLocale = _a.getDefaultLocale, currencyDigitsData = _a.currencyDigitsData; + var requestedLocales = (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(locales); + var options = (0, CoerceOptionsToObject_1.CoerceOptionsToObject)(opts); + var opt = /* @__PURE__ */ Object.create(null); + var matcher = (0, GetOption_1.GetOption)(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); + opt.localeMatcher = matcher; + var numberingSystem = (0, GetOption_1.GetOption)(options, "numberingSystem", "string", void 0, void 0); + if (numberingSystem !== void 0 && numberingSystemNames.indexOf(numberingSystem) < 0) { + throw RangeError("Invalid numberingSystems: ".concat(numberingSystem)); + } + opt.nu = numberingSystem; + var r = (0, intl_localematcher_1.ResolveLocale)( + availableLocales, + requestedLocales, + opt, + // [[RelevantExtensionKeys]] slot, which is a constant + ["nu"], + localeData, + getDefaultLocale + ); + var dataLocaleData = localeData[r.dataLocale]; + (0, utils_1.invariant)(!!dataLocaleData, "Missing locale data for ".concat(r.dataLocale)); + var internalSlots = getInternalSlots(nf); + internalSlots.locale = r.locale; + internalSlots.dataLocale = r.dataLocale; + internalSlots.numberingSystem = r.nu; + internalSlots.dataLocaleData = dataLocaleData; + (0, SetNumberFormatUnitOptions_1.SetNumberFormatUnitOptions)(nf, options, { getInternalSlots }); + var style = internalSlots.style; + var mnfdDefault; + var mxfdDefault; + if (style === "currency") { + var currency = internalSlots.currency; + var cDigits = (0, CurrencyDigits_1.CurrencyDigits)(currency, { currencyDigitsData }); + mnfdDefault = cDigits; + mxfdDefault = cDigits; + } else { + mnfdDefault = 0; + mxfdDefault = style === "percent" ? 0 : 3; + } + var notation = (0, GetOption_1.GetOption)(options, "notation", "string", ["standard", "scientific", "engineering", "compact"], "standard"); + internalSlots.notation = notation; + (0, SetNumberFormatDigitOptions_1.SetNumberFormatDigitOptions)(internalSlots, options, mnfdDefault, mxfdDefault, notation); + var roundingIncrement = (0, GetNumberOption_1.GetNumberOption)(options, "roundingIncrement", 1, 5e3, 1); + if (VALID_ROUND_INCREMENT_VALUES.indexOf(roundingIncrement) === -1) { + throw new RangeError("Invalid rounding increment value: ".concat(roundingIncrement, ".\nValid values are ").concat(VALID_ROUND_INCREMENT_VALUES, ".")); + } + if (roundingIncrement !== 1 && internalSlots.roundingType !== "fractionDigits") { + throw new TypeError("For roundingIncrement > 1 only fractionDigits is a valid roundingType"); + } + if (roundingIncrement !== 1 && internalSlots.maximumFractionDigits !== internalSlots.minimumFractionDigits) { + throw new RangeError("With roundingIncrement > 1, maximumFractionDigits and minimumFractionDigits must be equal."); + } + internalSlots.roundingIncrement = roundingIncrement; + var trailingZeroDisplay = (0, GetOption_1.GetOption)(options, "trailingZeroDisplay", "string", ["auto", "stripIfInteger"], "auto"); + internalSlots.trailingZeroDisplay = trailingZeroDisplay; + var compactDisplay = (0, GetOption_1.GetOption)(options, "compactDisplay", "string", ["short", "long"], "short"); + var defaultUseGrouping = "auto"; + if (notation === "compact") { + internalSlots.compactDisplay = compactDisplay; + defaultUseGrouping = "min2"; + } + internalSlots.useGrouping = (0, GetStringOrBooleanOption_1.GetStringOrBooleanOption)(options, "useGrouping", ["min2", "auto", "always"], "always", false, defaultUseGrouping); + internalSlots.signDisplay = (0, GetOption_1.GetOption)(options, "signDisplay", "string", ["auto", "never", "always", "exceptZero", "negative"], "auto"); + internalSlots.roundingMode = (0, GetOption_1.GetOption)(options, "roundingMode", "string", [ + "ceil", + "floor", + "expand", + "trunc", + "halfCeil", + "halfFloor", + "halfExpand", + "halfTrunc", + "halfEven" + ], "halfExpand"); + return nf; + } + exports.InitializeNumberFormat = InitializeNumberFormat; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberRangePattern.js + var require_PartitionNumberRangePattern = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberRangePattern.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.PartitionNumberRangePattern = void 0; + var _262_1 = require__(); + var PartitionNumberPattern_1 = require_PartitionNumberPattern(); + var CollapseNumberRange_1 = require_CollapseNumberRange(); + var FormatApproximately_1 = require_FormatApproximately(); + function PartitionNumberRangePattern(numberFormat, x, y, _a) { + var getInternalSlots = _a.getInternalSlots; + var internalSlots = getInternalSlots(numberFormat); + if (isNaN(x) || isNaN(y)) { + throw new RangeError("Input must be a number"); + } + if (isFinite(x)) { + if (isFinite(y) && y < x) { + throw new RangeError("Y input must be bigger than X"); + } else if (y == Number.NEGATIVE_INFINITY) { + throw new RangeError("Y input must not be NegativeInfinity"); + } else if ((0, _262_1.SameValue)(y, -0) && x >= 0) { + throw new RangeError("Y input must be bigger than X"); + } + } else if (x == Number.POSITIVE_INFINITY) { + if (isFinite(y) || y == Number.NEGATIVE_INFINITY || (0, _262_1.SameValue)(y, -0)) { + throw new RangeError("Y input must be bigger than X"); + } + } else if ((0, _262_1.SameValue)(x, -0)) { + if (isFinite(y) && y < 0) { + throw new RangeError("Y input must be bigger than X"); + } else if (y == Number.NEGATIVE_INFINITY) { + throw new RangeError("Y input must be bigger than X"); + } + } + var result = []; + var xResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, x, { getInternalSlots }); + var yResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, y, { getInternalSlots }); + if (xResult === yResult) { + return (0, FormatApproximately_1.FormatApproximately)(numberFormat, xResult, { getInternalSlots }); + } + for (var _i = 0, xResult_1 = xResult; _i < xResult_1.length; _i++) { + var r = xResult_1[_i]; + r.source = "startRange"; + } + result = result.concat(xResult); + var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]; + var rangeSeparator = symbols.timeSeparator; + result.push({ type: "literal", value: rangeSeparator, source: "shared" }); + for (var _b = 0, yResult_1 = yResult; _b < yResult_1.length; _b++) { + var r = yResult_1[_b]; + r.source = "endRange"; + } + result = result.concat(yResult); + return (0, CollapseNumberRange_1.CollapseNumberRange)(result); + } + exports.PartitionNumberRangePattern = PartitionNumberRangePattern; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/PartitionPattern.js + var require_PartitionPattern = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/PartitionPattern.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.PartitionPattern = void 0; + var utils_1 = require_utils(); + function PartitionPattern(pattern) { + var result = []; + var beginIndex = pattern.indexOf("{"); + var endIndex = 0; + var nextIndex = 0; + var length = pattern.length; + while (beginIndex < pattern.length && beginIndex > -1) { + endIndex = pattern.indexOf("}", beginIndex); + (0, utils_1.invariant)(endIndex > beginIndex, "Invalid pattern ".concat(pattern)); + if (beginIndex > nextIndex) { + result.push({ + type: "literal", + value: pattern.substring(nextIndex, beginIndex) + }); + } + result.push({ + type: pattern.substring(beginIndex + 1, endIndex), + value: void 0 + }); + nextIndex = endIndex + 1; + beginIndex = pattern.indexOf("{", nextIndex); + } + if (nextIndex < length) { + result.push({ + type: "literal", + value: pattern.substring(nextIndex, length) + }); + } + return result; + } + exports.PartitionPattern = PartitionPattern; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/SupportedLocales.js + var require_SupportedLocales = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/SupportedLocales.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.SupportedLocales = void 0; + var _262_1 = require__(); + var GetOption_1 = require_GetOption(); + var intl_localematcher_1 = require_intl_localematcher(); + function SupportedLocales(availableLocales, requestedLocales, options) { + var matcher = "best fit"; + if (options !== void 0) { + options = (0, _262_1.ToObject)(options); + matcher = (0, GetOption_1.GetOption)(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); + } + if (matcher === "best fit") { + return (0, intl_localematcher_1.LookupSupportedLocales)(availableLocales, requestedLocales); + } + return (0, intl_localematcher_1.LookupSupportedLocales)(availableLocales, requestedLocales); + } + exports.SupportedLocales = SupportedLocales; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/data.js + var require_data = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/data.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.isMissingLocaleDataError = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var MissingLocaleDataError = ( + /** @class */ + function(_super) { + tslib_1.__extends(MissingLocaleDataError2, _super); + function MissingLocaleDataError2() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = "MISSING_LOCALE_DATA"; + return _this; + } + return MissingLocaleDataError2; + }(Error) + ); + function isMissingLocaleDataError(e) { + return e.type === "MISSING_LOCALE_DATA"; + } + exports.isMissingLocaleDataError = isMissingLocaleDataError; + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/relative-time.js + var require_relative_time = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/relative-time.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/date-time.js + var require_date_time = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/date-time.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.RangePatternType = void 0; + var RangePatternType; + (function(RangePatternType2) { + RangePatternType2["startRange"] = "startRange"; + RangePatternType2["shared"] = "shared"; + RangePatternType2["endRange"] = "endRange"; + })(RangePatternType = exports.RangePatternType || (exports.RangePatternType = {})); + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/list.js + var require_list = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/list.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/plural-rules.js + var require_plural_rules = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/plural-rules.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/number.js + var require_number = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/number.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/displaynames.js + var require_displaynames = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/displaynames.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } + }); + + // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/index.js + var require_ecma402_abstract = __commonJS({ + "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/index.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.invariant = exports.isMissingLocaleDataError = exports.defineProperty = exports.getMagnitude = exports.setMultiInternalSlots = exports.setInternalSlot = exports.isLiteralPart = exports.getMultiInternalSlots = exports.getInternalSlot = exports._formatToParts = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + tslib_1.__exportStar(require_CanonicalizeLocaleList(), exports); + tslib_1.__exportStar(require_CanonicalizeTimeZoneName(), exports); + tslib_1.__exportStar(require_CoerceOptionsToObject(), exports); + tslib_1.__exportStar(require_GetNumberOption(), exports); + tslib_1.__exportStar(require_GetOption(), exports); + tslib_1.__exportStar(require_GetOptionsObject(), exports); + tslib_1.__exportStar(require_GetStringOrBooleanOption(), exports); + tslib_1.__exportStar(require_IsSanctionedSimpleUnitIdentifier(), exports); + tslib_1.__exportStar(require_IsValidTimeZoneName(), exports); + tslib_1.__exportStar(require_IsWellFormedCurrencyCode(), exports); + tslib_1.__exportStar(require_IsWellFormedUnitIdentifier(), exports); + tslib_1.__exportStar(require_ApplyUnsignedRoundingMode(), exports); + tslib_1.__exportStar(require_CollapseNumberRange(), exports); + tslib_1.__exportStar(require_ComputeExponent(), exports); + tslib_1.__exportStar(require_ComputeExponentForMagnitude(), exports); + tslib_1.__exportStar(require_CurrencyDigits(), exports); + tslib_1.__exportStar(require_FormatApproximately(), exports); + tslib_1.__exportStar(require_FormatNumericToParts(), exports); + tslib_1.__exportStar(require_FormatNumericToString(), exports); + tslib_1.__exportStar(require_GetUnsignedRoundingMode(), exports); + tslib_1.__exportStar(require_InitializeNumberFormat(), exports); + tslib_1.__exportStar(require_PartitionNumberPattern(), exports); + tslib_1.__exportStar(require_PartitionNumberRangePattern(), exports); + tslib_1.__exportStar(require_SetNumberFormatDigitOptions(), exports); + tslib_1.__exportStar(require_SetNumberFormatUnitOptions(), exports); + tslib_1.__exportStar(require_ToRawFixed(), exports); + tslib_1.__exportStar(require_ToRawPrecision(), exports); + var format_to_parts_1 = require_format_to_parts(); + Object.defineProperty(exports, "_formatToParts", { enumerable: true, get: function() { + return tslib_1.__importDefault(format_to_parts_1).default; + } }); + tslib_1.__exportStar(require_PartitionPattern(), exports); + tslib_1.__exportStar(require_SupportedLocales(), exports); + var utils_1 = require_utils(); + Object.defineProperty(exports, "getInternalSlot", { enumerable: true, get: function() { + return utils_1.getInternalSlot; + } }); + Object.defineProperty(exports, "getMultiInternalSlots", { enumerable: true, get: function() { + return utils_1.getMultiInternalSlots; + } }); + Object.defineProperty(exports, "isLiteralPart", { enumerable: true, get: function() { + return utils_1.isLiteralPart; + } }); + Object.defineProperty(exports, "setInternalSlot", { enumerable: true, get: function() { + return utils_1.setInternalSlot; + } }); + Object.defineProperty(exports, "setMultiInternalSlots", { enumerable: true, get: function() { + return utils_1.setMultiInternalSlots; + } }); + Object.defineProperty(exports, "getMagnitude", { enumerable: true, get: function() { + return utils_1.getMagnitude; + } }); + Object.defineProperty(exports, "defineProperty", { enumerable: true, get: function() { + return utils_1.defineProperty; + } }); + var data_1 = require_data(); + Object.defineProperty(exports, "isMissingLocaleDataError", { enumerable: true, get: function() { + return data_1.isMissingLocaleDataError; + } }); + tslib_1.__exportStar(require_relative_time(), exports); + tslib_1.__exportStar(require_date_time(), exports); + tslib_1.__exportStar(require_list(), exports); + tslib_1.__exportStar(require_plural_rules(), exports); + tslib_1.__exportStar(require_number(), exports); + tslib_1.__exportStar(require_displaynames(), exports); + var utils_2 = require_utils(); + Object.defineProperty(exports, "invariant", { enumerable: true, get: function() { + return utils_2.invariant; + } }); + tslib_1.__exportStar(require__(), exports); + } + }); + + // node_modules/@formatjs/intl-getcanonicallocales/src/parser.js + var require_parser = __commonJS({ + "node_modules/@formatjs/intl-getcanonicallocales/src/parser.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.parseUnicodeLocaleId = exports.parseUnicodeLanguageId = exports.isUnicodeVariantSubtag = exports.isUnicodeScriptSubtag = exports.isUnicodeRegionSubtag = exports.isStructurallyValidLanguageTag = exports.isUnicodeLanguageSubtag = exports.SEPARATOR = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var ALPHANUM_1_8 = /^[a-z0-9]{1,8}$/i; + var ALPHANUM_2_8 = /^[a-z0-9]{2,8}$/i; + var ALPHANUM_3_8 = /^[a-z0-9]{3,8}$/i; + var KEY_REGEX = /^[a-z0-9][a-z]$/i; + var TYPE_REGEX = /^[a-z0-9]{3,8}$/i; + var ALPHA_4 = /^[a-z]{4}$/i; + var OTHER_EXTENSION_TYPE = /^[0-9a-svwyz]$/i; + var UNICODE_REGION_SUBTAG_REGEX = /^([a-z]{2}|[0-9]{3})$/i; + var UNICODE_VARIANT_SUBTAG_REGEX = /^([a-z0-9]{5,8}|[0-9][a-z0-9]{3})$/i; + var UNICODE_LANGUAGE_SUBTAG_REGEX = /^([a-z]{2,3}|[a-z]{5,8})$/i; + var TKEY_REGEX = /^[a-z][0-9]$/i; + exports.SEPARATOR = "-"; + function isUnicodeLanguageSubtag(lang) { + return UNICODE_LANGUAGE_SUBTAG_REGEX.test(lang); + } + exports.isUnicodeLanguageSubtag = isUnicodeLanguageSubtag; + function isStructurallyValidLanguageTag(tag) { + try { + parseUnicodeLanguageId(tag.split(exports.SEPARATOR)); + } catch (e) { + return false; + } + return true; + } + exports.isStructurallyValidLanguageTag = isStructurallyValidLanguageTag; + function isUnicodeRegionSubtag(region) { + return UNICODE_REGION_SUBTAG_REGEX.test(region); + } + exports.isUnicodeRegionSubtag = isUnicodeRegionSubtag; + function isUnicodeScriptSubtag(script) { + return ALPHA_4.test(script); + } + exports.isUnicodeScriptSubtag = isUnicodeScriptSubtag; + function isUnicodeVariantSubtag(variant) { + return UNICODE_VARIANT_SUBTAG_REGEX.test(variant); + } + exports.isUnicodeVariantSubtag = isUnicodeVariantSubtag; + function parseUnicodeLanguageId(chunks) { + if (typeof chunks === "string") { + chunks = chunks.split(exports.SEPARATOR); + } + var lang = chunks.shift(); + if (!lang) { + throw new RangeError("Missing unicode_language_subtag"); + } + if (lang === "root") { + return { lang: "root", variants: [] }; + } + if (!isUnicodeLanguageSubtag(lang)) { + throw new RangeError("Malformed unicode_language_subtag"); + } + var script; + if (chunks.length && isUnicodeScriptSubtag(chunks[0])) { + script = chunks.shift(); + } + var region; + if (chunks.length && isUnicodeRegionSubtag(chunks[0])) { + region = chunks.shift(); + } + var variants = {}; + while (chunks.length && isUnicodeVariantSubtag(chunks[0])) { + var variant = chunks.shift(); + if (variant in variants) { + throw new RangeError('Duplicate variant "'.concat(variant, '"')); + } + variants[variant] = 1; + } + return { + lang, + script, + region, + variants: Object.keys(variants) + }; + } + exports.parseUnicodeLanguageId = parseUnicodeLanguageId; + function parseUnicodeExtension(chunks) { + var keywords = []; + var keyword; + while (chunks.length && (keyword = parseKeyword(chunks))) { + keywords.push(keyword); + } + if (keywords.length) { + return { + type: "u", + keywords, + attributes: [] + }; + } + var attributes = []; + while (chunks.length && ALPHANUM_3_8.test(chunks[0])) { + attributes.push(chunks.shift()); + } + while (chunks.length && (keyword = parseKeyword(chunks))) { + keywords.push(keyword); + } + if (keywords.length || attributes.length) { + return { + type: "u", + attributes, + keywords + }; + } + throw new RangeError("Malformed unicode_extension"); + } + function parseKeyword(chunks) { + var key; + if (!KEY_REGEX.test(chunks[0])) { + return; + } + key = chunks.shift(); + var type = []; + while (chunks.length && TYPE_REGEX.test(chunks[0])) { + type.push(chunks.shift()); + } + var value = ""; + if (type.length) { + value = type.join(exports.SEPARATOR); + } + return [key, value]; + } + function parseTransformedExtension(chunks) { + var lang; + try { + lang = parseUnicodeLanguageId(chunks); + } catch (e) { + } + var fields = []; + while (chunks.length && TKEY_REGEX.test(chunks[0])) { + var key = chunks.shift(); + var value = []; + while (chunks.length && ALPHANUM_3_8.test(chunks[0])) { + value.push(chunks.shift()); + } + if (!value.length) { + throw new RangeError('Missing tvalue for tkey "'.concat(key, '"')); + } + fields.push([key, value.join(exports.SEPARATOR)]); + } + if (fields.length) { + return { + type: "t", + fields, + lang + }; + } + throw new RangeError("Malformed transformed_extension"); + } + function parsePuExtension(chunks) { + var exts = []; + while (chunks.length && ALPHANUM_1_8.test(chunks[0])) { + exts.push(chunks.shift()); + } + if (exts.length) { + return { + type: "x", + value: exts.join(exports.SEPARATOR) + }; + } + throw new RangeError("Malformed private_use_extension"); + } + function parseOtherExtensionValue(chunks) { + var exts = []; + while (chunks.length && ALPHANUM_2_8.test(chunks[0])) { + exts.push(chunks.shift()); + } + if (exts.length) { + return exts.join(exports.SEPARATOR); + } + return ""; + } + function parseExtensions(chunks) { + if (!chunks.length) { + return { extensions: [] }; + } + var extensions = []; + var unicodeExtension; + var transformedExtension; + var puExtension; + var otherExtensionMap = {}; + do { + var type = chunks.shift(); + switch (type) { + case "u": + case "U": + if (unicodeExtension) { + throw new RangeError("There can only be 1 -u- extension"); + } + unicodeExtension = parseUnicodeExtension(chunks); + extensions.push(unicodeExtension); + break; + case "t": + case "T": + if (transformedExtension) { + throw new RangeError("There can only be 1 -t- extension"); + } + transformedExtension = parseTransformedExtension(chunks); + extensions.push(transformedExtension); + break; + case "x": + case "X": + if (puExtension) { + throw new RangeError("There can only be 1 -x- extension"); + } + puExtension = parsePuExtension(chunks); + extensions.push(puExtension); + break; + default: + if (!OTHER_EXTENSION_TYPE.test(type)) { + throw new RangeError("Malformed extension type"); + } + if (type in otherExtensionMap) { + throw new RangeError("There can only be 1 -".concat(type, "- extension")); + } + var extension = { + type, + value: parseOtherExtensionValue(chunks) + }; + otherExtensionMap[extension.type] = extension; + extensions.push(extension); + break; + } + } while (chunks.length); + return { extensions }; + } + function parseUnicodeLocaleId(locale) { + var chunks = locale.split(exports.SEPARATOR); + var lang = parseUnicodeLanguageId(chunks); + return tslib_1.__assign({ lang }, parseExtensions(chunks)); + } + exports.parseUnicodeLocaleId = parseUnicodeLocaleId; + } + }); + + // node_modules/@formatjs/intl-getcanonicallocales/src/emitter.js + var require_emitter = __commonJS({ + "node_modules/@formatjs/intl-getcanonicallocales/src/emitter.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.emitUnicodeLocaleId = exports.emitUnicodeLanguageId = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + function emitUnicodeLanguageId(lang) { + if (!lang) { + return ""; + } + return tslib_1.__spreadArray([lang.lang, lang.script, lang.region], lang.variants || [], true).filter(Boolean).join("-"); + } + exports.emitUnicodeLanguageId = emitUnicodeLanguageId; + function emitUnicodeLocaleId(_a) { + var lang = _a.lang, extensions = _a.extensions; + var chunks = [emitUnicodeLanguageId(lang)]; + for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) { + var ext = extensions_1[_i]; + chunks.push(ext.type); + switch (ext.type) { + case "u": + chunks.push.apply(chunks, tslib_1.__spreadArray(tslib_1.__spreadArray([], ext.attributes, false), ext.keywords.reduce(function(all, kv) { + return all.concat(kv); + }, []), false)); + break; + case "t": + chunks.push.apply(chunks, tslib_1.__spreadArray([emitUnicodeLanguageId(ext.lang)], ext.fields.reduce(function(all, kv) { + return all.concat(kv); + }, []), false)); + break; + default: + chunks.push(ext.value); + break; + } + } + return chunks.filter(Boolean).join("-"); + } + exports.emitUnicodeLocaleId = emitUnicodeLocaleId; + } + }); + + // node_modules/@formatjs/intl-getcanonicallocales/src/aliases.generated.js + var require_aliases_generated = __commonJS({ + "node_modules/@formatjs/intl-getcanonicallocales/src/aliases.generated.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.variantAlias = exports.scriptAlias = exports.territoryAlias = exports.languageAlias = void 0; + exports.languageAlias = { + "aa-saaho": "ssy", + "aam": "aas", + "aar": "aa", + "abk": "ab", + "adp": "dz", + "afr": "af", + "agp": "apf", + "ais": "ami", + "aju": "jrb", + "aka": "ak", + "alb": "sq", + "als": "sq", + "amh": "am", + "ara": "ar", + "arb": "ar", + "arg": "an", + "arm": "hy", + "art-lojban": "jbo", + "asd": "snz", + "asm": "as", + "aue": "ktz", + "ava": "av", + "ave": "ae", + "aym": "ay", + "ayr": "ay", + "ayx": "nun", + "aze": "az", + "azj": "az", + "bak": "ba", + "bam": "bm", + "baq": "eu", + "baz": "nvo", + "bcc": "bal", + "bcl": "bik", + "bel": "be", + "ben": "bn", + "bgm": "bcg", + "bh": "bho", + "bhk": "fbl", + "bic": "bir", + "bih": "bho", + "bis": "bi", + "bjd": "drl", + "bjq": "bzc", + "bkb": "ebk", + "blg": "iba", + "bod": "bo", + "bos": "bs", + "bre": "br", + "btb": "beb", + "bul": "bg", + "bur": "my", + "bxk": "luy", + "bxr": "bua", + "cat": "ca", + "ccq": "rki", + "cel-gaulish": "xtg", + "ces": "cs", + "cha": "ch", + "che": "ce", + "chi": "zh", + "chu": "cu", + "chv": "cv", + "cjr": "mom", + "cka": "cmr", + "cld": "syr", + "cmk": "xch", + "cmn": "zh", + "cnr": "sr-ME", + "cor": "kw", + "cos": "co", + "coy": "pij", + "cqu": "quh", + "cre": "cr", + "cwd": "cr", + "cym": "cy", + "cze": "cs", + "daf": "dnj", + "dan": "da", + "dap": "njz", + "deu": "de", + "dgo": "doi", + "dhd": "mwr", + "dik": "din", + "diq": "zza", + "dit": "dif", + "div": "dv", + "djl": "dze", + "dkl": "aqd", + "drh": "mn", + "drr": "kzk", + "drw": "fa-AF", + "dud": "uth", + "duj": "dwu", + "dut": "nl", + "dwl": "dbt", + "dzo": "dz", + "ekk": "et", + "ell": "el", + "elp": "amq", + "emk": "man", + "en-GB-oed": "en-GB-oxendict", + "eng": "en", + "epo": "eo", + "esk": "ik", + "est": "et", + "eus": "eu", + "ewe": "ee", + "fao": "fo", + "fas": "fa", + "fat": "ak", + "fij": "fj", + "fin": "fi", + "fra": "fr", + "fre": "fr", + "fry": "fy", + "fuc": "ff", + "ful": "ff", + "gav": "dev", + "gaz": "om", + "gbc": "wny", + "gbo": "grb", + "geo": "ka", + "ger": "de", + "gfx": "vaj", + "ggn": "gvr", + "ggo": "esg", + "ggr": "gtu", + "gio": "aou", + "gla": "gd", + "gle": "ga", + "glg": "gl", + "gli": "kzk", + "glv": "gv", + "gno": "gon", + "gre": "el", + "grn": "gn", + "gti": "nyc", + "gug": "gn", + "guj": "gu", + "guv": "duz", + "gya": "gba", + "hat": "ht", + "hau": "ha", + "hbs": "sr-Latn", + "hdn": "hai", + "hea": "hmn", + "heb": "he", + "her": "hz", + "him": "srx", + "hin": "hi", + "hmo": "ho", + "hrr": "jal", + "hrv": "hr", + "hun": "hu", + "hy-arevmda": "hyw", + "hye": "hy", + "i-ami": "ami", + "i-bnn": "bnn", + "i-default": "en-x-i-default", + "i-enochian": "und-x-i-enochian", + "i-hak": "hak", + "i-klingon": "tlh", + "i-lux": "lb", + "i-mingo": "see-x-i-mingo", + "i-navajo": "nv", + "i-pwn": "pwn", + "i-tao": "tao", + "i-tay": "tay", + "i-tsu": "tsu", + "ibi": "opa", + "ibo": "ig", + "ice": "is", + "ido": "io", + "iii": "ii", + "ike": "iu", + "iku": "iu", + "ile": "ie", + "ill": "ilm", + "ilw": "gal", + "in": "id", + "ina": "ia", + "ind": "id", + "ipk": "ik", + "isl": "is", + "ita": "it", + "iw": "he", + "izi": "eza", + "jar": "jgk", + "jav": "jv", + "jeg": "oyb", + "ji": "yi", + "jpn": "ja", + "jw": "jv", + "kal": "kl", + "kan": "kn", + "kas": "ks", + "kat": "ka", + "kau": "kr", + "kaz": "kk", + "kdv": "zkd", + "kgc": "tdf", + "kgd": "ncq", + "kgh": "kml", + "khk": "mn", + "khm": "km", + "kik": "ki", + "kin": "rw", + "kir": "ky", + "kmr": "ku", + "knc": "kr", + "kng": "kg", + "knn": "kok", + "koj": "kwv", + "kom": "kv", + "kon": "kg", + "kor": "ko", + "kpp": "jkm", + "kpv": "kv", + "krm": "bmf", + "ktr": "dtp", + "kua": "kj", + "kur": "ku", + "kvs": "gdj", + "kwq": "yam", + "kxe": "tvd", + "kxl": "kru", + "kzh": "dgl", + "kzj": "dtp", + "kzt": "dtp", + "lao": "lo", + "lat": "la", + "lav": "lv", + "lbk": "bnc", + "leg": "enl", + "lii": "raq", + "lim": "li", + "lin": "ln", + "lit": "lt", + "llo": "ngt", + "lmm": "rmx", + "ltz": "lb", + "lub": "lu", + "lug": "lg", + "lvs": "lv", + "mac": "mk", + "mah": "mh", + "mal": "ml", + "mao": "mi", + "mar": "mr", + "may": "ms", + "meg": "cir", + "mgx": "jbk", + "mhr": "chm", + "mkd": "mk", + "mlg": "mg", + "mlt": "mt", + "mnk": "man", + "mnt": "wnn", + "mo": "ro", + "mof": "xnt", + "mol": "ro", + "mon": "mn", + "mri": "mi", + "msa": "ms", + "mst": "mry", + "mup": "raj", + "mwd": "dmw", + "mwj": "vaj", + "mya": "my", + "myd": "aog", + "myt": "mry", + "nad": "xny", + "nau": "na", + "nav": "nv", + "nbf": "nru", + "nbl": "nr", + "nbx": "ekc", + "ncp": "kdz", + "nde": "nd", + "ndo": "ng", + "nep": "ne", + "nld": "nl", + "nln": "azd", + "nlr": "nrk", + "nno": "nn", + "nns": "nbr", + "nnx": "ngv", + "no-bok": "nb", + "no-bokmal": "nb", + "no-nyn": "nn", + "no-nynorsk": "nn", + "nob": "nb", + "noo": "dtd", + "nor": "no", + "npi": "ne", + "nts": "pij", + "nxu": "bpp", + "nya": "ny", + "oci": "oc", + "ojg": "oj", + "oji": "oj", + "ori": "or", + "orm": "om", + "ory": "or", + "oss": "os", + "oun": "vaj", + "pan": "pa", + "pat": "kxr", + "pbu": "ps", + "pcr": "adx", + "per": "fa", + "pes": "fa", + "pli": "pi", + "plt": "mg", + "pmc": "huw", + "pmu": "phr", + "pnb": "lah", + "pol": "pl", + "por": "pt", + "ppa": "bfy", + "ppr": "lcq", + "prs": "fa-AF", + "pry": "prt", + "pus": "ps", + "puz": "pub", + "que": "qu", + "quz": "qu", + "rmr": "emx", + "rmy": "rom", + "roh": "rm", + "ron": "ro", + "rum": "ro", + "run": "rn", + "rus": "ru", + "sag": "sg", + "san": "sa", + "sap": "aqt", + "sca": "hle", + "scc": "sr", + "scr": "hr", + "sgl": "isk", + "sgn-BE-FR": "sfb", + "sgn-BE-NL": "vgt", + "sgn-BR": "bzs", + "sgn-CH-DE": "sgg", + "sgn-CO": "csn", + "sgn-DE": "gsg", + "sgn-DK": "dsl", + "sgn-ES": "ssp", + "sgn-FR": "fsl", + "sgn-GB": "bfi", + "sgn-GR": "gss", + "sgn-IE": "isg", + "sgn-IT": "ise", + "sgn-JP": "jsl", + "sgn-MX": "mfs", + "sgn-NI": "ncs", + "sgn-NL": "dse", + "sgn-NO": "nsi", + "sgn-PT": "psr", + "sgn-SE": "swl", + "sgn-US": "ase", + "sgn-ZA": "sfs", + "sh": "sr-Latn", + "sin": "si", + "skk": "oyb", + "slk": "sk", + "slo": "sk", + "slv": "sl", + "sme": "se", + "smo": "sm", + "sna": "sn", + "snd": "sd", + "som": "so", + "sot": "st", + "spa": "es", + "spy": "kln", + "sqi": "sq", + "src": "sc", + "srd": "sc", + "srp": "sr", + "ssw": "ss", + "sul": "sgd", + "sum": "ulw", + "sun": "su", + "swa": "sw", + "swc": "sw-CD", + "swe": "sv", + "swh": "sw", + "tah": "ty", + "tam": "ta", + "tat": "tt", + "tdu": "dtp", + "tel": "te", + "tgg": "bjp", + "tgk": "tg", + "tgl": "fil", + "tha": "th", + "thc": "tpo", + "thw": "ola", + "thx": "oyb", + "tib": "bo", + "tid": "itd", + "tie": "ras", + "tir": "ti", + "tkk": "twm", + "tl": "fil", + "tlw": "weo", + "tmp": "tyj", + "tne": "kak", + "tnf": "fa-AF", + "ton": "to", + "tsf": "taj", + "tsn": "tn", + "tso": "ts", + "ttq": "tmh", + "tuk": "tk", + "tur": "tr", + "tw": "ak", + "twi": "ak", + "uig": "ug", + "ukr": "uk", + "umu": "del", + "und-aaland": "und-AX", + "und-arevela": "und", + "und-arevmda": "und", + "und-bokmal": "und", + "und-hakka": "und", + "und-hepburn-heploc": "und-alalc97", + "und-lojban": "und", + "und-nynorsk": "und", + "und-saaho": "und", + "und-xiang": "und", + "unp": "wro", + "uok": "ema", + "urd": "ur", + "uzb": "uz", + "uzn": "uz", + "ven": "ve", + "vie": "vi", + "vol": "vo", + "wel": "cy", + "wgw": "wgb", + "wit": "nol", + "wiw": "nwo", + "wln": "wa", + "wol": "wo", + "xba": "cax", + "xho": "xh", + "xia": "acn", + "xkh": "waw", + "xpe": "kpe", + "xrq": "dmw", + "xsj": "suj", + "xsl": "den", + "ybd": "rki", + "ydd": "yi", + "yen": "ynq", + "yid": "yi", + "yiy": "yrm", + "yma": "lrr", + "ymt": "mtm", + "yor": "yo", + "yos": "zom", + "yuu": "yug", + "zai": "zap", + "zh-cmn": "zh", + "zh-cmn-Hans": "zh-Hans", + "zh-cmn-Hant": "zh-Hant", + "zh-gan": "gan", + "zh-guoyu": "zh", + "zh-hakka": "hak", + "zh-min": "nan-x-zh-min", + "zh-min-nan": "nan", + "zh-wuu": "wuu", + "zh-xiang": "hsn", + "zh-yue": "yue", + "zha": "za", + "zho": "zh", + "zir": "scv", + "zsm": "ms", + "zul": "zu", + "zyb": "za" + }; + exports.territoryAlias = { + "100": "BG", + "104": "MM", + "108": "BI", + "112": "BY", + "116": "KH", + "120": "CM", + "124": "CA", + "132": "CV", + "136": "KY", + "140": "CF", + "144": "LK", + "148": "TD", + "152": "CL", + "156": "CN", + "158": "TW", + "162": "CX", + "166": "CC", + "170": "CO", + "172": "RU AM AZ BY GE KG KZ MD TJ TM UA UZ", + "174": "KM", + "175": "YT", + "178": "CG", + "180": "CD", + "184": "CK", + "188": "CR", + "191": "HR", + "192": "CU", + "196": "CY", + "200": "CZ SK", + "203": "CZ", + "204": "BJ", + "208": "DK", + "212": "DM", + "214": "DO", + "218": "EC", + "222": "SV", + "226": "GQ", + "230": "ET", + "231": "ET", + "232": "ER", + "233": "EE", + "234": "FO", + "238": "FK", + "239": "GS", + "242": "FJ", + "246": "FI", + "248": "AX", + "249": "FR", + "250": "FR", + "254": "GF", + "258": "PF", + "260": "TF", + "262": "DJ", + "266": "GA", + "268": "GE", + "270": "GM", + "275": "PS", + "276": "DE", + "278": "DE", + "280": "DE", + "288": "GH", + "292": "GI", + "296": "KI", + "300": "GR", + "304": "GL", + "308": "GD", + "312": "GP", + "316": "GU", + "320": "GT", + "324": "GN", + "328": "GY", + "332": "HT", + "334": "HM", + "336": "VA", + "340": "HN", + "344": "HK", + "348": "HU", + "352": "IS", + "356": "IN", + "360": "ID", + "364": "IR", + "368": "IQ", + "372": "IE", + "376": "IL", + "380": "IT", + "384": "CI", + "388": "JM", + "392": "JP", + "398": "KZ", + "400": "JO", + "404": "KE", + "408": "KP", + "410": "KR", + "414": "KW", + "417": "KG", + "418": "LA", + "422": "LB", + "426": "LS", + "428": "LV", + "430": "LR", + "434": "LY", + "438": "LI", + "440": "LT", + "442": "LU", + "446": "MO", + "450": "MG", + "454": "MW", + "458": "MY", + "462": "MV", + "466": "ML", + "470": "MT", + "474": "MQ", + "478": "MR", + "480": "MU", + "484": "MX", + "492": "MC", + "496": "MN", + "498": "MD", + "499": "ME", + "500": "MS", + "504": "MA", + "508": "MZ", + "512": "OM", + "516": "NA", + "520": "NR", + "524": "NP", + "528": "NL", + "530": "CW SX BQ", + "531": "CW", + "532": "CW SX BQ", + "533": "AW", + "534": "SX", + "535": "BQ", + "536": "SA IQ", + "540": "NC", + "548": "VU", + "554": "NZ", + "558": "NI", + "562": "NE", + "566": "NG", + "570": "NU", + "574": "NF", + "578": "NO", + "580": "MP", + "581": "UM", + "582": "FM MH MP PW", + "583": "FM", + "584": "MH", + "585": "PW", + "586": "PK", + "591": "PA", + "598": "PG", + "600": "PY", + "604": "PE", + "608": "PH", + "612": "PN", + "616": "PL", + "620": "PT", + "624": "GW", + "626": "TL", + "630": "PR", + "634": "QA", + "638": "RE", + "642": "RO", + "643": "RU", + "646": "RW", + "652": "BL", + "654": "SH", + "659": "KN", + "660": "AI", + "662": "LC", + "663": "MF", + "666": "PM", + "670": "VC", + "674": "SM", + "678": "ST", + "682": "SA", + "686": "SN", + "688": "RS", + "690": "SC", + "694": "SL", + "702": "SG", + "703": "SK", + "704": "VN", + "705": "SI", + "706": "SO", + "710": "ZA", + "716": "ZW", + "720": "YE", + "724": "ES", + "728": "SS", + "729": "SD", + "732": "EH", + "736": "SD", + "740": "SR", + "744": "SJ", + "748": "SZ", + "752": "SE", + "756": "CH", + "760": "SY", + "762": "TJ", + "764": "TH", + "768": "TG", + "772": "TK", + "776": "TO", + "780": "TT", + "784": "AE", + "788": "TN", + "792": "TR", + "795": "TM", + "796": "TC", + "798": "TV", + "800": "UG", + "804": "UA", + "807": "MK", + "810": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", + "818": "EG", + "826": "GB", + "830": "JE GG", + "831": "GG", + "832": "JE", + "833": "IM", + "834": "TZ", + "840": "US", + "850": "VI", + "854": "BF", + "858": "UY", + "860": "UZ", + "862": "VE", + "876": "WF", + "882": "WS", + "886": "YE", + "887": "YE", + "890": "RS ME SI HR MK BA", + "891": "RS ME", + "894": "ZM", + "958": "AA", + "959": "QM", + "960": "QN", + "962": "QP", + "963": "QQ", + "964": "QR", + "965": "QS", + "966": "QT", + "967": "EU", + "968": "QV", + "969": "QW", + "970": "QX", + "971": "QY", + "972": "QZ", + "973": "XA", + "974": "XB", + "975": "XC", + "976": "XD", + "977": "XE", + "978": "XF", + "979": "XG", + "980": "XH", + "981": "XI", + "982": "XJ", + "983": "XK", + "984": "XL", + "985": "XM", + "986": "XN", + "987": "XO", + "988": "XP", + "989": "XQ", + "990": "XR", + "991": "XS", + "992": "XT", + "993": "XU", + "994": "XV", + "995": "XW", + "996": "XX", + "997": "XY", + "998": "XZ", + "999": "ZZ", + "004": "AF", + "008": "AL", + "010": "AQ", + "012": "DZ", + "016": "AS", + "020": "AD", + "024": "AO", + "028": "AG", + "031": "AZ", + "032": "AR", + "036": "AU", + "040": "AT", + "044": "BS", + "048": "BH", + "050": "BD", + "051": "AM", + "052": "BB", + "056": "BE", + "060": "BM", + "062": "034 143", + "064": "BT", + "068": "BO", + "070": "BA", + "072": "BW", + "074": "BV", + "076": "BR", + "084": "BZ", + "086": "IO", + "090": "SB", + "092": "VG", + "096": "BN", + "AAA": "AA", + "ABW": "AW", + "AFG": "AF", + "AGO": "AO", + "AIA": "AI", + "ALA": "AX", + "ALB": "AL", + "AN": "CW SX BQ", + "AND": "AD", + "ANT": "CW SX BQ", + "ARE": "AE", + "ARG": "AR", + "ARM": "AM", + "ASC": "AC", + "ASM": "AS", + "ATA": "AQ", + "ATF": "TF", + "ATG": "AG", + "AUS": "AU", + "AUT": "AT", + "AZE": "AZ", + "BDI": "BI", + "BEL": "BE", + "BEN": "BJ", + "BES": "BQ", + "BFA": "BF", + "BGD": "BD", + "BGR": "BG", + "BHR": "BH", + "BHS": "BS", + "BIH": "BA", + "BLM": "BL", + "BLR": "BY", + "BLZ": "BZ", + "BMU": "BM", + "BOL": "BO", + "BRA": "BR", + "BRB": "BB", + "BRN": "BN", + "BTN": "BT", + "BU": "MM", + "BUR": "MM", + "BVT": "BV", + "BWA": "BW", + "CAF": "CF", + "CAN": "CA", + "CCK": "CC", + "CHE": "CH", + "CHL": "CL", + "CHN": "CN", + "CIV": "CI", + "CMR": "CM", + "COD": "CD", + "COG": "CG", + "COK": "CK", + "COL": "CO", + "COM": "KM", + "CPT": "CP", + "CPV": "CV", + "CRI": "CR", + "CS": "RS ME", + "CT": "KI", + "CUB": "CU", + "CUW": "CW", + "CXR": "CX", + "CYM": "KY", + "CYP": "CY", + "CZE": "CZ", + "DD": "DE", + "DDR": "DE", + "DEU": "DE", + "DGA": "DG", + "DJI": "DJ", + "DMA": "DM", + "DNK": "DK", + "DOM": "DO", + "DY": "BJ", + "DZA": "DZ", + "ECU": "EC", + "EGY": "EG", + "ERI": "ER", + "ESH": "EH", + "ESP": "ES", + "EST": "EE", + "ETH": "ET", + "FIN": "FI", + "FJI": "FJ", + "FLK": "FK", + "FQ": "AQ TF", + "FRA": "FR", + "FRO": "FO", + "FSM": "FM", + "FX": "FR", + "FXX": "FR", + "GAB": "GA", + "GBR": "GB", + "GEO": "GE", + "GGY": "GG", + "GHA": "GH", + "GIB": "GI", + "GIN": "GN", + "GLP": "GP", + "GMB": "GM", + "GNB": "GW", + "GNQ": "GQ", + "GRC": "GR", + "GRD": "GD", + "GRL": "GL", + "GTM": "GT", + "GUF": "GF", + "GUM": "GU", + "GUY": "GY", + "HKG": "HK", + "HMD": "HM", + "HND": "HN", + "HRV": "HR", + "HTI": "HT", + "HUN": "HU", + "HV": "BF", + "IDN": "ID", + "IMN": "IM", + "IND": "IN", + "IOT": "IO", + "IRL": "IE", + "IRN": "IR", + "IRQ": "IQ", + "ISL": "IS", + "ISR": "IL", + "ITA": "IT", + "JAM": "JM", + "JEY": "JE", + "JOR": "JO", + "JPN": "JP", + "JT": "UM", + "KAZ": "KZ", + "KEN": "KE", + "KGZ": "KG", + "KHM": "KH", + "KIR": "KI", + "KNA": "KN", + "KOR": "KR", + "KWT": "KW", + "LAO": "LA", + "LBN": "LB", + "LBR": "LR", + "LBY": "LY", + "LCA": "LC", + "LIE": "LI", + "LKA": "LK", + "LSO": "LS", + "LTU": "LT", + "LUX": "LU", + "LVA": "LV", + "MAC": "MO", + "MAF": "MF", + "MAR": "MA", + "MCO": "MC", + "MDA": "MD", + "MDG": "MG", + "MDV": "MV", + "MEX": "MX", + "MHL": "MH", + "MI": "UM", + "MKD": "MK", + "MLI": "ML", + "MLT": "MT", + "MMR": "MM", + "MNE": "ME", + "MNG": "MN", + "MNP": "MP", + "MOZ": "MZ", + "MRT": "MR", + "MSR": "MS", + "MTQ": "MQ", + "MUS": "MU", + "MWI": "MW", + "MYS": "MY", + "MYT": "YT", + "NAM": "NA", + "NCL": "NC", + "NER": "NE", + "NFK": "NF", + "NGA": "NG", + "NH": "VU", + "NIC": "NI", + "NIU": "NU", + "NLD": "NL", + "NOR": "NO", + "NPL": "NP", + "NQ": "AQ", + "NRU": "NR", + "NT": "SA IQ", + "NTZ": "SA IQ", + "NZL": "NZ", + "OMN": "OM", + "PAK": "PK", + "PAN": "PA", + "PC": "FM MH MP PW", + "PCN": "PN", + "PER": "PE", + "PHL": "PH", + "PLW": "PW", + "PNG": "PG", + "POL": "PL", + "PRI": "PR", + "PRK": "KP", + "PRT": "PT", + "PRY": "PY", + "PSE": "PS", + "PU": "UM", + "PYF": "PF", + "PZ": "PA", + "QAT": "QA", + "QMM": "QM", + "QNN": "QN", + "QPP": "QP", + "QQQ": "QQ", + "QRR": "QR", + "QSS": "QS", + "QTT": "QT", + "QU": "EU", + "QUU": "EU", + "QVV": "QV", + "QWW": "QW", + "QXX": "QX", + "QYY": "QY", + "QZZ": "QZ", + "REU": "RE", + "RH": "ZW", + "ROU": "RO", + "RUS": "RU", + "RWA": "RW", + "SAU": "SA", + "SCG": "RS ME", + "SDN": "SD", + "SEN": "SN", + "SGP": "SG", + "SGS": "GS", + "SHN": "SH", + "SJM": "SJ", + "SLB": "SB", + "SLE": "SL", + "SLV": "SV", + "SMR": "SM", + "SOM": "SO", + "SPM": "PM", + "SRB": "RS", + "SSD": "SS", + "STP": "ST", + "SU": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", + "SUN": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", + "SUR": "SR", + "SVK": "SK", + "SVN": "SI", + "SWE": "SE", + "SWZ": "SZ", + "SXM": "SX", + "SYC": "SC", + "SYR": "SY", + "TAA": "TA", + "TCA": "TC", + "TCD": "TD", + "TGO": "TG", + "THA": "TH", + "TJK": "TJ", + "TKL": "TK", + "TKM": "TM", + "TLS": "TL", + "TMP": "TL", + "TON": "TO", + "TP": "TL", + "TTO": "TT", + "TUN": "TN", + "TUR": "TR", + "TUV": "TV", + "TWN": "TW", + "TZA": "TZ", + "UGA": "UG", + "UK": "GB", + "UKR": "UA", + "UMI": "UM", + "URY": "UY", + "USA": "US", + "UZB": "UZ", + "VAT": "VA", + "VCT": "VC", + "VD": "VN", + "VEN": "VE", + "VGB": "VG", + "VIR": "VI", + "VNM": "VN", + "VUT": "VU", + "WK": "UM", + "WLF": "WF", + "WSM": "WS", + "XAA": "XA", + "XBB": "XB", + "XCC": "XC", + "XDD": "XD", + "XEE": "XE", + "XFF": "XF", + "XGG": "XG", + "XHH": "XH", + "XII": "XI", + "XJJ": "XJ", + "XKK": "XK", + "XLL": "XL", + "XMM": "XM", + "XNN": "XN", + "XOO": "XO", + "XPP": "XP", + "XQQ": "XQ", + "XRR": "XR", + "XSS": "XS", + "XTT": "XT", + "XUU": "XU", + "XVV": "XV", + "XWW": "XW", + "XXX": "XX", + "XYY": "XY", + "XZZ": "XZ", + "YD": "YE", + "YEM": "YE", + "YMD": "YE", + "YU": "RS ME", + "YUG": "RS ME", + "ZAF": "ZA", + "ZAR": "CD", + "ZMB": "ZM", + "ZR": "CD", + "ZWE": "ZW", + "ZZZ": "ZZ" + }; + exports.scriptAlias = { + "Qaai": "Zinh" + }; + exports.variantAlias = { + "heploc": "alalc97", + "polytoni": "polyton" + }; + } + }); + + // node_modules/@formatjs/intl-getcanonicallocales/src/likelySubtags.generated.js + var require_likelySubtags_generated = __commonJS({ + "node_modules/@formatjs/intl-getcanonicallocales/src/likelySubtags.generated.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.likelySubtags = void 0; + exports.likelySubtags = { + "aa": "aa-Latn-ET", + "aai": "aai-Latn-ZZ", + "aak": "aak-Latn-ZZ", + "aau": "aau-Latn-ZZ", + "ab": "ab-Cyrl-GE", + "abi": "abi-Latn-ZZ", + "abq": "abq-Cyrl-ZZ", + "abr": "abr-Latn-GH", + "abt": "abt-Latn-ZZ", + "aby": "aby-Latn-ZZ", + "acd": "acd-Latn-ZZ", + "ace": "ace-Latn-ID", + "ach": "ach-Latn-UG", + "ada": "ada-Latn-GH", + "ade": "ade-Latn-ZZ", + "adj": "adj-Latn-ZZ", + "adp": "adp-Tibt-BT", + "ady": "ady-Cyrl-RU", + "adz": "adz-Latn-ZZ", + "ae": "ae-Avst-IR", + "aeb": "aeb-Arab-TN", + "aey": "aey-Latn-ZZ", + "af": "af-Latn-ZA", + "agc": "agc-Latn-ZZ", + "agd": "agd-Latn-ZZ", + "agg": "agg-Latn-ZZ", + "agm": "agm-Latn-ZZ", + "ago": "ago-Latn-ZZ", + "agq": "agq-Latn-CM", + "aha": "aha-Latn-ZZ", + "ahl": "ahl-Latn-ZZ", + "aho": "aho-Ahom-IN", + "ajg": "ajg-Latn-ZZ", + "ak": "ak-Latn-GH", + "akk": "akk-Xsux-IQ", + "ala": "ala-Latn-ZZ", + "ali": "ali-Latn-ZZ", + "aln": "aln-Latn-XK", + "alt": "alt-Cyrl-RU", + "am": "am-Ethi-ET", + "amm": "amm-Latn-ZZ", + "amn": "amn-Latn-ZZ", + "amo": "amo-Latn-NG", + "amp": "amp-Latn-ZZ", + "an": "an-Latn-ES", + "anc": "anc-Latn-ZZ", + "ank": "ank-Latn-ZZ", + "ann": "ann-Latn-ZZ", + "any": "any-Latn-ZZ", + "aoj": "aoj-Latn-ZZ", + "aom": "aom-Latn-ZZ", + "aoz": "aoz-Latn-ID", + "apc": "apc-Arab-ZZ", + "apd": "apd-Arab-TG", + "ape": "ape-Latn-ZZ", + "apr": "apr-Latn-ZZ", + "aps": "aps-Latn-ZZ", + "apz": "apz-Latn-ZZ", + "ar": "ar-Arab-EG", + "arc": "arc-Armi-IR", + "arc-Nbat": "arc-Nbat-JO", + "arc-Palm": "arc-Palm-SY", + "arh": "arh-Latn-ZZ", + "arn": "arn-Latn-CL", + "aro": "aro-Latn-BO", + "arq": "arq-Arab-DZ", + "ars": "ars-Arab-SA", + "ary": "ary-Arab-MA", + "arz": "arz-Arab-EG", + "as": "as-Beng-IN", + "asa": "asa-Latn-TZ", + "ase": "ase-Sgnw-US", + "asg": "asg-Latn-ZZ", + "aso": "aso-Latn-ZZ", + "ast": "ast-Latn-ES", + "ata": "ata-Latn-ZZ", + "atg": "atg-Latn-ZZ", + "atj": "atj-Latn-CA", + "auy": "auy-Latn-ZZ", + "av": "av-Cyrl-RU", + "avl": "avl-Arab-ZZ", + "avn": "avn-Latn-ZZ", + "avt": "avt-Latn-ZZ", + "avu": "avu-Latn-ZZ", + "awa": "awa-Deva-IN", + "awb": "awb-Latn-ZZ", + "awo": "awo-Latn-ZZ", + "awx": "awx-Latn-ZZ", + "ay": "ay-Latn-BO", + "ayb": "ayb-Latn-ZZ", + "az": "az-Latn-AZ", + "az-Arab": "az-Arab-IR", + "az-IQ": "az-Arab-IQ", + "az-IR": "az-Arab-IR", + "az-RU": "az-Cyrl-RU", + "ba": "ba-Cyrl-RU", + "bal": "bal-Arab-PK", + "ban": "ban-Latn-ID", + "bap": "bap-Deva-NP", + "bar": "bar-Latn-AT", + "bas": "bas-Latn-CM", + "bav": "bav-Latn-ZZ", + "bax": "bax-Bamu-CM", + "bba": "bba-Latn-ZZ", + "bbb": "bbb-Latn-ZZ", + "bbc": "bbc-Latn-ID", + "bbd": "bbd-Latn-ZZ", + "bbj": "bbj-Latn-CM", + "bbp": "bbp-Latn-ZZ", + "bbr": "bbr-Latn-ZZ", + "bcf": "bcf-Latn-ZZ", + "bch": "bch-Latn-ZZ", + "bci": "bci-Latn-CI", + "bcm": "bcm-Latn-ZZ", + "bcn": "bcn-Latn-ZZ", + "bco": "bco-Latn-ZZ", + "bcq": "bcq-Ethi-ZZ", + "bcu": "bcu-Latn-ZZ", + "bdd": "bdd-Latn-ZZ", + "be": "be-Cyrl-BY", + "bef": "bef-Latn-ZZ", + "beh": "beh-Latn-ZZ", + "bej": "bej-Arab-SD", + "bem": "bem-Latn-ZM", + "bet": "bet-Latn-ZZ", + "bew": "bew-Latn-ID", + "bex": "bex-Latn-ZZ", + "bez": "bez-Latn-TZ", + "bfd": "bfd-Latn-CM", + "bfq": "bfq-Taml-IN", + "bft": "bft-Arab-PK", + "bfy": "bfy-Deva-IN", + "bg": "bg-Cyrl-BG", + "bgc": "bgc-Deva-IN", + "bgn": "bgn-Arab-PK", + "bgx": "bgx-Grek-TR", + "bhb": "bhb-Deva-IN", + "bhg": "bhg-Latn-ZZ", + "bhi": "bhi-Deva-IN", + "bhl": "bhl-Latn-ZZ", + "bho": "bho-Deva-IN", + "bhy": "bhy-Latn-ZZ", + "bi": "bi-Latn-VU", + "bib": "bib-Latn-ZZ", + "big": "big-Latn-ZZ", + "bik": "bik-Latn-PH", + "bim": "bim-Latn-ZZ", + "bin": "bin-Latn-NG", + "bio": "bio-Latn-ZZ", + "biq": "biq-Latn-ZZ", + "bjh": "bjh-Latn-ZZ", + "bji": "bji-Ethi-ZZ", + "bjj": "bjj-Deva-IN", + "bjn": "bjn-Latn-ID", + "bjo": "bjo-Latn-ZZ", + "bjr": "bjr-Latn-ZZ", + "bjt": "bjt-Latn-SN", + "bjz": "bjz-Latn-ZZ", + "bkc": "bkc-Latn-ZZ", + "bkm": "bkm-Latn-CM", + "bkq": "bkq-Latn-ZZ", + "bku": "bku-Latn-PH", + "bkv": "bkv-Latn-ZZ", + "blg": "blg-Latn-MY", + "blt": "blt-Tavt-VN", + "bm": "bm-Latn-ML", + "bmh": "bmh-Latn-ZZ", + "bmk": "bmk-Latn-ZZ", + "bmq": "bmq-Latn-ML", + "bmu": "bmu-Latn-ZZ", + "bn": "bn-Beng-BD", + "bng": "bng-Latn-ZZ", + "bnm": "bnm-Latn-ZZ", + "bnp": "bnp-Latn-ZZ", + "bo": "bo-Tibt-CN", + "boj": "boj-Latn-ZZ", + "bom": "bom-Latn-ZZ", + "bon": "bon-Latn-ZZ", + "bpy": "bpy-Beng-IN", + "bqc": "bqc-Latn-ZZ", + "bqi": "bqi-Arab-IR", + "bqp": "bqp-Latn-ZZ", + "bqv": "bqv-Latn-CI", + "br": "br-Latn-FR", + "bra": "bra-Deva-IN", + "brh": "brh-Arab-PK", + "brx": "brx-Deva-IN", + "brz": "brz-Latn-ZZ", + "bs": "bs-Latn-BA", + "bsj": "bsj-Latn-ZZ", + "bsq": "bsq-Bass-LR", + "bss": "bss-Latn-CM", + "bst": "bst-Ethi-ZZ", + "bto": "bto-Latn-PH", + "btt": "btt-Latn-ZZ", + "btv": "btv-Deva-PK", + "bua": "bua-Cyrl-RU", + "buc": "buc-Latn-YT", + "bud": "bud-Latn-ZZ", + "bug": "bug-Latn-ID", + "buk": "buk-Latn-ZZ", + "bum": "bum-Latn-CM", + "buo": "buo-Latn-ZZ", + "bus": "bus-Latn-ZZ", + "buu": "buu-Latn-ZZ", + "bvb": "bvb-Latn-GQ", + "bwd": "bwd-Latn-ZZ", + "bwr": "bwr-Latn-ZZ", + "bxh": "bxh-Latn-ZZ", + "bye": "bye-Latn-ZZ", + "byn": "byn-Ethi-ER", + "byr": "byr-Latn-ZZ", + "bys": "bys-Latn-ZZ", + "byv": "byv-Latn-CM", + "byx": "byx-Latn-ZZ", + "bza": "bza-Latn-ZZ", + "bze": "bze-Latn-ML", + "bzf": "bzf-Latn-ZZ", + "bzh": "bzh-Latn-ZZ", + "bzw": "bzw-Latn-ZZ", + "ca": "ca-Latn-ES", + "cad": "cad-Latn-US", + "can": "can-Latn-ZZ", + "cbj": "cbj-Latn-ZZ", + "cch": "cch-Latn-NG", + "ccp": "ccp-Cakm-BD", + "ce": "ce-Cyrl-RU", + "ceb": "ceb-Latn-PH", + "cfa": "cfa-Latn-ZZ", + "cgg": "cgg-Latn-UG", + "ch": "ch-Latn-GU", + "chk": "chk-Latn-FM", + "chm": "chm-Cyrl-RU", + "cho": "cho-Latn-US", + "chp": "chp-Latn-CA", + "chr": "chr-Cher-US", + "cic": "cic-Latn-US", + "cja": "cja-Arab-KH", + "cjm": "cjm-Cham-VN", + "cjv": "cjv-Latn-ZZ", + "ckb": "ckb-Arab-IQ", + "ckl": "ckl-Latn-ZZ", + "cko": "cko-Latn-ZZ", + "cky": "cky-Latn-ZZ", + "cla": "cla-Latn-ZZ", + "cme": "cme-Latn-ZZ", + "cmg": "cmg-Soyo-MN", + "co": "co-Latn-FR", + "cop": "cop-Copt-EG", + "cps": "cps-Latn-PH", + "cr": "cr-Cans-CA", + "crh": "crh-Cyrl-UA", + "crj": "crj-Cans-CA", + "crk": "crk-Cans-CA", + "crl": "crl-Cans-CA", + "crm": "crm-Cans-CA", + "crs": "crs-Latn-SC", + "cs": "cs-Latn-CZ", + "csb": "csb-Latn-PL", + "csw": "csw-Cans-CA", + "ctd": "ctd-Pauc-MM", + "cu": "cu-Cyrl-RU", + "cu-Glag": "cu-Glag-BG", + "cv": "cv-Cyrl-RU", + "cy": "cy-Latn-GB", + "da": "da-Latn-DK", + "dad": "dad-Latn-ZZ", + "daf": "daf-Latn-CI", + "dag": "dag-Latn-ZZ", + "dah": "dah-Latn-ZZ", + "dak": "dak-Latn-US", + "dar": "dar-Cyrl-RU", + "dav": "dav-Latn-KE", + "dbd": "dbd-Latn-ZZ", + "dbq": "dbq-Latn-ZZ", + "dcc": "dcc-Arab-IN", + "ddn": "ddn-Latn-ZZ", + "de": "de-Latn-DE", + "ded": "ded-Latn-ZZ", + "den": "den-Latn-CA", + "dga": "dga-Latn-ZZ", + "dgh": "dgh-Latn-ZZ", + "dgi": "dgi-Latn-ZZ", + "dgl": "dgl-Arab-ZZ", + "dgr": "dgr-Latn-CA", + "dgz": "dgz-Latn-ZZ", + "dia": "dia-Latn-ZZ", + "dje": "dje-Latn-NE", + "dmf": "dmf-Medf-NG", + "dnj": "dnj-Latn-CI", + "dob": "dob-Latn-ZZ", + "doi": "doi-Deva-IN", + "dop": "dop-Latn-ZZ", + "dow": "dow-Latn-ZZ", + "drh": "drh-Mong-CN", + "dri": "dri-Latn-ZZ", + "drs": "drs-Ethi-ZZ", + "dsb": "dsb-Latn-DE", + "dtm": "dtm-Latn-ML", + "dtp": "dtp-Latn-MY", + "dts": "dts-Latn-ZZ", + "dty": "dty-Deva-NP", + "dua": "dua-Latn-CM", + "duc": "duc-Latn-ZZ", + "dud": "dud-Latn-ZZ", + "dug": "dug-Latn-ZZ", + "dv": "dv-Thaa-MV", + "dva": "dva-Latn-ZZ", + "dww": "dww-Latn-ZZ", + "dyo": "dyo-Latn-SN", + "dyu": "dyu-Latn-BF", + "dz": "dz-Tibt-BT", + "dzg": "dzg-Latn-ZZ", + "ebu": "ebu-Latn-KE", + "ee": "ee-Latn-GH", + "efi": "efi-Latn-NG", + "egl": "egl-Latn-IT", + "egy": "egy-Egyp-EG", + "eka": "eka-Latn-ZZ", + "eky": "eky-Kali-MM", + "el": "el-Grek-GR", + "ema": "ema-Latn-ZZ", + "emi": "emi-Latn-ZZ", + "en": "en-Latn-US", + "en-Shaw": "en-Shaw-GB", + "enn": "enn-Latn-ZZ", + "enq": "enq-Latn-ZZ", + "eo": "eo-Latn-001", + "eri": "eri-Latn-ZZ", + "es": "es-Latn-ES", + "esg": "esg-Gonm-IN", + "esu": "esu-Latn-US", + "et": "et-Latn-EE", + "etr": "etr-Latn-ZZ", + "ett": "ett-Ital-IT", + "etu": "etu-Latn-ZZ", + "etx": "etx-Latn-ZZ", + "eu": "eu-Latn-ES", + "ewo": "ewo-Latn-CM", + "ext": "ext-Latn-ES", + "eza": "eza-Latn-ZZ", + "fa": "fa-Arab-IR", + "faa": "faa-Latn-ZZ", + "fab": "fab-Latn-ZZ", + "fag": "fag-Latn-ZZ", + "fai": "fai-Latn-ZZ", + "fan": "fan-Latn-GQ", + "ff": "ff-Latn-SN", + "ff-Adlm": "ff-Adlm-GN", + "ffi": "ffi-Latn-ZZ", + "ffm": "ffm-Latn-ML", + "fi": "fi-Latn-FI", + "fia": "fia-Arab-SD", + "fil": "fil-Latn-PH", + "fit": "fit-Latn-SE", + "fj": "fj-Latn-FJ", + "flr": "flr-Latn-ZZ", + "fmp": "fmp-Latn-ZZ", + "fo": "fo-Latn-FO", + "fod": "fod-Latn-ZZ", + "fon": "fon-Latn-BJ", + "for": "for-Latn-ZZ", + "fpe": "fpe-Latn-ZZ", + "fqs": "fqs-Latn-ZZ", + "fr": "fr-Latn-FR", + "frc": "frc-Latn-US", + "frp": "frp-Latn-FR", + "frr": "frr-Latn-DE", + "frs": "frs-Latn-DE", + "fub": "fub-Arab-CM", + "fud": "fud-Latn-WF", + "fue": "fue-Latn-ZZ", + "fuf": "fuf-Latn-GN", + "fuh": "fuh-Latn-ZZ", + "fuq": "fuq-Latn-NE", + "fur": "fur-Latn-IT", + "fuv": "fuv-Latn-NG", + "fuy": "fuy-Latn-ZZ", + "fvr": "fvr-Latn-SD", + "fy": "fy-Latn-NL", + "ga": "ga-Latn-IE", + "gaa": "gaa-Latn-GH", + "gaf": "gaf-Latn-ZZ", + "gag": "gag-Latn-MD", + "gah": "gah-Latn-ZZ", + "gaj": "gaj-Latn-ZZ", + "gam": "gam-Latn-ZZ", + "gan": "gan-Hans-CN", + "gaw": "gaw-Latn-ZZ", + "gay": "gay-Latn-ID", + "gba": "gba-Latn-ZZ", + "gbf": "gbf-Latn-ZZ", + "gbm": "gbm-Deva-IN", + "gby": "gby-Latn-ZZ", + "gbz": "gbz-Arab-IR", + "gcr": "gcr-Latn-GF", + "gd": "gd-Latn-GB", + "gde": "gde-Latn-ZZ", + "gdn": "gdn-Latn-ZZ", + "gdr": "gdr-Latn-ZZ", + "geb": "geb-Latn-ZZ", + "gej": "gej-Latn-ZZ", + "gel": "gel-Latn-ZZ", + "gez": "gez-Ethi-ET", + "gfk": "gfk-Latn-ZZ", + "ggn": "ggn-Deva-NP", + "ghs": "ghs-Latn-ZZ", + "gil": "gil-Latn-KI", + "gim": "gim-Latn-ZZ", + "gjk": "gjk-Arab-PK", + "gjn": "gjn-Latn-ZZ", + "gju": "gju-Arab-PK", + "gkn": "gkn-Latn-ZZ", + "gkp": "gkp-Latn-ZZ", + "gl": "gl-Latn-ES", + "glk": "glk-Arab-IR", + "gmm": "gmm-Latn-ZZ", + "gmv": "gmv-Ethi-ZZ", + "gn": "gn-Latn-PY", + "gnd": "gnd-Latn-ZZ", + "gng": "gng-Latn-ZZ", + "god": "god-Latn-ZZ", + "gof": "gof-Ethi-ZZ", + "goi": "goi-Latn-ZZ", + "gom": "gom-Deva-IN", + "gon": "gon-Telu-IN", + "gor": "gor-Latn-ID", + "gos": "gos-Latn-NL", + "got": "got-Goth-UA", + "grb": "grb-Latn-ZZ", + "grc": "grc-Cprt-CY", + "grc-Linb": "grc-Linb-GR", + "grt": "grt-Beng-IN", + "grw": "grw-Latn-ZZ", + "gsw": "gsw-Latn-CH", + "gu": "gu-Gujr-IN", + "gub": "gub-Latn-BR", + "guc": "guc-Latn-CO", + "gud": "gud-Latn-ZZ", + "gur": "gur-Latn-GH", + "guw": "guw-Latn-ZZ", + "gux": "gux-Latn-ZZ", + "guz": "guz-Latn-KE", + "gv": "gv-Latn-IM", + "gvf": "gvf-Latn-ZZ", + "gvr": "gvr-Deva-NP", + "gvs": "gvs-Latn-ZZ", + "gwc": "gwc-Arab-ZZ", + "gwi": "gwi-Latn-CA", + "gwt": "gwt-Arab-ZZ", + "gyi": "gyi-Latn-ZZ", + "ha": "ha-Latn-NG", + "ha-CM": "ha-Arab-CM", + "ha-SD": "ha-Arab-SD", + "hag": "hag-Latn-ZZ", + "hak": "hak-Hans-CN", + "ham": "ham-Latn-ZZ", + "haw": "haw-Latn-US", + "haz": "haz-Arab-AF", + "hbb": "hbb-Latn-ZZ", + "hdy": "hdy-Ethi-ZZ", + "he": "he-Hebr-IL", + "hhy": "hhy-Latn-ZZ", + "hi": "hi-Deva-IN", + "hia": "hia-Latn-ZZ", + "hif": "hif-Latn-FJ", + "hig": "hig-Latn-ZZ", + "hih": "hih-Latn-ZZ", + "hil": "hil-Latn-PH", + "hla": "hla-Latn-ZZ", + "hlu": "hlu-Hluw-TR", + "hmd": "hmd-Plrd-CN", + "hmt": "hmt-Latn-ZZ", + "hnd": "hnd-Arab-PK", + "hne": "hne-Deva-IN", + "hnj": "hnj-Hmnp-US", + "hnn": "hnn-Latn-PH", + "hno": "hno-Arab-PK", + "ho": "ho-Latn-PG", + "hoc": "hoc-Deva-IN", + "hoj": "hoj-Deva-IN", + "hot": "hot-Latn-ZZ", + "hr": "hr-Latn-HR", + "hsb": "hsb-Latn-DE", + "hsn": "hsn-Hans-CN", + "ht": "ht-Latn-HT", + "hu": "hu-Latn-HU", + "hui": "hui-Latn-ZZ", + "hy": "hy-Armn-AM", + "hz": "hz-Latn-NA", + "ia": "ia-Latn-001", + "ian": "ian-Latn-ZZ", + "iar": "iar-Latn-ZZ", + "iba": "iba-Latn-MY", + "ibb": "ibb-Latn-NG", + "iby": "iby-Latn-ZZ", + "ica": "ica-Latn-ZZ", + "ich": "ich-Latn-ZZ", + "id": "id-Latn-ID", + "idd": "idd-Latn-ZZ", + "idi": "idi-Latn-ZZ", + "idu": "idu-Latn-ZZ", + "ife": "ife-Latn-TG", + "ig": "ig-Latn-NG", + "igb": "igb-Latn-ZZ", + "ige": "ige-Latn-ZZ", + "ii": "ii-Yiii-CN", + "ijj": "ijj-Latn-ZZ", + "ik": "ik-Latn-US", + "ikk": "ikk-Latn-ZZ", + "ikt": "ikt-Latn-CA", + "ikw": "ikw-Latn-ZZ", + "ikx": "ikx-Latn-ZZ", + "ilo": "ilo-Latn-PH", + "imo": "imo-Latn-ZZ", + "in": "in-Latn-ID", + "inh": "inh-Cyrl-RU", + "io": "io-Latn-001", + "iou": "iou-Latn-ZZ", + "iri": "iri-Latn-ZZ", + "is": "is-Latn-IS", + "it": "it-Latn-IT", + "iu": "iu-Cans-CA", + "iw": "iw-Hebr-IL", + "iwm": "iwm-Latn-ZZ", + "iws": "iws-Latn-ZZ", + "izh": "izh-Latn-RU", + "izi": "izi-Latn-ZZ", + "ja": "ja-Jpan-JP", + "jab": "jab-Latn-ZZ", + "jam": "jam-Latn-JM", + "jar": "jar-Latn-ZZ", + "jbo": "jbo-Latn-001", + "jbu": "jbu-Latn-ZZ", + "jen": "jen-Latn-ZZ", + "jgk": "jgk-Latn-ZZ", + "jgo": "jgo-Latn-CM", + "ji": "ji-Hebr-UA", + "jib": "jib-Latn-ZZ", + "jmc": "jmc-Latn-TZ", + "jml": "jml-Deva-NP", + "jra": "jra-Latn-ZZ", + "jut": "jut-Latn-DK", + "jv": "jv-Latn-ID", + "jw": "jw-Latn-ID", + "ka": "ka-Geor-GE", + "kaa": "kaa-Cyrl-UZ", + "kab": "kab-Latn-DZ", + "kac": "kac-Latn-MM", + "kad": "kad-Latn-ZZ", + "kai": "kai-Latn-ZZ", + "kaj": "kaj-Latn-NG", + "kam": "kam-Latn-KE", + "kao": "kao-Latn-ML", + "kbd": "kbd-Cyrl-RU", + "kbm": "kbm-Latn-ZZ", + "kbp": "kbp-Latn-ZZ", + "kbq": "kbq-Latn-ZZ", + "kbx": "kbx-Latn-ZZ", + "kby": "kby-Arab-NE", + "kcg": "kcg-Latn-NG", + "kck": "kck-Latn-ZW", + "kcl": "kcl-Latn-ZZ", + "kct": "kct-Latn-ZZ", + "kde": "kde-Latn-TZ", + "kdh": "kdh-Latn-TG", + "kdl": "kdl-Latn-ZZ", + "kdt": "kdt-Thai-TH", + "kea": "kea-Latn-CV", + "ken": "ken-Latn-CM", + "kez": "kez-Latn-ZZ", + "kfo": "kfo-Latn-CI", + "kfr": "kfr-Deva-IN", + "kfy": "kfy-Deva-IN", + "kg": "kg-Latn-CD", + "kge": "kge-Latn-ID", + "kgf": "kgf-Latn-ZZ", + "kgp": "kgp-Latn-BR", + "kha": "kha-Latn-IN", + "khb": "khb-Talu-CN", + "khn": "khn-Deva-IN", + "khq": "khq-Latn-ML", + "khs": "khs-Latn-ZZ", + "kht": "kht-Mymr-IN", + "khw": "khw-Arab-PK", + "khz": "khz-Latn-ZZ", + "ki": "ki-Latn-KE", + "kij": "kij-Latn-ZZ", + "kiu": "kiu-Latn-TR", + "kiw": "kiw-Latn-ZZ", + "kj": "kj-Latn-NA", + "kjd": "kjd-Latn-ZZ", + "kjg": "kjg-Laoo-LA", + "kjs": "kjs-Latn-ZZ", + "kjy": "kjy-Latn-ZZ", + "kk": "kk-Cyrl-KZ", + "kk-AF": "kk-Arab-AF", + "kk-Arab": "kk-Arab-CN", + "kk-CN": "kk-Arab-CN", + "kk-IR": "kk-Arab-IR", + "kk-MN": "kk-Arab-MN", + "kkc": "kkc-Latn-ZZ", + "kkj": "kkj-Latn-CM", + "kl": "kl-Latn-GL", + "kln": "kln-Latn-KE", + "klq": "klq-Latn-ZZ", + "klt": "klt-Latn-ZZ", + "klx": "klx-Latn-ZZ", + "km": "km-Khmr-KH", + "kmb": "kmb-Latn-AO", + "kmh": "kmh-Latn-ZZ", + "kmo": "kmo-Latn-ZZ", + "kms": "kms-Latn-ZZ", + "kmu": "kmu-Latn-ZZ", + "kmw": "kmw-Latn-ZZ", + "kn": "kn-Knda-IN", + "knf": "knf-Latn-GW", + "knp": "knp-Latn-ZZ", + "ko": "ko-Kore-KR", + "koi": "koi-Cyrl-RU", + "kok": "kok-Deva-IN", + "kol": "kol-Latn-ZZ", + "kos": "kos-Latn-FM", + "koz": "koz-Latn-ZZ", + "kpe": "kpe-Latn-LR", + "kpf": "kpf-Latn-ZZ", + "kpo": "kpo-Latn-ZZ", + "kpr": "kpr-Latn-ZZ", + "kpx": "kpx-Latn-ZZ", + "kqb": "kqb-Latn-ZZ", + "kqf": "kqf-Latn-ZZ", + "kqs": "kqs-Latn-ZZ", + "kqy": "kqy-Ethi-ZZ", + "kr": "kr-Latn-ZZ", + "krc": "krc-Cyrl-RU", + "kri": "kri-Latn-SL", + "krj": "krj-Latn-PH", + "krl": "krl-Latn-RU", + "krs": "krs-Latn-ZZ", + "kru": "kru-Deva-IN", + "ks": "ks-Arab-IN", + "ksb": "ksb-Latn-TZ", + "ksd": "ksd-Latn-ZZ", + "ksf": "ksf-Latn-CM", + "ksh": "ksh-Latn-DE", + "ksj": "ksj-Latn-ZZ", + "ksr": "ksr-Latn-ZZ", + "ktb": "ktb-Ethi-ZZ", + "ktm": "ktm-Latn-ZZ", + "kto": "kto-Latn-ZZ", + "ktr": "ktr-Latn-MY", + "ku": "ku-Latn-TR", + "ku-Arab": "ku-Arab-IQ", + "ku-LB": "ku-Arab-LB", + "ku-Yezi": "ku-Yezi-GE", + "kub": "kub-Latn-ZZ", + "kud": "kud-Latn-ZZ", + "kue": "kue-Latn-ZZ", + "kuj": "kuj-Latn-ZZ", + "kum": "kum-Cyrl-RU", + "kun": "kun-Latn-ZZ", + "kup": "kup-Latn-ZZ", + "kus": "kus-Latn-ZZ", + "kv": "kv-Cyrl-RU", + "kvg": "kvg-Latn-ZZ", + "kvr": "kvr-Latn-ID", + "kvx": "kvx-Arab-PK", + "kw": "kw-Latn-GB", + "kwj": "kwj-Latn-ZZ", + "kwo": "kwo-Latn-ZZ", + "kwq": "kwq-Latn-ZZ", + "kxa": "kxa-Latn-ZZ", + "kxc": "kxc-Ethi-ZZ", + "kxe": "kxe-Latn-ZZ", + "kxl": "kxl-Deva-IN", + "kxm": "kxm-Thai-TH", + "kxp": "kxp-Arab-PK", + "kxw": "kxw-Latn-ZZ", + "kxz": "kxz-Latn-ZZ", + "ky": "ky-Cyrl-KG", + "ky-Arab": "ky-Arab-CN", + "ky-CN": "ky-Arab-CN", + "ky-Latn": "ky-Latn-TR", + "ky-TR": "ky-Latn-TR", + "kye": "kye-Latn-ZZ", + "kyx": "kyx-Latn-ZZ", + "kzh": "kzh-Arab-ZZ", + "kzj": "kzj-Latn-MY", + "kzr": "kzr-Latn-ZZ", + "kzt": "kzt-Latn-MY", + "la": "la-Latn-VA", + "lab": "lab-Lina-GR", + "lad": "lad-Hebr-IL", + "lag": "lag-Latn-TZ", + "lah": "lah-Arab-PK", + "laj": "laj-Latn-UG", + "las": "las-Latn-ZZ", + "lb": "lb-Latn-LU", + "lbe": "lbe-Cyrl-RU", + "lbu": "lbu-Latn-ZZ", + "lbw": "lbw-Latn-ID", + "lcm": "lcm-Latn-ZZ", + "lcp": "lcp-Thai-CN", + "ldb": "ldb-Latn-ZZ", + "led": "led-Latn-ZZ", + "lee": "lee-Latn-ZZ", + "lem": "lem-Latn-ZZ", + "lep": "lep-Lepc-IN", + "leq": "leq-Latn-ZZ", + "leu": "leu-Latn-ZZ", + "lez": "lez-Cyrl-RU", + "lg": "lg-Latn-UG", + "lgg": "lgg-Latn-ZZ", + "li": "li-Latn-NL", + "lia": "lia-Latn-ZZ", + "lid": "lid-Latn-ZZ", + "lif": "lif-Deva-NP", + "lif-Limb": "lif-Limb-IN", + "lig": "lig-Latn-ZZ", + "lih": "lih-Latn-ZZ", + "lij": "lij-Latn-IT", + "lis": "lis-Lisu-CN", + "ljp": "ljp-Latn-ID", + "lki": "lki-Arab-IR", + "lkt": "lkt-Latn-US", + "lle": "lle-Latn-ZZ", + "lln": "lln-Latn-ZZ", + "lmn": "lmn-Telu-IN", + "lmo": "lmo-Latn-IT", + "lmp": "lmp-Latn-ZZ", + "ln": "ln-Latn-CD", + "lns": "lns-Latn-ZZ", + "lnu": "lnu-Latn-ZZ", + "lo": "lo-Laoo-LA", + "loj": "loj-Latn-ZZ", + "lok": "lok-Latn-ZZ", + "lol": "lol-Latn-CD", + "lor": "lor-Latn-ZZ", + "los": "los-Latn-ZZ", + "loz": "loz-Latn-ZM", + "lrc": "lrc-Arab-IR", + "lt": "lt-Latn-LT", + "ltg": "ltg-Latn-LV", + "lu": "lu-Latn-CD", + "lua": "lua-Latn-CD", + "luo": "luo-Latn-KE", + "luy": "luy-Latn-KE", + "luz": "luz-Arab-IR", + "lv": "lv-Latn-LV", + "lwl": "lwl-Thai-TH", + "lzh": "lzh-Hans-CN", + "lzz": "lzz-Latn-TR", + "mad": "mad-Latn-ID", + "maf": "maf-Latn-CM", + "mag": "mag-Deva-IN", + "mai": "mai-Deva-IN", + "mak": "mak-Latn-ID", + "man": "man-Latn-GM", + "man-GN": "man-Nkoo-GN", + "man-Nkoo": "man-Nkoo-GN", + "mas": "mas-Latn-KE", + "maw": "maw-Latn-ZZ", + "maz": "maz-Latn-MX", + "mbh": "mbh-Latn-ZZ", + "mbo": "mbo-Latn-ZZ", + "mbq": "mbq-Latn-ZZ", + "mbu": "mbu-Latn-ZZ", + "mbw": "mbw-Latn-ZZ", + "mci": "mci-Latn-ZZ", + "mcp": "mcp-Latn-ZZ", + "mcq": "mcq-Latn-ZZ", + "mcr": "mcr-Latn-ZZ", + "mcu": "mcu-Latn-ZZ", + "mda": "mda-Latn-ZZ", + "mde": "mde-Arab-ZZ", + "mdf": "mdf-Cyrl-RU", + "mdh": "mdh-Latn-PH", + "mdj": "mdj-Latn-ZZ", + "mdr": "mdr-Latn-ID", + "mdx": "mdx-Ethi-ZZ", + "med": "med-Latn-ZZ", + "mee": "mee-Latn-ZZ", + "mek": "mek-Latn-ZZ", + "men": "men-Latn-SL", + "mer": "mer-Latn-KE", + "met": "met-Latn-ZZ", + "meu": "meu-Latn-ZZ", + "mfa": "mfa-Arab-TH", + "mfe": "mfe-Latn-MU", + "mfn": "mfn-Latn-ZZ", + "mfo": "mfo-Latn-ZZ", + "mfq": "mfq-Latn-ZZ", + "mg": "mg-Latn-MG", + "mgh": "mgh-Latn-MZ", + "mgl": "mgl-Latn-ZZ", + "mgo": "mgo-Latn-CM", + "mgp": "mgp-Deva-NP", + "mgy": "mgy-Latn-TZ", + "mh": "mh-Latn-MH", + "mhi": "mhi-Latn-ZZ", + "mhl": "mhl-Latn-ZZ", + "mi": "mi-Latn-NZ", + "mif": "mif-Latn-ZZ", + "min": "min-Latn-ID", + "miw": "miw-Latn-ZZ", + "mk": "mk-Cyrl-MK", + "mki": "mki-Arab-ZZ", + "mkl": "mkl-Latn-ZZ", + "mkp": "mkp-Latn-ZZ", + "mkw": "mkw-Latn-ZZ", + "ml": "ml-Mlym-IN", + "mle": "mle-Latn-ZZ", + "mlp": "mlp-Latn-ZZ", + "mls": "mls-Latn-SD", + "mmo": "mmo-Latn-ZZ", + "mmu": "mmu-Latn-ZZ", + "mmx": "mmx-Latn-ZZ", + "mn": "mn-Cyrl-MN", + "mn-CN": "mn-Mong-CN", + "mn-Mong": "mn-Mong-CN", + "mna": "mna-Latn-ZZ", + "mnf": "mnf-Latn-ZZ", + "mni": "mni-Beng-IN", + "mnw": "mnw-Mymr-MM", + "mo": "mo-Latn-RO", + "moa": "moa-Latn-ZZ", + "moe": "moe-Latn-CA", + "moh": "moh-Latn-CA", + "mos": "mos-Latn-BF", + "mox": "mox-Latn-ZZ", + "mpp": "mpp-Latn-ZZ", + "mps": "mps-Latn-ZZ", + "mpt": "mpt-Latn-ZZ", + "mpx": "mpx-Latn-ZZ", + "mql": "mql-Latn-ZZ", + "mr": "mr-Deva-IN", + "mrd": "mrd-Deva-NP", + "mrj": "mrj-Cyrl-RU", + "mro": "mro-Mroo-BD", + "ms": "ms-Latn-MY", + "ms-CC": "ms-Arab-CC", + "mt": "mt-Latn-MT", + "mtc": "mtc-Latn-ZZ", + "mtf": "mtf-Latn-ZZ", + "mti": "mti-Latn-ZZ", + "mtr": "mtr-Deva-IN", + "mua": "mua-Latn-CM", + "mur": "mur-Latn-ZZ", + "mus": "mus-Latn-US", + "mva": "mva-Latn-ZZ", + "mvn": "mvn-Latn-ZZ", + "mvy": "mvy-Arab-PK", + "mwk": "mwk-Latn-ML", + "mwr": "mwr-Deva-IN", + "mwv": "mwv-Latn-ID", + "mww": "mww-Hmnp-US", + "mxc": "mxc-Latn-ZW", + "mxm": "mxm-Latn-ZZ", + "my": "my-Mymr-MM", + "myk": "myk-Latn-ZZ", + "mym": "mym-Ethi-ZZ", + "myv": "myv-Cyrl-RU", + "myw": "myw-Latn-ZZ", + "myx": "myx-Latn-UG", + "myz": "myz-Mand-IR", + "mzk": "mzk-Latn-ZZ", + "mzm": "mzm-Latn-ZZ", + "mzn": "mzn-Arab-IR", + "mzp": "mzp-Latn-ZZ", + "mzw": "mzw-Latn-ZZ", + "mzz": "mzz-Latn-ZZ", + "na": "na-Latn-NR", + "nac": "nac-Latn-ZZ", + "naf": "naf-Latn-ZZ", + "nak": "nak-Latn-ZZ", + "nan": "nan-Hans-CN", + "nap": "nap-Latn-IT", + "naq": "naq-Latn-NA", + "nas": "nas-Latn-ZZ", + "nb": "nb-Latn-NO", + "nca": "nca-Latn-ZZ", + "nce": "nce-Latn-ZZ", + "ncf": "ncf-Latn-ZZ", + "nch": "nch-Latn-MX", + "nco": "nco-Latn-ZZ", + "ncu": "ncu-Latn-ZZ", + "nd": "nd-Latn-ZW", + "ndc": "ndc-Latn-MZ", + "nds": "nds-Latn-DE", + "ne": "ne-Deva-NP", + "neb": "neb-Latn-ZZ", + "new": "new-Deva-NP", + "nex": "nex-Latn-ZZ", + "nfr": "nfr-Latn-ZZ", + "ng": "ng-Latn-NA", + "nga": "nga-Latn-ZZ", + "ngb": "ngb-Latn-ZZ", + "ngl": "ngl-Latn-MZ", + "nhb": "nhb-Latn-ZZ", + "nhe": "nhe-Latn-MX", + "nhw": "nhw-Latn-MX", + "nif": "nif-Latn-ZZ", + "nii": "nii-Latn-ZZ", + "nij": "nij-Latn-ID", + "nin": "nin-Latn-ZZ", + "niu": "niu-Latn-NU", + "niy": "niy-Latn-ZZ", + "niz": "niz-Latn-ZZ", + "njo": "njo-Latn-IN", + "nkg": "nkg-Latn-ZZ", + "nko": "nko-Latn-ZZ", + "nl": "nl-Latn-NL", + "nmg": "nmg-Latn-CM", + "nmz": "nmz-Latn-ZZ", + "nn": "nn-Latn-NO", + "nnf": "nnf-Latn-ZZ", + "nnh": "nnh-Latn-CM", + "nnk": "nnk-Latn-ZZ", + "nnm": "nnm-Latn-ZZ", + "nnp": "nnp-Wcho-IN", + "no": "no-Latn-NO", + "nod": "nod-Lana-TH", + "noe": "noe-Deva-IN", + "non": "non-Runr-SE", + "nop": "nop-Latn-ZZ", + "nou": "nou-Latn-ZZ", + "nqo": "nqo-Nkoo-GN", + "nr": "nr-Latn-ZA", + "nrb": "nrb-Latn-ZZ", + "nsk": "nsk-Cans-CA", + "nsn": "nsn-Latn-ZZ", + "nso": "nso-Latn-ZA", + "nss": "nss-Latn-ZZ", + "nst": "nst-Tnsa-IN", + "ntm": "ntm-Latn-ZZ", + "ntr": "ntr-Latn-ZZ", + "nui": "nui-Latn-ZZ", + "nup": "nup-Latn-ZZ", + "nus": "nus-Latn-SS", + "nuv": "nuv-Latn-ZZ", + "nux": "nux-Latn-ZZ", + "nv": "nv-Latn-US", + "nwb": "nwb-Latn-ZZ", + "nxq": "nxq-Latn-CN", + "nxr": "nxr-Latn-ZZ", + "ny": "ny-Latn-MW", + "nym": "nym-Latn-TZ", + "nyn": "nyn-Latn-UG", + "nzi": "nzi-Latn-GH", + "oc": "oc-Latn-FR", + "ogc": "ogc-Latn-ZZ", + "okr": "okr-Latn-ZZ", + "okv": "okv-Latn-ZZ", + "om": "om-Latn-ET", + "ong": "ong-Latn-ZZ", + "onn": "onn-Latn-ZZ", + "ons": "ons-Latn-ZZ", + "opm": "opm-Latn-ZZ", + "or": "or-Orya-IN", + "oro": "oro-Latn-ZZ", + "oru": "oru-Arab-ZZ", + "os": "os-Cyrl-GE", + "osa": "osa-Osge-US", + "ota": "ota-Arab-ZZ", + "otk": "otk-Orkh-MN", + "oui": "oui-Ougr-143", + "ozm": "ozm-Latn-ZZ", + "pa": "pa-Guru-IN", + "pa-Arab": "pa-Arab-PK", + "pa-PK": "pa-Arab-PK", + "pag": "pag-Latn-PH", + "pal": "pal-Phli-IR", + "pal-Phlp": "pal-Phlp-CN", + "pam": "pam-Latn-PH", + "pap": "pap-Latn-AW", + "pau": "pau-Latn-PW", + "pbi": "pbi-Latn-ZZ", + "pcd": "pcd-Latn-FR", + "pcm": "pcm-Latn-NG", + "pdc": "pdc-Latn-US", + "pdt": "pdt-Latn-CA", + "ped": "ped-Latn-ZZ", + "peo": "peo-Xpeo-IR", + "pex": "pex-Latn-ZZ", + "pfl": "pfl-Latn-DE", + "phl": "phl-Arab-ZZ", + "phn": "phn-Phnx-LB", + "pil": "pil-Latn-ZZ", + "pip": "pip-Latn-ZZ", + "pka": "pka-Brah-IN", + "pko": "pko-Latn-KE", + "pl": "pl-Latn-PL", + "pla": "pla-Latn-ZZ", + "pms": "pms-Latn-IT", + "png": "png-Latn-ZZ", + "pnn": "pnn-Latn-ZZ", + "pnt": "pnt-Grek-GR", + "pon": "pon-Latn-FM", + "ppa": "ppa-Deva-IN", + "ppo": "ppo-Latn-ZZ", + "pra": "pra-Khar-PK", + "prd": "prd-Arab-IR", + "prg": "prg-Latn-001", + "ps": "ps-Arab-AF", + "pss": "pss-Latn-ZZ", + "pt": "pt-Latn-BR", + "ptp": "ptp-Latn-ZZ", + "puu": "puu-Latn-GA", + "pwa": "pwa-Latn-ZZ", + "qu": "qu-Latn-PE", + "quc": "quc-Latn-GT", + "qug": "qug-Latn-EC", + "rai": "rai-Latn-ZZ", + "raj": "raj-Deva-IN", + "rao": "rao-Latn-ZZ", + "rcf": "rcf-Latn-RE", + "rej": "rej-Latn-ID", + "rel": "rel-Latn-ZZ", + "res": "res-Latn-ZZ", + "rgn": "rgn-Latn-IT", + "rhg": "rhg-Rohg-MM", + "ria": "ria-Latn-IN", + "rif": "rif-Tfng-MA", + "rif-NL": "rif-Latn-NL", + "rjs": "rjs-Deva-NP", + "rkt": "rkt-Beng-BD", + "rm": "rm-Latn-CH", + "rmf": "rmf-Latn-FI", + "rmo": "rmo-Latn-CH", + "rmt": "rmt-Arab-IR", + "rmu": "rmu-Latn-SE", + "rn": "rn-Latn-BI", + "rna": "rna-Latn-ZZ", + "rng": "rng-Latn-MZ", + "ro": "ro-Latn-RO", + "rob": "rob-Latn-ID", + "rof": "rof-Latn-TZ", + "roo": "roo-Latn-ZZ", + "rro": "rro-Latn-ZZ", + "rtm": "rtm-Latn-FJ", + "ru": "ru-Cyrl-RU", + "rue": "rue-Cyrl-UA", + "rug": "rug-Latn-SB", + "rw": "rw-Latn-RW", + "rwk": "rwk-Latn-TZ", + "rwo": "rwo-Latn-ZZ", + "ryu": "ryu-Kana-JP", + "sa": "sa-Deva-IN", + "saf": "saf-Latn-GH", + "sah": "sah-Cyrl-RU", + "saq": "saq-Latn-KE", + "sas": "sas-Latn-ID", + "sat": "sat-Olck-IN", + "sav": "sav-Latn-SN", + "saz": "saz-Saur-IN", + "sba": "sba-Latn-ZZ", + "sbe": "sbe-Latn-ZZ", + "sbp": "sbp-Latn-TZ", + "sc": "sc-Latn-IT", + "sck": "sck-Deva-IN", + "scl": "scl-Arab-ZZ", + "scn": "scn-Latn-IT", + "sco": "sco-Latn-GB", + "scs": "scs-Latn-CA", + "sd": "sd-Arab-PK", + "sd-Deva": "sd-Deva-IN", + "sd-Khoj": "sd-Khoj-IN", + "sd-Sind": "sd-Sind-IN", + "sdc": "sdc-Latn-IT", + "sdh": "sdh-Arab-IR", + "se": "se-Latn-NO", + "sef": "sef-Latn-CI", + "seh": "seh-Latn-MZ", + "sei": "sei-Latn-MX", + "ses": "ses-Latn-ML", + "sg": "sg-Latn-CF", + "sga": "sga-Ogam-IE", + "sgs": "sgs-Latn-LT", + "sgw": "sgw-Ethi-ZZ", + "sgz": "sgz-Latn-ZZ", + "shi": "shi-Tfng-MA", + "shk": "shk-Latn-ZZ", + "shn": "shn-Mymr-MM", + "shu": "shu-Arab-ZZ", + "si": "si-Sinh-LK", + "sid": "sid-Latn-ET", + "sig": "sig-Latn-ZZ", + "sil": "sil-Latn-ZZ", + "sim": "sim-Latn-ZZ", + "sjr": "sjr-Latn-ZZ", + "sk": "sk-Latn-SK", + "skc": "skc-Latn-ZZ", + "skr": "skr-Arab-PK", + "sks": "sks-Latn-ZZ", + "sl": "sl-Latn-SI", + "sld": "sld-Latn-ZZ", + "sli": "sli-Latn-PL", + "sll": "sll-Latn-ZZ", + "sly": "sly-Latn-ID", + "sm": "sm-Latn-WS", + "sma": "sma-Latn-SE", + "smj": "smj-Latn-SE", + "smn": "smn-Latn-FI", + "smp": "smp-Samr-IL", + "smq": "smq-Latn-ZZ", + "sms": "sms-Latn-FI", + "sn": "sn-Latn-ZW", + "snc": "snc-Latn-ZZ", + "snk": "snk-Latn-ML", + "snp": "snp-Latn-ZZ", + "snx": "snx-Latn-ZZ", + "sny": "sny-Latn-ZZ", + "so": "so-Latn-SO", + "sog": "sog-Sogd-UZ", + "sok": "sok-Latn-ZZ", + "soq": "soq-Latn-ZZ", + "sou": "sou-Thai-TH", + "soy": "soy-Latn-ZZ", + "spd": "spd-Latn-ZZ", + "spl": "spl-Latn-ZZ", + "sps": "sps-Latn-ZZ", + "sq": "sq-Latn-AL", + "sr": "sr-Cyrl-RS", + "sr-ME": "sr-Latn-ME", + "sr-RO": "sr-Latn-RO", + "sr-RU": "sr-Latn-RU", + "sr-TR": "sr-Latn-TR", + "srb": "srb-Sora-IN", + "srn": "srn-Latn-SR", + "srr": "srr-Latn-SN", + "srx": "srx-Deva-IN", + "ss": "ss-Latn-ZA", + "ssd": "ssd-Latn-ZZ", + "ssg": "ssg-Latn-ZZ", + "ssy": "ssy-Latn-ER", + "st": "st-Latn-ZA", + "stk": "stk-Latn-ZZ", + "stq": "stq-Latn-DE", + "su": "su-Latn-ID", + "sua": "sua-Latn-ZZ", + "sue": "sue-Latn-ZZ", + "suk": "suk-Latn-TZ", + "sur": "sur-Latn-ZZ", + "sus": "sus-Latn-GN", + "sv": "sv-Latn-SE", + "sw": "sw-Latn-TZ", + "swb": "swb-Arab-YT", + "swc": "swc-Latn-CD", + "swg": "swg-Latn-DE", + "swp": "swp-Latn-ZZ", + "swv": "swv-Deva-IN", + "sxn": "sxn-Latn-ID", + "sxw": "sxw-Latn-ZZ", + "syl": "syl-Beng-BD", + "syr": "syr-Syrc-IQ", + "szl": "szl-Latn-PL", + "ta": "ta-Taml-IN", + "taj": "taj-Deva-NP", + "tal": "tal-Latn-ZZ", + "tan": "tan-Latn-ZZ", + "taq": "taq-Latn-ZZ", + "tbc": "tbc-Latn-ZZ", + "tbd": "tbd-Latn-ZZ", + "tbf": "tbf-Latn-ZZ", + "tbg": "tbg-Latn-ZZ", + "tbo": "tbo-Latn-ZZ", + "tbw": "tbw-Latn-PH", + "tbz": "tbz-Latn-ZZ", + "tci": "tci-Latn-ZZ", + "tcy": "tcy-Knda-IN", + "tdd": "tdd-Tale-CN", + "tdg": "tdg-Deva-NP", + "tdh": "tdh-Deva-NP", + "tdu": "tdu-Latn-MY", + "te": "te-Telu-IN", + "ted": "ted-Latn-ZZ", + "tem": "tem-Latn-SL", + "teo": "teo-Latn-UG", + "tet": "tet-Latn-TL", + "tfi": "tfi-Latn-ZZ", + "tg": "tg-Cyrl-TJ", + "tg-Arab": "tg-Arab-PK", + "tg-PK": "tg-Arab-PK", + "tgc": "tgc-Latn-ZZ", + "tgo": "tgo-Latn-ZZ", + "tgu": "tgu-Latn-ZZ", + "th": "th-Thai-TH", + "thl": "thl-Deva-NP", + "thq": "thq-Deva-NP", + "thr": "thr-Deva-NP", + "ti": "ti-Ethi-ET", + "tif": "tif-Latn-ZZ", + "tig": "tig-Ethi-ER", + "tik": "tik-Latn-ZZ", + "tim": "tim-Latn-ZZ", + "tio": "tio-Latn-ZZ", + "tiv": "tiv-Latn-NG", + "tk": "tk-Latn-TM", + "tkl": "tkl-Latn-TK", + "tkr": "tkr-Latn-AZ", + "tkt": "tkt-Deva-NP", + "tl": "tl-Latn-PH", + "tlf": "tlf-Latn-ZZ", + "tlx": "tlx-Latn-ZZ", + "tly": "tly-Latn-AZ", + "tmh": "tmh-Latn-NE", + "tmy": "tmy-Latn-ZZ", + "tn": "tn-Latn-ZA", + "tnh": "tnh-Latn-ZZ", + "to": "to-Latn-TO", + "tof": "tof-Latn-ZZ", + "tog": "tog-Latn-MW", + "toq": "toq-Latn-ZZ", + "tpi": "tpi-Latn-PG", + "tpm": "tpm-Latn-ZZ", + "tpz": "tpz-Latn-ZZ", + "tqo": "tqo-Latn-ZZ", + "tr": "tr-Latn-TR", + "tru": "tru-Latn-TR", + "trv": "trv-Latn-TW", + "trw": "trw-Arab-PK", + "ts": "ts-Latn-ZA", + "tsd": "tsd-Grek-GR", + "tsf": "tsf-Deva-NP", + "tsg": "tsg-Latn-PH", + "tsj": "tsj-Tibt-BT", + "tsw": "tsw-Latn-ZZ", + "tt": "tt-Cyrl-RU", + "ttd": "ttd-Latn-ZZ", + "tte": "tte-Latn-ZZ", + "ttj": "ttj-Latn-UG", + "ttr": "ttr-Latn-ZZ", + "tts": "tts-Thai-TH", + "ttt": "ttt-Latn-AZ", + "tuh": "tuh-Latn-ZZ", + "tul": "tul-Latn-ZZ", + "tum": "tum-Latn-MW", + "tuq": "tuq-Latn-ZZ", + "tvd": "tvd-Latn-ZZ", + "tvl": "tvl-Latn-TV", + "tvu": "tvu-Latn-ZZ", + "twh": "twh-Latn-ZZ", + "twq": "twq-Latn-NE", + "txg": "txg-Tang-CN", + "txo": "txo-Toto-IN", + "ty": "ty-Latn-PF", + "tya": "tya-Latn-ZZ", + "tyv": "tyv-Cyrl-RU", + "tzm": "tzm-Latn-MA", + "ubu": "ubu-Latn-ZZ", + "udi": "udi-Aghb-RU", + "udm": "udm-Cyrl-RU", + "ug": "ug-Arab-CN", + "ug-Cyrl": "ug-Cyrl-KZ", + "ug-KZ": "ug-Cyrl-KZ", + "ug-MN": "ug-Cyrl-MN", + "uga": "uga-Ugar-SY", + "uk": "uk-Cyrl-UA", + "uli": "uli-Latn-FM", + "umb": "umb-Latn-AO", + "und": "en-Latn-US", + "und-002": "en-Latn-NG", + "und-003": "en-Latn-US", + "und-005": "pt-Latn-BR", + "und-009": "en-Latn-AU", + "und-011": "en-Latn-NG", + "und-013": "es-Latn-MX", + "und-014": "sw-Latn-TZ", + "und-015": "ar-Arab-EG", + "und-017": "sw-Latn-CD", + "und-018": "en-Latn-ZA", + "und-019": "en-Latn-US", + "und-021": "en-Latn-US", + "und-029": "es-Latn-CU", + "und-030": "zh-Hans-CN", + "und-034": "hi-Deva-IN", + "und-035": "id-Latn-ID", + "und-039": "it-Latn-IT", + "und-053": "en-Latn-AU", + "und-054": "en-Latn-PG", + "und-057": "en-Latn-GU", + "und-061": "sm-Latn-WS", + "und-142": "zh-Hans-CN", + "und-143": "uz-Latn-UZ", + "und-145": "ar-Arab-SA", + "und-150": "ru-Cyrl-RU", + "und-151": "ru-Cyrl-RU", + "und-154": "en-Latn-GB", + "und-155": "de-Latn-DE", + "und-202": "en-Latn-NG", + "und-419": "es-Latn-419", + "und-AD": "ca-Latn-AD", + "und-Adlm": "ff-Adlm-GN", + "und-AE": "ar-Arab-AE", + "und-AF": "fa-Arab-AF", + "und-Aghb": "udi-Aghb-RU", + "und-Ahom": "aho-Ahom-IN", + "und-AL": "sq-Latn-AL", + "und-AM": "hy-Armn-AM", + "und-AO": "pt-Latn-AO", + "und-AQ": "und-Latn-AQ", + "und-AR": "es-Latn-AR", + "und-Arab": "ar-Arab-EG", + "und-Arab-CC": "ms-Arab-CC", + "und-Arab-CN": "ug-Arab-CN", + "und-Arab-GB": "ks-Arab-GB", + "und-Arab-ID": "ms-Arab-ID", + "und-Arab-IN": "ur-Arab-IN", + "und-Arab-KH": "cja-Arab-KH", + "und-Arab-MM": "rhg-Arab-MM", + "und-Arab-MN": "kk-Arab-MN", + "und-Arab-MU": "ur-Arab-MU", + "und-Arab-NG": "ha-Arab-NG", + "und-Arab-PK": "ur-Arab-PK", + "und-Arab-TG": "apd-Arab-TG", + "und-Arab-TH": "mfa-Arab-TH", + "und-Arab-TJ": "fa-Arab-TJ", + "und-Arab-TR": "az-Arab-TR", + "und-Arab-YT": "swb-Arab-YT", + "und-Armi": "arc-Armi-IR", + "und-Armn": "hy-Armn-AM", + "und-AS": "sm-Latn-AS", + "und-AT": "de-Latn-AT", + "und-Avst": "ae-Avst-IR", + "und-AW": "nl-Latn-AW", + "und-AX": "sv-Latn-AX", + "und-AZ": "az-Latn-AZ", + "und-BA": "bs-Latn-BA", + "und-Bali": "ban-Bali-ID", + "und-Bamu": "bax-Bamu-CM", + "und-Bass": "bsq-Bass-LR", + "und-Batk": "bbc-Batk-ID", + "und-BD": "bn-Beng-BD", + "und-BE": "nl-Latn-BE", + "und-Beng": "bn-Beng-BD", + "und-BF": "fr-Latn-BF", + "und-BG": "bg-Cyrl-BG", + "und-BH": "ar-Arab-BH", + "und-Bhks": "sa-Bhks-IN", + "und-BI": "rn-Latn-BI", + "und-BJ": "fr-Latn-BJ", + "und-BL": "fr-Latn-BL", + "und-BN": "ms-Latn-BN", + "und-BO": "es-Latn-BO", + "und-Bopo": "zh-Bopo-TW", + "und-BQ": "pap-Latn-BQ", + "und-BR": "pt-Latn-BR", + "und-Brah": "pka-Brah-IN", + "und-Brai": "fr-Brai-FR", + "und-BT": "dz-Tibt-BT", + "und-Bugi": "bug-Bugi-ID", + "und-Buhd": "bku-Buhd-PH", + "und-BV": "und-Latn-BV", + "und-BY": "be-Cyrl-BY", + "und-Cakm": "ccp-Cakm-BD", + "und-Cans": "cr-Cans-CA", + "und-Cari": "xcr-Cari-TR", + "und-CD": "sw-Latn-CD", + "und-CF": "fr-Latn-CF", + "und-CG": "fr-Latn-CG", + "und-CH": "de-Latn-CH", + "und-Cham": "cjm-Cham-VN", + "und-Cher": "chr-Cher-US", + "und-Chrs": "xco-Chrs-UZ", + "und-CI": "fr-Latn-CI", + "und-CL": "es-Latn-CL", + "und-CM": "fr-Latn-CM", + "und-CN": "zh-Hans-CN", + "und-CO": "es-Latn-CO", + "und-Copt": "cop-Copt-EG", + "und-CP": "und-Latn-CP", + "und-Cpmn": "und-Cpmn-CY", + "und-Cpmn-CY": "und-Cpmn-CY", + "und-Cprt": "grc-Cprt-CY", + "und-CR": "es-Latn-CR", + "und-CU": "es-Latn-CU", + "und-CV": "pt-Latn-CV", + "und-CW": "pap-Latn-CW", + "und-CY": "el-Grek-CY", + "und-Cyrl": "ru-Cyrl-RU", + "und-Cyrl-AL": "mk-Cyrl-AL", + "und-Cyrl-BA": "sr-Cyrl-BA", + "und-Cyrl-GE": "os-Cyrl-GE", + "und-Cyrl-GR": "mk-Cyrl-GR", + "und-Cyrl-MD": "uk-Cyrl-MD", + "und-Cyrl-RO": "bg-Cyrl-RO", + "und-Cyrl-SK": "uk-Cyrl-SK", + "und-Cyrl-TR": "kbd-Cyrl-TR", + "und-Cyrl-XK": "sr-Cyrl-XK", + "und-CZ": "cs-Latn-CZ", + "und-DE": "de-Latn-DE", + "und-Deva": "hi-Deva-IN", + "und-Deva-BT": "ne-Deva-BT", + "und-Deva-FJ": "hif-Deva-FJ", + "und-Deva-MU": "bho-Deva-MU", + "und-Deva-PK": "btv-Deva-PK", + "und-Diak": "dv-Diak-MV", + "und-DJ": "aa-Latn-DJ", + "und-DK": "da-Latn-DK", + "und-DO": "es-Latn-DO", + "und-Dogr": "doi-Dogr-IN", + "und-Dupl": "fr-Dupl-FR", + "und-DZ": "ar-Arab-DZ", + "und-EA": "es-Latn-EA", + "und-EC": "es-Latn-EC", + "und-EE": "et-Latn-EE", + "und-EG": "ar-Arab-EG", + "und-Egyp": "egy-Egyp-EG", + "und-EH": "ar-Arab-EH", + "und-Elba": "sq-Elba-AL", + "und-Elym": "arc-Elym-IR", + "und-ER": "ti-Ethi-ER", + "und-ES": "es-Latn-ES", + "und-ET": "am-Ethi-ET", + "und-Ethi": "am-Ethi-ET", + "und-EU": "en-Latn-IE", + "und-EZ": "de-Latn-EZ", + "und-FI": "fi-Latn-FI", + "und-FO": "fo-Latn-FO", + "und-FR": "fr-Latn-FR", + "und-GA": "fr-Latn-GA", + "und-GE": "ka-Geor-GE", + "und-Geor": "ka-Geor-GE", + "und-GF": "fr-Latn-GF", + "und-GH": "ak-Latn-GH", + "und-GL": "kl-Latn-GL", + "und-Glag": "cu-Glag-BG", + "und-GN": "fr-Latn-GN", + "und-Gong": "wsg-Gong-IN", + "und-Gonm": "esg-Gonm-IN", + "und-Goth": "got-Goth-UA", + "und-GP": "fr-Latn-GP", + "und-GQ": "es-Latn-GQ", + "und-GR": "el-Grek-GR", + "und-Gran": "sa-Gran-IN", + "und-Grek": "el-Grek-GR", + "und-Grek-TR": "bgx-Grek-TR", + "und-GS": "und-Latn-GS", + "und-GT": "es-Latn-GT", + "und-Gujr": "gu-Gujr-IN", + "und-Guru": "pa-Guru-IN", + "und-GW": "pt-Latn-GW", + "und-Hanb": "zh-Hanb-TW", + "und-Hang": "ko-Hang-KR", + "und-Hani": "zh-Hani-CN", + "und-Hano": "hnn-Hano-PH", + "und-Hans": "zh-Hans-CN", + "und-Hant": "zh-Hant-TW", + "und-Hebr": "he-Hebr-IL", + "und-Hebr-CA": "yi-Hebr-CA", + "und-Hebr-GB": "yi-Hebr-GB", + "und-Hebr-SE": "yi-Hebr-SE", + "und-Hebr-UA": "yi-Hebr-UA", + "und-Hebr-US": "yi-Hebr-US", + "und-Hira": "ja-Hira-JP", + "und-HK": "zh-Hant-HK", + "und-Hluw": "hlu-Hluw-TR", + "und-HM": "und-Latn-HM", + "und-Hmng": "hnj-Hmng-LA", + "und-Hmnp": "hnj-Hmnp-US", + "und-HN": "es-Latn-HN", + "und-HR": "hr-Latn-HR", + "und-HT": "ht-Latn-HT", + "und-HU": "hu-Latn-HU", + "und-Hung": "hu-Hung-HU", + "und-IC": "es-Latn-IC", + "und-ID": "id-Latn-ID", + "und-IL": "he-Hebr-IL", + "und-IN": "hi-Deva-IN", + "und-IQ": "ar-Arab-IQ", + "und-IR": "fa-Arab-IR", + "und-IS": "is-Latn-IS", + "und-IT": "it-Latn-IT", + "und-Ital": "ett-Ital-IT", + "und-Jamo": "ko-Jamo-KR", + "und-Java": "jv-Java-ID", + "und-JO": "ar-Arab-JO", + "und-JP": "ja-Jpan-JP", + "und-Jpan": "ja-Jpan-JP", + "und-Kali": "eky-Kali-MM", + "und-Kana": "ja-Kana-JP", + "und-KE": "sw-Latn-KE", + "und-KG": "ky-Cyrl-KG", + "und-KH": "km-Khmr-KH", + "und-Khar": "pra-Khar-PK", + "und-Khmr": "km-Khmr-KH", + "und-Khoj": "sd-Khoj-IN", + "und-Kits": "zkt-Kits-CN", + "und-KM": "ar-Arab-KM", + "und-Knda": "kn-Knda-IN", + "und-Kore": "ko-Kore-KR", + "und-KP": "ko-Kore-KP", + "und-KR": "ko-Kore-KR", + "und-Kthi": "bho-Kthi-IN", + "und-KW": "ar-Arab-KW", + "und-KZ": "ru-Cyrl-KZ", + "und-LA": "lo-Laoo-LA", + "und-Lana": "nod-Lana-TH", + "und-Laoo": "lo-Laoo-LA", + "und-Latn-AF": "tk-Latn-AF", + "und-Latn-AM": "ku-Latn-AM", + "und-Latn-CN": "za-Latn-CN", + "und-Latn-CY": "tr-Latn-CY", + "und-Latn-DZ": "fr-Latn-DZ", + "und-Latn-ET": "en-Latn-ET", + "und-Latn-GE": "ku-Latn-GE", + "und-Latn-IR": "tk-Latn-IR", + "und-Latn-KM": "fr-Latn-KM", + "und-Latn-MA": "fr-Latn-MA", + "und-Latn-MK": "sq-Latn-MK", + "und-Latn-MM": "kac-Latn-MM", + "und-Latn-MO": "pt-Latn-MO", + "und-Latn-MR": "fr-Latn-MR", + "und-Latn-RU": "krl-Latn-RU", + "und-Latn-SY": "fr-Latn-SY", + "und-Latn-TN": "fr-Latn-TN", + "und-Latn-TW": "trv-Latn-TW", + "und-Latn-UA": "pl-Latn-UA", + "und-LB": "ar-Arab-LB", + "und-Lepc": "lep-Lepc-IN", + "und-LI": "de-Latn-LI", + "und-Limb": "lif-Limb-IN", + "und-Lina": "lab-Lina-GR", + "und-Linb": "grc-Linb-GR", + "und-Lisu": "lis-Lisu-CN", + "und-LK": "si-Sinh-LK", + "und-LS": "st-Latn-LS", + "und-LT": "lt-Latn-LT", + "und-LU": "fr-Latn-LU", + "und-LV": "lv-Latn-LV", + "und-LY": "ar-Arab-LY", + "und-Lyci": "xlc-Lyci-TR", + "und-Lydi": "xld-Lydi-TR", + "und-MA": "ar-Arab-MA", + "und-Mahj": "hi-Mahj-IN", + "und-Maka": "mak-Maka-ID", + "und-Mand": "myz-Mand-IR", + "und-Mani": "xmn-Mani-CN", + "und-Marc": "bo-Marc-CN", + "und-MC": "fr-Latn-MC", + "und-MD": "ro-Latn-MD", + "und-ME": "sr-Latn-ME", + "und-Medf": "dmf-Medf-NG", + "und-Mend": "men-Mend-SL", + "und-Merc": "xmr-Merc-SD", + "und-Mero": "xmr-Mero-SD", + "und-MF": "fr-Latn-MF", + "und-MG": "mg-Latn-MG", + "und-MK": "mk-Cyrl-MK", + "und-ML": "bm-Latn-ML", + "und-Mlym": "ml-Mlym-IN", + "und-MM": "my-Mymr-MM", + "und-MN": "mn-Cyrl-MN", + "und-MO": "zh-Hant-MO", + "und-Modi": "mr-Modi-IN", + "und-Mong": "mn-Mong-CN", + "und-MQ": "fr-Latn-MQ", + "und-MR": "ar-Arab-MR", + "und-Mroo": "mro-Mroo-BD", + "und-MT": "mt-Latn-MT", + "und-Mtei": "mni-Mtei-IN", + "und-MU": "mfe-Latn-MU", + "und-Mult": "skr-Mult-PK", + "und-MV": "dv-Thaa-MV", + "und-MX": "es-Latn-MX", + "und-MY": "ms-Latn-MY", + "und-Mymr": "my-Mymr-MM", + "und-Mymr-IN": "kht-Mymr-IN", + "und-Mymr-TH": "mnw-Mymr-TH", + "und-MZ": "pt-Latn-MZ", + "und-NA": "af-Latn-NA", + "und-Nand": "sa-Nand-IN", + "und-Narb": "xna-Narb-SA", + "und-Nbat": "arc-Nbat-JO", + "und-NC": "fr-Latn-NC", + "und-NE": "ha-Latn-NE", + "und-Newa": "new-Newa-NP", + "und-NI": "es-Latn-NI", + "und-Nkoo": "man-Nkoo-GN", + "und-NL": "nl-Latn-NL", + "und-NO": "nb-Latn-NO", + "und-NP": "ne-Deva-NP", + "und-Nshu": "zhx-Nshu-CN", + "und-Ogam": "sga-Ogam-IE", + "und-Olck": "sat-Olck-IN", + "und-OM": "ar-Arab-OM", + "und-Orkh": "otk-Orkh-MN", + "und-Orya": "or-Orya-IN", + "und-Osge": "osa-Osge-US", + "und-Osma": "so-Osma-SO", + "und-Ougr": "oui-Ougr-143", + "und-PA": "es-Latn-PA", + "und-Palm": "arc-Palm-SY", + "und-Pauc": "ctd-Pauc-MM", + "und-PE": "es-Latn-PE", + "und-Perm": "kv-Perm-RU", + "und-PF": "fr-Latn-PF", + "und-PG": "tpi-Latn-PG", + "und-PH": "fil-Latn-PH", + "und-Phag": "lzh-Phag-CN", + "und-Phli": "pal-Phli-IR", + "und-Phlp": "pal-Phlp-CN", + "und-Phnx": "phn-Phnx-LB", + "und-PK": "ur-Arab-PK", + "und-PL": "pl-Latn-PL", + "und-Plrd": "hmd-Plrd-CN", + "und-PM": "fr-Latn-PM", + "und-PR": "es-Latn-PR", + "und-Prti": "xpr-Prti-IR", + "und-PS": "ar-Arab-PS", + "und-PT": "pt-Latn-PT", + "und-PW": "pau-Latn-PW", + "und-PY": "gn-Latn-PY", + "und-QA": "ar-Arab-QA", + "und-QO": "en-Latn-DG", + "und-RE": "fr-Latn-RE", + "und-Rjng": "rej-Rjng-ID", + "und-RO": "ro-Latn-RO", + "und-Rohg": "rhg-Rohg-MM", + "und-RS": "sr-Cyrl-RS", + "und-RU": "ru-Cyrl-RU", + "und-Runr": "non-Runr-SE", + "und-RW": "rw-Latn-RW", + "und-SA": "ar-Arab-SA", + "und-Samr": "smp-Samr-IL", + "und-Sarb": "xsa-Sarb-YE", + "und-Saur": "saz-Saur-IN", + "und-SC": "fr-Latn-SC", + "und-SD": "ar-Arab-SD", + "und-SE": "sv-Latn-SE", + "und-Sgnw": "ase-Sgnw-US", + "und-Shaw": "en-Shaw-GB", + "und-Shrd": "sa-Shrd-IN", + "und-SI": "sl-Latn-SI", + "und-Sidd": "sa-Sidd-IN", + "und-Sind": "sd-Sind-IN", + "und-Sinh": "si-Sinh-LK", + "und-SJ": "nb-Latn-SJ", + "und-SK": "sk-Latn-SK", + "und-SM": "it-Latn-SM", + "und-SN": "fr-Latn-SN", + "und-SO": "so-Latn-SO", + "und-Sogd": "sog-Sogd-UZ", + "und-Sogo": "sog-Sogo-UZ", + "und-Sora": "srb-Sora-IN", + "und-Soyo": "cmg-Soyo-MN", + "und-SR": "nl-Latn-SR", + "und-ST": "pt-Latn-ST", + "und-Sund": "su-Sund-ID", + "und-SV": "es-Latn-SV", + "und-SY": "ar-Arab-SY", + "und-Sylo": "syl-Sylo-BD", + "und-Syrc": "syr-Syrc-IQ", + "und-Tagb": "tbw-Tagb-PH", + "und-Takr": "doi-Takr-IN", + "und-Tale": "tdd-Tale-CN", + "und-Talu": "khb-Talu-CN", + "und-Taml": "ta-Taml-IN", + "und-Tang": "txg-Tang-CN", + "und-Tavt": "blt-Tavt-VN", + "und-TD": "fr-Latn-TD", + "und-Telu": "te-Telu-IN", + "und-TF": "fr-Latn-TF", + "und-Tfng": "zgh-Tfng-MA", + "und-TG": "fr-Latn-TG", + "und-Tglg": "fil-Tglg-PH", + "und-TH": "th-Thai-TH", + "und-Thaa": "dv-Thaa-MV", + "und-Thai": "th-Thai-TH", + "und-Thai-CN": "lcp-Thai-CN", + "und-Thai-KH": "kdt-Thai-KH", + "und-Thai-LA": "kdt-Thai-LA", + "und-Tibt": "bo-Tibt-CN", + "und-Tirh": "mai-Tirh-IN", + "und-TJ": "tg-Cyrl-TJ", + "und-TK": "tkl-Latn-TK", + "und-TL": "pt-Latn-TL", + "und-TM": "tk-Latn-TM", + "und-TN": "ar-Arab-TN", + "und-Tnsa": "nst-Tnsa-IN", + "und-TO": "to-Latn-TO", + "und-Toto": "txo-Toto-IN", + "und-TR": "tr-Latn-TR", + "und-TV": "tvl-Latn-TV", + "und-TW": "zh-Hant-TW", + "und-TZ": "sw-Latn-TZ", + "und-UA": "uk-Cyrl-UA", + "und-UG": "sw-Latn-UG", + "und-Ugar": "uga-Ugar-SY", + "und-UY": "es-Latn-UY", + "und-UZ": "uz-Latn-UZ", + "und-VA": "it-Latn-VA", + "und-Vaii": "vai-Vaii-LR", + "und-VE": "es-Latn-VE", + "und-Vith": "sq-Vith-AL", + "und-VN": "vi-Latn-VN", + "und-VU": "bi-Latn-VU", + "und-Wara": "hoc-Wara-IN", + "und-Wcho": "nnp-Wcho-IN", + "und-WF": "fr-Latn-WF", + "und-WS": "sm-Latn-WS", + "und-XK": "sq-Latn-XK", + "und-Xpeo": "peo-Xpeo-IR", + "und-Xsux": "akk-Xsux-IQ", + "und-YE": "ar-Arab-YE", + "und-Yezi": "ku-Yezi-GE", + "und-Yiii": "ii-Yiii-CN", + "und-YT": "fr-Latn-YT", + "und-Zanb": "cmg-Zanb-MN", + "und-ZW": "sn-Latn-ZW", + "unr": "unr-Beng-IN", + "unr-Deva": "unr-Deva-NP", + "unr-NP": "unr-Deva-NP", + "unx": "unx-Beng-IN", + "uok": "uok-Latn-ZZ", + "ur": "ur-Arab-PK", + "uri": "uri-Latn-ZZ", + "urt": "urt-Latn-ZZ", + "urw": "urw-Latn-ZZ", + "usa": "usa-Latn-ZZ", + "uth": "uth-Latn-ZZ", + "utr": "utr-Latn-ZZ", + "uvh": "uvh-Latn-ZZ", + "uvl": "uvl-Latn-ZZ", + "uz": "uz-Latn-UZ", + "uz-AF": "uz-Arab-AF", + "uz-Arab": "uz-Arab-AF", + "uz-CN": "uz-Cyrl-CN", + "vag": "vag-Latn-ZZ", + "vai": "vai-Vaii-LR", + "van": "van-Latn-ZZ", + "ve": "ve-Latn-ZA", + "vec": "vec-Latn-IT", + "vep": "vep-Latn-RU", + "vi": "vi-Latn-VN", + "vic": "vic-Latn-SX", + "viv": "viv-Latn-ZZ", + "vls": "vls-Latn-BE", + "vmf": "vmf-Latn-DE", + "vmw": "vmw-Latn-MZ", + "vo": "vo-Latn-001", + "vot": "vot-Latn-RU", + "vro": "vro-Latn-EE", + "vun": "vun-Latn-TZ", + "vut": "vut-Latn-ZZ", + "wa": "wa-Latn-BE", + "wae": "wae-Latn-CH", + "waj": "waj-Latn-ZZ", + "wal": "wal-Ethi-ET", + "wan": "wan-Latn-ZZ", + "war": "war-Latn-PH", + "wbp": "wbp-Latn-AU", + "wbq": "wbq-Telu-IN", + "wbr": "wbr-Deva-IN", + "wci": "wci-Latn-ZZ", + "wer": "wer-Latn-ZZ", + "wgi": "wgi-Latn-ZZ", + "whg": "whg-Latn-ZZ", + "wib": "wib-Latn-ZZ", + "wiu": "wiu-Latn-ZZ", + "wiv": "wiv-Latn-ZZ", + "wja": "wja-Latn-ZZ", + "wji": "wji-Latn-ZZ", + "wls": "wls-Latn-WF", + "wmo": "wmo-Latn-ZZ", + "wnc": "wnc-Latn-ZZ", + "wni": "wni-Arab-KM", + "wnu": "wnu-Latn-ZZ", + "wo": "wo-Latn-SN", + "wob": "wob-Latn-ZZ", + "wos": "wos-Latn-ZZ", + "wrs": "wrs-Latn-ZZ", + "wsg": "wsg-Gong-IN", + "wsk": "wsk-Latn-ZZ", + "wtm": "wtm-Deva-IN", + "wuu": "wuu-Hans-CN", + "wuv": "wuv-Latn-ZZ", + "wwa": "wwa-Latn-ZZ", + "xav": "xav-Latn-BR", + "xbi": "xbi-Latn-ZZ", + "xco": "xco-Chrs-UZ", + "xcr": "xcr-Cari-TR", + "xes": "xes-Latn-ZZ", + "xh": "xh-Latn-ZA", + "xla": "xla-Latn-ZZ", + "xlc": "xlc-Lyci-TR", + "xld": "xld-Lydi-TR", + "xmf": "xmf-Geor-GE", + "xmn": "xmn-Mani-CN", + "xmr": "xmr-Merc-SD", + "xna": "xna-Narb-SA", + "xnr": "xnr-Deva-IN", + "xog": "xog-Latn-UG", + "xon": "xon-Latn-ZZ", + "xpr": "xpr-Prti-IR", + "xrb": "xrb-Latn-ZZ", + "xsa": "xsa-Sarb-YE", + "xsi": "xsi-Latn-ZZ", + "xsm": "xsm-Latn-ZZ", + "xsr": "xsr-Deva-NP", + "xwe": "xwe-Latn-ZZ", + "yam": "yam-Latn-ZZ", + "yao": "yao-Latn-MZ", + "yap": "yap-Latn-FM", + "yas": "yas-Latn-ZZ", + "yat": "yat-Latn-ZZ", + "yav": "yav-Latn-CM", + "yay": "yay-Latn-ZZ", + "yaz": "yaz-Latn-ZZ", + "yba": "yba-Latn-ZZ", + "ybb": "ybb-Latn-CM", + "yby": "yby-Latn-ZZ", + "yer": "yer-Latn-ZZ", + "ygr": "ygr-Latn-ZZ", + "ygw": "ygw-Latn-ZZ", + "yi": "yi-Hebr-001", + "yko": "yko-Latn-ZZ", + "yle": "yle-Latn-ZZ", + "ylg": "ylg-Latn-ZZ", + "yll": "yll-Latn-ZZ", + "yml": "yml-Latn-ZZ", + "yo": "yo-Latn-NG", + "yon": "yon-Latn-ZZ", + "yrb": "yrb-Latn-ZZ", + "yre": "yre-Latn-ZZ", + "yrl": "yrl-Latn-BR", + "yss": "yss-Latn-ZZ", + "yua": "yua-Latn-MX", + "yue": "yue-Hant-HK", + "yue-CN": "yue-Hans-CN", + "yue-Hans": "yue-Hans-CN", + "yuj": "yuj-Latn-ZZ", + "yut": "yut-Latn-ZZ", + "yuw": "yuw-Latn-ZZ", + "za": "za-Latn-CN", + "zag": "zag-Latn-SD", + "zdj": "zdj-Arab-KM", + "zea": "zea-Latn-NL", + "zgh": "zgh-Tfng-MA", + "zh": "zh-Hans-CN", + "zh-AU": "zh-Hant-AU", + "zh-BN": "zh-Hant-BN", + "zh-Bopo": "zh-Bopo-TW", + "zh-GB": "zh-Hant-GB", + "zh-GF": "zh-Hant-GF", + "zh-Hanb": "zh-Hanb-TW", + "zh-Hant": "zh-Hant-TW", + "zh-HK": "zh-Hant-HK", + "zh-ID": "zh-Hant-ID", + "zh-MO": "zh-Hant-MO", + "zh-PA": "zh-Hant-PA", + "zh-PF": "zh-Hant-PF", + "zh-PH": "zh-Hant-PH", + "zh-SR": "zh-Hant-SR", + "zh-TH": "zh-Hant-TH", + "zh-TW": "zh-Hant-TW", + "zh-US": "zh-Hant-US", + "zh-VN": "zh-Hant-VN", + "zhx": "zhx-Nshu-CN", + "zia": "zia-Latn-ZZ", + "zkt": "zkt-Kits-CN", + "zlm": "zlm-Latn-TG", + "zmi": "zmi-Latn-MY", + "zne": "zne-Latn-ZZ", + "zu": "zu-Latn-ZA", + "zza": "zza-Latn-TR" + }; + } + }); + + // node_modules/@formatjs/intl-getcanonicallocales/src/canonicalizer.js + var require_canonicalizer = __commonJS({ + "node_modules/@formatjs/intl-getcanonicallocales/src/canonicalizer.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.canonicalizeUnicodeLocaleId = exports.canonicalizeUnicodeLanguageId = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var aliases_generated_1 = require_aliases_generated(); + var parser_1 = require_parser(); + var likelySubtags_generated_1 = require_likelySubtags_generated(); + var emitter_1 = require_emitter(); + function canonicalizeAttrs(strs) { + return Object.keys(strs.reduce(function(all, str) { + all[str.toLowerCase()] = 1; + return all; + }, {})).sort(); + } + function canonicalizeKVs(arr) { + var all = {}; + var result = []; + for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) { + var kv = arr_1[_i]; + if (kv[0] in all) { + continue; + } + all[kv[0]] = 1; + if (!kv[1] || kv[1] === "true") { + result.push([kv[0].toLowerCase()]); + } else { + result.push([kv[0].toLowerCase(), kv[1].toLowerCase()]); + } + } + return result.sort(compareKV); + } + function compareKV(t1, t2) { + return t1[0] < t2[0] ? -1 : t1[0] > t2[0] ? 1 : 0; + } + function compareExtension(e1, e2) { + return e1.type < e2.type ? -1 : e1.type > e2.type ? 1 : 0; + } + function mergeVariants(v1, v2) { + var result = tslib_1.__spreadArray([], v1, true); + for (var _i = 0, v2_1 = v2; _i < v2_1.length; _i++) { + var v = v2_1[_i]; + if (v1.indexOf(v) < 0) { + result.push(v); + } + } + return result; + } + function canonicalizeUnicodeLanguageId(unicodeLanguageId) { + var finalLangAst = unicodeLanguageId; + if (unicodeLanguageId.variants.length) { + var replacedLang_1 = ""; + for (var _i = 0, _a = unicodeLanguageId.variants; _i < _a.length; _i++) { + var variant = _a[_i]; + if (replacedLang_1 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ + lang: unicodeLanguageId.lang, + variants: [variant] + })]) { + var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_1.split(parser_1.SEPARATOR)); + finalLangAst = { + lang: replacedLangAst.lang, + script: finalLangAst.script || replacedLangAst.script, + region: finalLangAst.region || replacedLangAst.region, + variants: mergeVariants(finalLangAst.variants, replacedLangAst.variants) + }; + break; + } + } + } + if (finalLangAst.script && finalLangAst.region) { + var replacedLang_2 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ + lang: finalLangAst.lang, + script: finalLangAst.script, + region: finalLangAst.region, + variants: [] + })]; + if (replacedLang_2) { + var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_2.split(parser_1.SEPARATOR)); + finalLangAst = { + lang: replacedLangAst.lang, + script: replacedLangAst.script, + region: replacedLangAst.region, + variants: finalLangAst.variants + }; + } + } + if (finalLangAst.region) { + var replacedLang_3 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ + lang: finalLangAst.lang, + region: finalLangAst.region, + variants: [] + })]; + if (replacedLang_3) { + var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_3.split(parser_1.SEPARATOR)); + finalLangAst = { + lang: replacedLangAst.lang, + script: finalLangAst.script || replacedLangAst.script, + region: replacedLangAst.region, + variants: finalLangAst.variants + }; + } + } + var replacedLang = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ + lang: finalLangAst.lang, + variants: [] + })]; + if (replacedLang) { + var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang.split(parser_1.SEPARATOR)); + finalLangAst = { + lang: replacedLangAst.lang, + script: finalLangAst.script || replacedLangAst.script, + region: finalLangAst.region || replacedLangAst.region, + variants: finalLangAst.variants + }; + } + if (finalLangAst.region) { + var region = finalLangAst.region.toUpperCase(); + var regionAlias = aliases_generated_1.territoryAlias[region]; + var replacedRegion = void 0; + if (regionAlias) { + var regions = regionAlias.split(" "); + replacedRegion = regions[0]; + var likelySubtag = likelySubtags_generated_1.likelySubtags[(0, emitter_1.emitUnicodeLanguageId)({ + lang: finalLangAst.lang, + script: finalLangAst.script, + variants: [] + })]; + if (likelySubtag) { + var likelyRegion = (0, parser_1.parseUnicodeLanguageId)(likelySubtag.split(parser_1.SEPARATOR)).region; + if (likelyRegion && regions.indexOf(likelyRegion) > -1) { + replacedRegion = likelyRegion; + } + } + } + if (replacedRegion) { + finalLangAst.region = replacedRegion; + } + finalLangAst.region = finalLangAst.region.toUpperCase(); + } + if (finalLangAst.script) { + finalLangAst.script = finalLangAst.script[0].toUpperCase() + finalLangAst.script.slice(1).toLowerCase(); + if (aliases_generated_1.scriptAlias[finalLangAst.script]) { + finalLangAst.script = aliases_generated_1.scriptAlias[finalLangAst.script]; + } + } + if (finalLangAst.variants.length) { + for (var i = 0; i < finalLangAst.variants.length; i++) { + var variant = finalLangAst.variants[i].toLowerCase(); + if (aliases_generated_1.variantAlias[variant]) { + var alias = aliases_generated_1.variantAlias[variant]; + if ((0, parser_1.isUnicodeVariantSubtag)(alias)) { + finalLangAst.variants[i] = alias; + } else if ((0, parser_1.isUnicodeLanguageSubtag)(alias)) { + finalLangAst.lang = alias; + } + } + } + finalLangAst.variants.sort(); + } + return finalLangAst; + } + exports.canonicalizeUnicodeLanguageId = canonicalizeUnicodeLanguageId; + function canonicalizeUnicodeLocaleId(locale) { + locale.lang = canonicalizeUnicodeLanguageId(locale.lang); + if (locale.extensions) { + for (var _i = 0, _a = locale.extensions; _i < _a.length; _i++) { + var extension = _a[_i]; + switch (extension.type) { + case "u": + extension.keywords = canonicalizeKVs(extension.keywords); + if (extension.attributes) { + extension.attributes = canonicalizeAttrs(extension.attributes); + } + break; + case "t": + if (extension.lang) { + extension.lang = canonicalizeUnicodeLanguageId(extension.lang); + } + extension.fields = canonicalizeKVs(extension.fields); + break; + default: + extension.value = extension.value.toLowerCase(); + break; + } + } + locale.extensions.sort(compareExtension); + } + return locale; + } + exports.canonicalizeUnicodeLocaleId = canonicalizeUnicodeLocaleId; + } + }); + + // node_modules/@formatjs/intl-getcanonicallocales/src/types.js + var require_types = __commonJS({ + "node_modules/@formatjs/intl-getcanonicallocales/src/types.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + } + }); + + // node_modules/@formatjs/intl-getcanonicallocales/index.js + var require_intl_getcanonicallocales = __commonJS({ + "node_modules/@formatjs/intl-getcanonicallocales/index.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.isUnicodeLanguageSubtag = exports.isUnicodeScriptSubtag = exports.isUnicodeRegionSubtag = exports.isStructurallyValidLanguageTag = exports.parseUnicodeLanguageId = exports.parseUnicodeLocaleId = exports.getCanonicalLocales = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var parser_1 = require_parser(); + var emitter_1 = require_emitter(); + var canonicalizer_1 = require_canonicalizer(); + function CanonicalizeLocaleList(locales) { + if (locales === void 0) { + return []; + } + var seen = []; + if (typeof locales === "string") { + locales = [locales]; + } + for (var _i = 0, locales_1 = locales; _i < locales_1.length; _i++) { + var locale = locales_1[_i]; + var canonicalizedTag = (0, emitter_1.emitUnicodeLocaleId)((0, canonicalizer_1.canonicalizeUnicodeLocaleId)((0, parser_1.parseUnicodeLocaleId)(locale))); + if (seen.indexOf(canonicalizedTag) < 0) { + seen.push(canonicalizedTag); + } + } + return seen; + } + function getCanonicalLocales(locales) { + return CanonicalizeLocaleList(locales); + } + exports.getCanonicalLocales = getCanonicalLocales; + var parser_2 = require_parser(); + Object.defineProperty(exports, "parseUnicodeLocaleId", { enumerable: true, get: function() { + return parser_2.parseUnicodeLocaleId; + } }); + Object.defineProperty(exports, "parseUnicodeLanguageId", { enumerable: true, get: function() { + return parser_2.parseUnicodeLanguageId; + } }); + Object.defineProperty(exports, "isStructurallyValidLanguageTag", { enumerable: true, get: function() { + return parser_2.isStructurallyValidLanguageTag; + } }); + Object.defineProperty(exports, "isUnicodeRegionSubtag", { enumerable: true, get: function() { + return parser_2.isUnicodeRegionSubtag; + } }); + Object.defineProperty(exports, "isUnicodeScriptSubtag", { enumerable: true, get: function() { + return parser_2.isUnicodeScriptSubtag; + } }); + Object.defineProperty(exports, "isUnicodeLanguageSubtag", { enumerable: true, get: function() { + return parser_2.isUnicodeLanguageSubtag; + } }); + tslib_1.__exportStar(require_types(), exports); + tslib_1.__exportStar(require_emitter(), exports); + tslib_1.__exportStar(require_likelySubtags_generated(), exports); + } + }); + + // node_modules/@formatjs/intl-locale/get_internal_slots.js + var require_get_internal_slots = __commonJS({ + "node_modules/@formatjs/intl-locale/get_internal_slots.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var internalSlotMap = /* @__PURE__ */ new WeakMap(); + function getInternalSlots(x) { + var internalSlots = internalSlotMap.get(x); + if (!internalSlots) { + internalSlots = /* @__PURE__ */ Object.create(null); + internalSlotMap.set(x, internalSlots); + } + return internalSlots; + } + exports.default = getInternalSlots; + } + }); + + // node_modules/@formatjs/intl-locale/index.js + var require_intl_locale = __commonJS({ + "node_modules/@formatjs/intl-locale/index.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.Locale = void 0; + var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); + var ecma402_abstract_1 = require_ecma402_abstract(); + var intl_getcanonicallocales_1 = require_intl_getcanonicallocales(); + var get_internal_slots_1 = tslib_1.__importDefault(require_get_internal_slots()); + var RELEVANT_EXTENSION_KEYS = ["ca", "co", "hc", "kf", "kn", "nu"]; + var UNICODE_TYPE_REGEX = /^[a-z0-9]{3,8}(-[a-z0-9]{3,8})*$/i; + function applyOptionsToTag(tag, options) { + (0, ecma402_abstract_1.invariant)(typeof tag === "string", "language tag must be a string"); + (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isStructurallyValidLanguageTag)(tag), "malformed language tag", RangeError); + var language = (0, ecma402_abstract_1.GetOption)(options, "language", "string", void 0, void 0); + if (language !== void 0) { + (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeLanguageSubtag)(language), "Malformed unicode_language_subtag", RangeError); + } + var script = (0, ecma402_abstract_1.GetOption)(options, "script", "string", void 0, void 0); + if (script !== void 0) { + (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeScriptSubtag)(script), "Malformed unicode_script_subtag", RangeError); + } + var region = (0, ecma402_abstract_1.GetOption)(options, "region", "string", void 0, void 0); + if (region !== void 0) { + (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeRegionSubtag)(region), "Malformed unicode_region_subtag", RangeError); + } + var languageId = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(tag); + if (language !== void 0) { + languageId.lang = language; + } + if (script !== void 0) { + languageId.script = script; + } + if (region !== void 0) { + languageId.region = region; + } + return Intl.getCanonicalLocales((0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag)), { lang: languageId })))[0]; + } + function applyUnicodeExtensionToTag(tag, options, relevantExtensionKeys) { + var unicodeExtension; + var keywords = []; + var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); + for (var _i = 0, _a = ast.extensions; _i < _a.length; _i++) { + var ext = _a[_i]; + if (ext.type === "u") { + unicodeExtension = ext; + if (Array.isArray(ext.keywords)) + keywords = ext.keywords; + } + } + var result = /* @__PURE__ */ Object.create(null); + for (var _b = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _b < relevantExtensionKeys_1.length; _b++) { + var key = relevantExtensionKeys_1[_b]; + var value = void 0, entry = void 0; + for (var _c = 0, keywords_1 = keywords; _c < keywords_1.length; _c++) { + var keyword = keywords_1[_c]; + if (keyword[0] === key) { + entry = keyword; + value = entry[1]; + } + } + (0, ecma402_abstract_1.invariant)(key in options, "".concat(key, " must be in options")); + var optionsValue = options[key]; + if (optionsValue !== void 0) { + (0, ecma402_abstract_1.invariant)(typeof optionsValue === "string", "Value for ".concat(key, " must be a string")); + value = optionsValue; + if (entry) { + entry[1] = value; + } else { + keywords.push([key, value]); + } + } + result[key] = value; + } + if (!unicodeExtension) { + if (keywords.length) { + ast.extensions.push({ + type: "u", + keywords, + attributes: [] + }); + } + } else { + unicodeExtension.keywords = keywords; + } + result.locale = Intl.getCanonicalLocales((0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast))[0]; + return result; + } + function mergeUnicodeLanguageId(lang, script, region, variants, replacement) { + if (variants === void 0) { + variants = []; + } + if (!replacement) { + return { + lang: lang || "und", + script, + region, + variants + }; + } + return { + lang: !lang || lang === "und" ? replacement.lang : lang, + script: script || replacement.script, + region: region || replacement.region, + variants: tslib_1.__spreadArray(tslib_1.__spreadArray([], variants, true), replacement.variants, true) + }; + } + function addLikelySubtags(tag) { + var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); + var unicodeLangId = ast.lang; + var lang = unicodeLangId.lang, script = unicodeLangId.script, region = unicodeLangId.region, variants = unicodeLangId.variants; + if (script && region) { + var match_1 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, region, variants: [] })]; + if (match_1) { + var parts_1 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_1); + ast.lang = mergeUnicodeLanguageId(void 0, void 0, void 0, variants, parts_1); + return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); + } + } + if (script) { + var match_2 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, variants: [] })]; + if (match_2) { + var parts_2 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_2); + ast.lang = mergeUnicodeLanguageId(void 0, void 0, region, variants, parts_2); + return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); + } + } + if (region) { + var match_3 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, region, variants: [] })]; + if (match_3) { + var parts_3 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_3); + ast.lang = mergeUnicodeLanguageId(void 0, script, void 0, variants, parts_3); + return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); + } + } + var match = intl_getcanonicallocales_1.likelySubtags[lang] || intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang: "und", script, variants: [] })]; + if (!match) { + throw new Error("No match for addLikelySubtags"); + } + var parts = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match); + ast.lang = mergeUnicodeLanguageId(void 0, script, region, variants, parts); + return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); + } + function removeLikelySubtags(tag) { + var maxLocale = addLikelySubtags(tag); + if (!maxLocale) { + return tag; + } + maxLocale = (0, intl_getcanonicallocales_1.emitUnicodeLanguageId)(tslib_1.__assign(tslib_1.__assign({}, (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(maxLocale)), { variants: [] })); + var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); + var _a = ast.lang, lang = _a.lang, script = _a.script, region = _a.region, variants = _a.variants; + var trial = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, variants: [] })); + if (trial === maxLocale) { + return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, void 0, void 0, variants) })); + } + if (region) { + var trial_1 = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, region, variants: [] })); + if (trial_1 === maxLocale) { + return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, void 0, region, variants) })); + } + } + if (script) { + var trial_2 = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, variants: [] })); + if (trial_2 === maxLocale) { + return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, script, void 0, variants) })); + } + } + return tag; + } + var Locale = ( + /** @class */ + function() { + function Locale2(tag, opts) { + var newTarget = this && this instanceof Locale2 ? this.constructor : void 0; + if (!newTarget) { + throw new TypeError("Intl.Locale must be called with 'new'"); + } + var relevantExtensionKeys = Locale2.relevantExtensionKeys; + var internalSlotsList = [ + "initializedLocale", + "locale", + "calendar", + "collation", + "hourCycle", + "numberingSystem" + ]; + if (relevantExtensionKeys.indexOf("kf") > -1) { + internalSlotsList.push("caseFirst"); + } + if (relevantExtensionKeys.indexOf("kn") > -1) { + internalSlotsList.push("numeric"); + } + if (tag === void 0) { + throw new TypeError("First argument to Intl.Locale constructor can't be empty or missing"); + } + if (typeof tag !== "string" && typeof tag !== "object") { + throw new TypeError("tag must be a string or object"); + } + var internalSlots; + if (typeof tag === "object" && (internalSlots = (0, get_internal_slots_1.default)(tag)) && internalSlots.initializedLocale) { + tag = internalSlots.locale; + } else { + tag = tag.toString(); + } + internalSlots = (0, get_internal_slots_1.default)(this); + var options = (0, ecma402_abstract_1.CoerceOptionsToObject)(opts); + tag = applyOptionsToTag(tag, options); + var opt = /* @__PURE__ */ Object.create(null); + var calendar = (0, ecma402_abstract_1.GetOption)(options, "calendar", "string", void 0, void 0); + if (calendar !== void 0) { + if (!UNICODE_TYPE_REGEX.test(calendar)) { + throw new RangeError("invalid calendar"); + } + } + opt.ca = calendar; + var collation = (0, ecma402_abstract_1.GetOption)(options, "collation", "string", void 0, void 0); + if (collation !== void 0) { + if (!UNICODE_TYPE_REGEX.test(collation)) { + throw new RangeError("invalid collation"); + } + } + opt.co = collation; + var hc = (0, ecma402_abstract_1.GetOption)(options, "hourCycle", "string", ["h11", "h12", "h23", "h24"], void 0); + opt.hc = hc; + var kf = (0, ecma402_abstract_1.GetOption)(options, "caseFirst", "string", ["upper", "lower", "false"], void 0); + opt.kf = kf; + var _kn = (0, ecma402_abstract_1.GetOption)(options, "numeric", "boolean", void 0, void 0); + var kn; + if (_kn !== void 0) { + kn = String(_kn); + } + opt.kn = kn; + var numberingSystem = (0, ecma402_abstract_1.GetOption)(options, "numberingSystem", "string", void 0, void 0); + if (numberingSystem !== void 0) { + if (!UNICODE_TYPE_REGEX.test(numberingSystem)) { + throw new RangeError("Invalid numberingSystem"); + } + } + opt.nu = numberingSystem; + var r = applyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys); + internalSlots.locale = r.locale; + internalSlots.calendar = r.ca; + internalSlots.collation = r.co; + internalSlots.hourCycle = r.hc; + if (relevantExtensionKeys.indexOf("kf") > -1) { + internalSlots.caseFirst = r.kf; + } + if (relevantExtensionKeys.indexOf("kn") > -1) { + internalSlots.numeric = (0, ecma402_abstract_1.SameValue)(r.kn, "true"); + } + internalSlots.numberingSystem = r.nu; + } + Locale2.prototype.maximize = function() { + var locale = (0, get_internal_slots_1.default)(this).locale; + try { + var maximizedLocale = addLikelySubtags(locale); + return new Locale2(maximizedLocale); + } catch (e) { + return new Locale2(locale); + } + }; + Locale2.prototype.minimize = function() { + var locale = (0, get_internal_slots_1.default)(this).locale; + try { + var minimizedLocale = removeLikelySubtags(locale); + return new Locale2(minimizedLocale); + } catch (e) { + return new Locale2(locale); + } + }; + Locale2.prototype.toString = function() { + return (0, get_internal_slots_1.default)(this).locale; + }; + Object.defineProperty(Locale2.prototype, "baseName", { + get: function() { + var locale = (0, get_internal_slots_1.default)(this).locale; + return (0, intl_getcanonicallocales_1.emitUnicodeLanguageId)((0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale)); + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "calendar", { + get: function() { + return (0, get_internal_slots_1.default)(this).calendar; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "collation", { + get: function() { + return (0, get_internal_slots_1.default)(this).collation; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "hourCycle", { + get: function() { + return (0, get_internal_slots_1.default)(this).hourCycle; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "caseFirst", { + get: function() { + return (0, get_internal_slots_1.default)(this).caseFirst; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "numeric", { + get: function() { + return (0, get_internal_slots_1.default)(this).numeric; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "numberingSystem", { + get: function() { + return (0, get_internal_slots_1.default)(this).numberingSystem; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "language", { + /** + * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.language + */ + get: function() { + var locale = (0, get_internal_slots_1.default)(this).locale; + return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).lang; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "script", { + /** + * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.script + */ + get: function() { + var locale = (0, get_internal_slots_1.default)(this).locale; + return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).script; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Locale2.prototype, "region", { + /** + * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.region + */ + get: function() { + var locale = (0, get_internal_slots_1.default)(this).locale; + return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).region; + }, + enumerable: false, + configurable: true + }); + Locale2.relevantExtensionKeys = RELEVANT_EXTENSION_KEYS; + return Locale2; + }() + ); + exports.Locale = Locale; + try { + if (typeof Symbol !== "undefined") { + Object.defineProperty(Locale.prototype, Symbol.toStringTag, { + value: "Intl.Locale", + writable: false, + enumerable: false, + configurable: true + }); + } + Object.defineProperty(Locale.prototype.constructor, "length", { + value: 1, + writable: false, + enumerable: false, + configurable: true + }); + } catch (e) { + } + exports.default = Locale; + } + }); + + // node_modules/@formatjs/intl-locale/should-polyfill.js + var require_should_polyfill = __commonJS({ + "node_modules/@formatjs/intl-locale/should-polyfill.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + exports.shouldPolyfill = void 0; + function hasIntlGetCanonicalLocalesBug() { + try { + return new Intl.Locale("und-x-private").toString() === "x-private"; + } catch (e) { + return true; + } + } + function shouldPolyfill() { + return !("Locale" in Intl) || hasIntlGetCanonicalLocalesBug(); + } + exports.shouldPolyfill = shouldPolyfill; + } + }); + + // node_modules/@formatjs/intl-locale/polyfill.js + var require_polyfill = __commonJS({ + "node_modules/@formatjs/intl-locale/polyfill.js"(exports) { + "use strict"; + Object.defineProperty(exports, "__esModule", { value: true }); + var _1 = require_intl_locale(); + var should_polyfill_1 = require_should_polyfill(); + if ((0, should_polyfill_1.shouldPolyfill)()) { + Object.defineProperty(Intl, "Locale", { + value: _1.Locale, + writable: true, + enumerable: false, + configurable: true + }); + } + } + }); + + // shared/js/polyfill.js + var import_polyfill = __toESM(require_polyfill()); +})(); diff --git a/package-lock.json b/package-lock.json index 3dbb4812b8bc..808ba7c07941 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "@duckduckgo/autoconsent": "^12.3.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", - "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", + "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.1", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" }, "devDependencies": { @@ -76,7 +76,7 @@ } }, "node_modules/@duckduckgo/privacy-dashboard": { - "resolved": "git+ssh://git@github.com/duckduckgo/privacy-dashboard.git#e1ec13370ac302307e7d5cb172f45106da911c9e", + "resolved": "git+ssh://git@github.com/duckduckgo/privacy-dashboard.git#440ded715fe44d34e4c352d61c783d64835fac92", "engines": { "node": ">=22.0.0", "npm": ">=9.0.0" diff --git a/package.json b/package.json index 82ee56ef9cc0..9f531394a0c7 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@duckduckgo/autoconsent": "^12.3.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", - "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", + "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.1", "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" } } From 38fc930518533dd8ff489929efc2fb588077f9fb Mon Sep 17 00:00:00 2001 From: Noelia Alcala Date: Sat, 21 Dec 2024 01:53:54 +0000 Subject: [PATCH 25/32] Privacy Pro Subscriptions: Update some internal models and methods (#5402) Task/Issue URL: https://app.asana.com/0/1201807753394693/1209007672205184/f ### Description Update some subscriptions models in order to support free trials on mobile: - `SubscriptionOffer` model - `OptionsJson` model - `getSubscriptionOffer()` method ### Steps to test this PR _Pre steps_ - [x] Apply patch to being able to test subscriptions in staging _Privacy Pro Eligible US_ - [x] Make sure you are US eligible - [x] Install form branch - [x] Check browser works as expected - [x] Go to Settings - [x] Check you can see Privacy Pro option - [x] Tap on that option - [x] Check Subscription page looks as expected - [x] Purchase any of the options and check it works well - [x] Go to Subscription Settings - [x] Check everything works as expected _Privacy Pro Eligible ROW (Optional)_ - [x] Make sure you are ROW eligible - [x] Install form branch - [x] Check browser works as expected - [x] Go to Settings - [x] Check you can see Privacy Pro option - [x] Tap on that option - [x] Check Subscription page looks as expected - [x] Purchase any of the options and check it works well - [x] Go to Subscription Settings - [x] Check everything works as expected _Privacy Pro No Eligible_ - [x] Install form branch - [x] Check browser works as expected - [x] Go to Settings - [x] Check you can't see Privacy Pro option ### No UI changes Co-authored-by: Lukasz Macionczyk --- .../subscriptions/impl/RealSubscriptions.kt | 2 +- .../impl/SubscriptionsConstants.kt | 4 + .../impl/SubscriptionsManager.kt | 86 ++++++++----- .../views/LegacyProSettingViewModel.kt | 9 +- .../settings/views/ProSettingViewModel.kt | 9 +- .../impl/ui/SubscriptionWebViewViewModel.kt | 119 ++++++++++++++---- .../impl/RealSubscriptionsManagerTest.kt | 66 ++++++---- .../impl/RealSubscriptionsTest.kt | 68 +++------- .../views/LegacyProSettingViewModelTest.kt | 1 + .../settings/views/ProSettingViewModelTest.kt | 1 + .../ui/SubscriptionWebViewViewModelTest.kt | 45 ++++--- 11 files changed, 258 insertions(+), 152 deletions(-) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/RealSubscriptions.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/RealSubscriptions.kt index 4b62a7aa5f2c..fbd17b79bd1f 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/RealSubscriptions.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/RealSubscriptions.kt @@ -77,7 +77,7 @@ class RealSubscriptions @Inject constructor( override suspend fun isEligible(): Boolean { val supportsEncryption = subscriptionsManager.canSupportEncryption() val isActive = subscriptionsManager.subscriptionStatus().isActiveOrWaiting() - val isEligible = subscriptionsManager.getSubscriptionOffer() != null + val isEligible = subscriptionsManager.getSubscriptionOffer().isNotEmpty() return isActive || (isEligible && supportsEncryption) } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt index c1ffcb942bf7..252d093aca5c 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsConstants.kt @@ -33,6 +33,10 @@ object SubscriptionsConstants { const val YEARLY_PLAN_ROW = "ddg-privacy-pro-yearly-renews-row" const val MONTHLY_PLAN_ROW = "ddg-privacy-pro-monthly-renews-row" + // List of offers + const val MONTHLY_FREE_TRIAL_OFFER_US = "ddg-privacy-pro-sandbox-freetrial-monthly-renews-us" + const val YEARLY_FREE_TRIAL_OFFER_US = "ddg-privacy-pro-sandbox-freetrial-yearly-renews-us" + // List of features const val LEGACY_FE_NETP = "vpn" const val LEGACY_FE_ITR = "identity-theft-restoration" diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsManager.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsManager.kt index 35003f189f75..5128b240e557 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsManager.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/SubscriptionsManager.kt @@ -100,7 +100,7 @@ interface SubscriptionsManager { /** * Returns available purchase options retrieved from Play Store */ - suspend fun getSubscriptionOffer(): SubscriptionOffer? + suspend fun getSubscriptionOffer(): List /** * Launches the purchase flow for a given plan id @@ -309,6 +309,7 @@ class RealSubscriptionsManager @Inject constructor( removeExpiredSubscriptionOnCancelledPurchase = false } } + else -> { // NOOP } @@ -612,6 +613,7 @@ class RealSubscriptionsManager @Inject constructor( RecoverSubscriptionResult.Failure(SUBSCRIPTION_NOT_FOUND_ERROR) } } + is StoreLoginResult.Failure -> { RecoverSubscriptionResult.Failure("") } @@ -653,43 +655,48 @@ class RealSubscriptionsManager @Inject constructor( data class Failure(val message: String) : RecoverSubscriptionResult() } - override suspend fun getSubscriptionOffer(): SubscriptionOffer? = + private suspend fun activePlanIds(): List = + if (isLaunchedRow()) { + listOf(YEARLY_PLAN_US, MONTHLY_PLAN_US, YEARLY_PLAN_ROW, MONTHLY_PLAN_ROW) + } else { + listOf(YEARLY_PLAN_US, MONTHLY_PLAN_US) + } + + override suspend fun getSubscriptionOffer(): List = playBillingManager.products .find { it.productId == BASIC_SUBSCRIPTION } ?.subscriptionOfferDetails .orEmpty() - .associateBy { it.basePlanId } + .filter { activePlanIds().contains(it.basePlanId) } .let { availablePlans -> - when { - availablePlans.keys.containsAll(listOf(MONTHLY_PLAN_US, YEARLY_PLAN_US)) -> { - availablePlans.getValue(MONTHLY_PLAN_US) to availablePlans.getValue(YEARLY_PLAN_US) - } - availablePlans.keys.containsAll(listOf(MONTHLY_PLAN_ROW, YEARLY_PLAN_ROW)) && isLaunchedRow() -> { - availablePlans.getValue(MONTHLY_PLAN_ROW) to availablePlans.getValue(YEARLY_PLAN_ROW) + availablePlans.map { offer -> + val pricingPhases = offer.pricingPhases.pricingPhaseList.map { phase -> + PricingPhase( + formattedPrice = phase.formattedPrice, + billingPeriod = phase.billingPeriod, + + ) } - else -> null - } - } - ?.let { (monthlyOffer, yearlyOffer) -> - val features = if (privacyProFeature.get().featuresApi().isEnabled()) { - authRepository.getFeatures(monthlyOffer.basePlanId) - } else { - when (monthlyOffer.basePlanId) { - MONTHLY_PLAN_US -> setOf(LEGACY_FE_NETP, LEGACY_FE_PIR, LEGACY_FE_ITR) - MONTHLY_PLAN_ROW -> setOf(NETP, ROW_ITR) - else -> throw IllegalStateException() + + val features = if (privacyProFeature.get().featuresApi().isEnabled()) { + authRepository.getFeatures(offer.basePlanId) + } else { + when (offer.basePlanId) { + MONTHLY_PLAN_US, YEARLY_PLAN_US -> setOf(LEGACY_FE_NETP, LEGACY_FE_PIR, LEGACY_FE_ITR) + MONTHLY_PLAN_ROW, YEARLY_PLAN_ROW -> setOf(NETP, ROW_ITR) + else -> throw IllegalStateException() + } } - } - if (features.isEmpty()) return@let null + if (features.isEmpty()) return@let emptyList() - SubscriptionOffer( - monthlyPlanId = monthlyOffer.basePlanId, - monthlyFormattedPrice = monthlyOffer.pricingPhases.pricingPhaseList.first().formattedPrice, - yearlyPlanId = yearlyOffer.basePlanId, - yearlyFormattedPrice = yearlyOffer.pricingPhases.pricingPhaseList.first().formattedPrice, - features = features, - ) + SubscriptionOffer( + planId = offer.basePlanId, + pricingPhases = pricingPhases, + offerId = offer.offerId, + features = features, + ) + } } override suspend fun purchase( @@ -945,13 +952,26 @@ sealed class CurrentPurchase { } data class SubscriptionOffer( - val monthlyPlanId: String, - val monthlyFormattedPrice: String, - val yearlyPlanId: String, - val yearlyFormattedPrice: String, + val planId: String, + val offerId: String?, + val pricingPhases: List, val features: Set, ) +data class PricingPhase( + val formattedPrice: String, + val billingPeriod: String, + +) { + internal fun getBillingPeriodInDays(): Int? = + when (billingPeriod) { + "P1W" -> 7 + "P1M" -> 30 + "P1Y" -> 365 + else -> null + } +} + data class ValidatedTokenPair( val accessToken: String, val accessTokenClaims: AccessTokenClaims, diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt index a824f85d7e50..42270ce6c622 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModel.kt @@ -27,6 +27,8 @@ import com.duckduckgo.subscriptions.api.SubscriptionStatus import com.duckduckgo.subscriptions.api.SubscriptionStatus.UNKNOWN import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_ROW import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_PLAN_ROW +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_PLAN_US import com.duckduckgo.subscriptions.impl.SubscriptionsManager import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingViewModel.Command.OpenBuyScreen @@ -88,9 +90,10 @@ class LegacyProSettingViewModel @Inject constructor( subscriptionsManager.subscriptionStatus .distinctUntilChanged() .onEach { subscriptionStatus -> - val region = when (subscriptionsManager.getSubscriptionOffer()?.monthlyPlanId) { - MONTHLY_PLAN_ROW -> SubscriptionRegion.ROW - MONTHLY_PLAN_US -> SubscriptionRegion.US + val offer = subscriptionsManager.getSubscriptionOffer().firstOrNull() + val region = when (offer?.planId) { + MONTHLY_PLAN_ROW, YEARLY_PLAN_ROW -> SubscriptionRegion.ROW + MONTHLY_PLAN_US, YEARLY_PLAN_US -> SubscriptionRegion.US else -> null } _viewState.emit(viewState.value.copy(status = subscriptionStatus, region = region)) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModel.kt index 40bed01b9209..4bcab0dd205a 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModel.kt @@ -27,6 +27,8 @@ import com.duckduckgo.subscriptions.api.SubscriptionStatus import com.duckduckgo.subscriptions.api.SubscriptionStatus.UNKNOWN import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_ROW import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_PLAN_ROW +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_PLAN_US import com.duckduckgo.subscriptions.impl.SubscriptionsManager import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.settings.views.ProSettingViewModel.Command.OpenBuyScreen @@ -88,9 +90,10 @@ class ProSettingViewModel @Inject constructor( subscriptionsManager.subscriptionStatus .distinctUntilChanged() .onEach { subscriptionStatus -> - val region = when (subscriptionsManager.getSubscriptionOffer()?.monthlyPlanId) { - MONTHLY_PLAN_ROW -> SubscriptionRegion.ROW - MONTHLY_PLAN_US -> SubscriptionRegion.US + val offer = subscriptionsManager.getSubscriptionOffer().firstOrNull() + val region = when (offer?.planId) { + MONTHLY_PLAN_ROW, YEARLY_PLAN_ROW -> SubscriptionRegion.ROW + MONTHLY_PLAN_US, YEARLY_PLAN_US -> SubscriptionRegion.US else -> null } _viewState.emit(viewState.value.copy(status = subscriptionStatus, region = region)) diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt index 30adf937beee..e2906cf82b12 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModel.kt @@ -30,17 +30,24 @@ import com.duckduckgo.subscriptions.api.SubscriptionStatus import com.duckduckgo.subscriptions.impl.CurrentPurchase import com.duckduckgo.subscriptions.impl.JSONObjectAdapter import com.duckduckgo.subscriptions.impl.PrivacyProFeature +import com.duckduckgo.subscriptions.impl.SubscriptionOffer import com.duckduckgo.subscriptions.impl.SubscriptionsChecker import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.ITR import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.LEGACY_FE_ITR import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.LEGACY_FE_NETP import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.LEGACY_FE_PIR import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_FREE_TRIAL_OFFER_US +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_ROW +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.NETP import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.PIR import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.PLATFORM import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.ROW_ITR import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_FREE_TRIAL_OFFER_US +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_PLAN_ROW +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_PLAN_US import com.duckduckgo.subscriptions.impl.SubscriptionsManager import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.repository.isActive @@ -229,38 +236,87 @@ class SubscriptionWebViewViewModel @Inject constructor( } private fun getSubscriptionOptions(featureName: String, method: String, id: String) { + suspend fun sendOptionJson(optionsJson: SubscriptionOptionsJson) { + val response = JsCallbackData( + featureName = featureName, + method = method, + id = id, + params = JSONObject(jsonAdapter.toJson(optionsJson)), + ) + command.send(SendResponseToJs(response)) + } + viewModelScope.launch(dispatcherProvider.io()) { - var subscriptionOptions = SubscriptionOptionsJson( + val defaultOptions = SubscriptionOptionsJson( options = emptyList(), features = emptyList(), ) - if (privacyProFeature.allowPurchase().isEnabled()) { - subscriptionsManager.getSubscriptionOffer()?.let { offer -> - val yearlyJson = OptionsJson( - id = offer.yearlyPlanId, - cost = CostJson(displayPrice = offer.yearlyFormattedPrice, recurrence = YEARLY), - ) + val subscriptionOptions = if (privacyProFeature.allowPurchase().isEnabled()) { + val subscriptionOffers = subscriptionsManager.getSubscriptionOffer().associateBy { it.offerId ?: it.planId } + when { + subscriptionOffers.keys.containsAll(listOf(MONTHLY_PLAN_US, YEARLY_PLAN_US)) -> { + createSubscriptionOptions( + monthlyOffer = subscriptionOffers.getValue(MONTHLY_PLAN_US), + yearlyOffer = subscriptionOffers.getValue(YEARLY_PLAN_US), + ) + } + + subscriptionOffers.keys.containsAll(listOf(MONTHLY_PLAN_ROW, YEARLY_PLAN_ROW)) -> { + createSubscriptionOptions( + monthlyOffer = subscriptionOffers.getValue(MONTHLY_PLAN_ROW), + yearlyOffer = subscriptionOffers.getValue(YEARLY_PLAN_ROW), + ) + } + + else -> defaultOptions + } + } else { + defaultOptions + } - val monthlyJson = OptionsJson( - id = offer.monthlyPlanId, - cost = CostJson(displayPrice = offer.monthlyFormattedPrice, recurrence = MONTHLY), - ) + sendOptionJson(subscriptionOptions) + } + } - subscriptionOptions = SubscriptionOptionsJson( - options = listOf(yearlyJson, monthlyJson), - features = offer.features.map(::FeatureJson), - ) - } + private fun createSubscriptionOptions( + monthlyOffer: SubscriptionOffer, + yearlyOffer: SubscriptionOffer, + ): SubscriptionOptionsJson { + return SubscriptionOptionsJson( + options = listOf( + createOptionsJson(yearlyOffer, YEARLY), + createOptionsJson(monthlyOffer, MONTHLY), + ), + features = monthlyOffer.features.map(::FeatureJson), + ) + } + + private fun createOptionsJson(offer: SubscriptionOffer, recurrence: String): OptionsJson { + val offerDisplayPrice: String = offer.offerId?.let { + offer.pricingPhases.getOrNull(1)?.formattedPrice ?: offer.pricingPhases.first().formattedPrice + } ?: offer.pricingPhases.first().formattedPrice + + return OptionsJson( + id = offer.planId, + cost = CostJson(displayPrice = offerDisplayPrice, recurrence = recurrence), + offer = getOfferJson(offer), + ) + } + + private fun getOfferJson(offer: SubscriptionOffer): OfferJson? { + return offer.offerId?.let { + val offerType = when (offer.offerId) { + MONTHLY_FREE_TRIAL_OFFER_US, YEARLY_FREE_TRIAL_OFFER_US -> OfferType.FREE_TRIAL + else -> OfferType.UNKNOWN } - val response = JsCallbackData( - featureName = featureName, - method = method, - id = id, - params = JSONObject(jsonAdapter.toJson(subscriptionOptions)), + OfferJson( + type = offerType.type, + id = it, + durationInDays = offer.pricingPhases.first().getBillingPeriodInDays(), + isUserEligible = true, // TODO Noelia: Need to check if they already had a free trial before to return false ) - command.send(SendResponseToJs(response)) } } @@ -293,11 +349,28 @@ class SubscriptionWebViewViewModel @Inject constructor( data class OptionsJson( val id: String, val cost: CostJson, + val offer: OfferJson?, + ) + + data class CostJson( + val displayPrice: String, + val recurrence: String, + ) + + data class OfferJson( + val type: String, + val id: String, + val durationInDays: Int?, + val isUserEligible: Boolean, ) - data class CostJson(val displayPrice: String, val recurrence: String) data class FeatureJson(val name: String) + enum class OfferType(val type: String) { + FREE_TRIAL("freeTrial"), + UNKNOWN("unknown"), + } + sealed class PurchaseStateView { data object Inactive : PurchaseStateView() data object InProgress : PurchaseStateView() diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsManagerTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsManagerTest.kt index ac595767adc5..7d0273dc020c 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsManagerTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsManagerTest.kt @@ -15,7 +15,13 @@ import com.duckduckgo.feature.toggles.api.FakeFeatureToggleFactory import com.duckduckgo.feature.toggles.api.Toggle.State import com.duckduckgo.subscriptions.api.Product.NetP import com.duckduckgo.subscriptions.api.SubscriptionStatus -import com.duckduckgo.subscriptions.api.SubscriptionStatus.* +import com.duckduckgo.subscriptions.api.SubscriptionStatus.AUTO_RENEWABLE +import com.duckduckgo.subscriptions.api.SubscriptionStatus.EXPIRED +import com.duckduckgo.subscriptions.api.SubscriptionStatus.GRACE_PERIOD +import com.duckduckgo.subscriptions.api.SubscriptionStatus.INACTIVE +import com.duckduckgo.subscriptions.api.SubscriptionStatus.NOT_AUTO_RENEWABLE +import com.duckduckgo.subscriptions.api.SubscriptionStatus.UNKNOWN +import com.duckduckgo.subscriptions.api.SubscriptionStatus.WAITING import com.duckduckgo.subscriptions.impl.RealSubscriptionsManager.RecoverSubscriptionResult import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_ROW import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US @@ -51,7 +57,6 @@ import com.duckduckgo.subscriptions.impl.services.SubscriptionResponse import com.duckduckgo.subscriptions.impl.services.SubscriptionsService import com.duckduckgo.subscriptions.impl.services.ValidateTokenResponse import com.duckduckgo.subscriptions.impl.store.SubscriptionsDataStore -import java.lang.Exception import java.time.Duration import java.time.Instant import java.time.LocalDateTime @@ -62,7 +67,10 @@ import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.ResponseBody.Companion.toResponseBody -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Assume.assumeFalse import org.junit.Assume.assumeTrue import org.junit.Before @@ -71,6 +79,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import org.mockito.kotlin.any +import org.mockito.kotlin.doReturn import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.never @@ -1125,51 +1134,55 @@ class RealSubscriptionsManagerTest(private val authApiV2Enabled: Boolean) { @Test fun whenGetSubscriptionOfferThenReturnValue() = runTest { authRepository.setFeatures(MONTHLY_PLAN_US, setOf(NETP)) + authRepository.setFeatures(YEARLY_PLAN_US, setOf(NETP)) givenPlansAvailable(MONTHLY_PLAN_US, YEARLY_PLAN_US) - val subscriptionOffer = subscriptionsManager.getSubscriptionOffer()!! + val subscriptionOffers = subscriptionsManager.getSubscriptionOffer() - with(subscriptionOffer) { - assertEquals(MONTHLY_PLAN_US, monthlyPlanId) - assertEquals("1$", monthlyFormattedPrice) - assertEquals(YEARLY_PLAN_US, yearlyPlanId) - assertEquals("1$", yearlyFormattedPrice) - assertEquals(setOf(NETP), features) + with(subscriptionOffers) { + assertTrue(any { it.planId == MONTHLY_PLAN_US }) + assertEquals("1$", find { it.planId == MONTHLY_PLAN_US }?.pricingPhases?.first()?.formattedPrice) + assertTrue(any { it.planId == YEARLY_PLAN_US }) + assertEquals("1$", find { it.planId == YEARLY_PLAN_US }?.pricingPhases?.first()?.formattedPrice) + assertEquals(setOf(NETP), first().features) } } @Test - fun whenGetSubscriptionOfferAndNoFeaturesThenReturnNull() = runTest { + fun whenGetSubscriptionOfferAndNoFeaturesThenReturnEmptyList() = runTest { authRepository.setFeatures(MONTHLY_PLAN_US, emptySet()) + authRepository.setFeatures(YEARLY_PLAN_US, emptySet()) givenPlansAvailable(MONTHLY_PLAN_US, YEARLY_PLAN_US) - assertNull(subscriptionsManager.getSubscriptionOffer()) + assertEquals(emptyList(), subscriptionsManager.getSubscriptionOffer()) } @Test fun whenGetSubscriptionOfferAndRowPlansAvailableThenReturnValue() = runTest { authRepository.setFeatures(MONTHLY_PLAN_ROW, setOf(NETP)) + authRepository.setFeatures(YEARLY_PLAN_ROW, setOf(NETP)) givenPlansAvailable(MONTHLY_PLAN_ROW, YEARLY_PLAN_ROW) givenIsLaunchedRow(true) - val subscriptionOffer = subscriptionsManager.getSubscriptionOffer()!! + val subscriptionOffers = subscriptionsManager.getSubscriptionOffer() - with(subscriptionOffer) { - assertEquals(MONTHLY_PLAN_ROW, monthlyPlanId) - assertEquals("1$", monthlyFormattedPrice) - assertEquals(YEARLY_PLAN_ROW, yearlyPlanId) - assertEquals("1$", yearlyFormattedPrice) - assertEquals(setOf(NETP), features) + with(subscriptionOffers) { + assertTrue(any { it.planId == MONTHLY_PLAN_ROW }) + assertEquals("1$", find { it.planId == MONTHLY_PLAN_ROW }?.pricingPhases?.first()?.formattedPrice) + assertTrue(any { it.planId == YEARLY_PLAN_ROW }) + assertEquals("1$", find { it.planId == YEARLY_PLAN_ROW }?.pricingPhases?.first()?.formattedPrice) + assertEquals(setOf(NETP), first().features) } } @Test - fun whenGetSubscriptionAndRowPlansAvailableAndFeatureDisabledThenReturnNull() = runTest { - authRepository.setFeatures(MONTHLY_PLAN_US, emptySet()) + fun whenGetSubscriptionAndRowPlansAvailableAndFeatureDisabledThenReturnEmptyList() = runTest { + authRepository.setFeatures(MONTHLY_PLAN_ROW, setOf(NETP)) + authRepository.setFeatures(YEARLY_PLAN_ROW, setOf(NETP)) givenPlansAvailable(MONTHLY_PLAN_ROW, YEARLY_PLAN_ROW) givenIsLaunchedRow(false) - assertNull(subscriptionsManager.getSubscriptionOffer()) + assertEquals(emptyList(), subscriptionsManager.getSubscriptionOffer()) } @Test @@ -1514,9 +1527,12 @@ class RealSubscriptionsManagerTest(private val authApiV2Enabled: Boolean) { val productDetails: ProductDetails = mock { productDetails -> whenever(productDetails.productId).thenReturn(SubscriptionsConstants.BASIC_SUBSCRIPTION) - val pricingPhaseList: List = listOf( - mock { pricingPhase -> whenever(pricingPhase.formattedPrice).thenReturn("1$") }, - ) + val mockPricingPhase: PricingPhase = mock { + on { formattedPrice } doReturn "1$" + on { billingPeriod } doReturn "P1M" + } + + val pricingPhaseList: List = listOf(mockPricingPhase) val pricingPhases: PricingPhases = mock { pricingPhases -> whenever(pricingPhases.pricingPhaseList).thenReturn(pricingPhaseList) diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsTest.kt index bd1462c68e29..149d648290e8 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealSubscriptionsTest.kt @@ -34,7 +34,10 @@ import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.ui.SubscriptionsWebViewActivityWithParams import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest -import org.junit.Assert.* +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test @@ -60,9 +63,19 @@ class RealSubscriptionsTest { private val pixel: SubscriptionPixelSender = mock() private lateinit var subscriptions: RealSubscriptions + private val testSubscriptionOfferList = listOf( + SubscriptionOffer( + planId = "test", + offerId = null, + pricingPhases = emptyList(), + features = setOf(SubscriptionsConstants.NETP), + ), + ) + @Before fun before() = runTest { whenever(mockSubscriptionsManager.canSupportEncryption()).thenReturn(true) + whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(emptyList()) subscriptions = RealSubscriptions(mockSubscriptionsManager, globalActivityStarter, pixel) } @@ -104,36 +117,25 @@ class RealSubscriptionsTest { @Test fun whenIsEligibleIfOffersReturnedThenReturnTrueRegardlessOfStatus() = runTest { whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(UNKNOWN) - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn( - SubscriptionOffer( - monthlyPlanId = "test", - yearlyFormattedPrice = "test", - yearlyPlanId = "test", - monthlyFormattedPrice = "test", - features = setOf(SubscriptionsConstants.NETP), - ), - ) + whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(testSubscriptionOfferList) assertTrue(subscriptions.isEligible()) } @Test fun whenIsEligibleIfNotOffersReturnedThenReturnFalseIfNotActiveOrWaiting() = runTest { whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(UNKNOWN) - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(null) assertFalse(subscriptions.isEligible()) } @Test fun whenIsEligibleIfNotOffersReturnedThenReturnTrueIfWaiting() = runTest { whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(WAITING) - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(null) assertTrue(subscriptions.isEligible()) } @Test fun whenIsEligibleIfNotOffersReturnedThenReturnTrueIfActive() = runTest { whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(AUTO_RENEWABLE) - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(null) assertTrue(subscriptions.isEligible()) } @@ -141,15 +143,7 @@ class RealSubscriptionsTest { fun whenIsEligibleIfNotEncryptionThenReturnTrueIfActive() = runTest { whenever(mockSubscriptionsManager.canSupportEncryption()).thenReturn(false) whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(AUTO_RENEWABLE) - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn( - SubscriptionOffer( - monthlyPlanId = "test", - yearlyFormattedPrice = "test", - yearlyPlanId = "test", - monthlyFormattedPrice = "test", - features = setOf(SubscriptionsConstants.NETP), - ), - ) + whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(testSubscriptionOfferList) assertTrue(subscriptions.isEligible()) } @@ -157,29 +151,13 @@ class RealSubscriptionsTest { fun whenIsEligibleIfNotEncryptionAndNotActiveThenReturnFalse() = runTest { whenever(mockSubscriptionsManager.canSupportEncryption()).thenReturn(false) whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(UNKNOWN) - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn( - SubscriptionOffer( - monthlyPlanId = "test", - yearlyFormattedPrice = "test", - yearlyPlanId = "test", - monthlyFormattedPrice = "test", - features = setOf(SubscriptionsConstants.NETP), - ), - ) + whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(testSubscriptionOfferList) assertFalse(subscriptions.isEligible()) } @Test fun whenShouldLaunchPrivacyProForUrlThenReturnCorrectValue() = runTest { - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn( - SubscriptionOffer( - monthlyPlanId = "test", - yearlyFormattedPrice = "test", - yearlyPlanId = "test", - monthlyFormattedPrice = "test", - features = setOf(SubscriptionsConstants.NETP), - ), - ) + whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(testSubscriptionOfferList) whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(UNKNOWN) assertTrue(subscriptions.shouldLaunchPrivacyProForUrl("https://duckduckgo.com/pro")) @@ -194,15 +172,7 @@ class RealSubscriptionsTest { @Test fun whenShouldLaunchPrivacyProForUrlThenReturnTrue() = runTest { - whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn( - SubscriptionOffer( - monthlyPlanId = "test", - yearlyFormattedPrice = "test", - yearlyPlanId = "test", - monthlyFormattedPrice = "test", - features = setOf(SubscriptionsConstants.NETP), - ), - ) + whenever(mockSubscriptionsManager.getSubscriptionOffer()).thenReturn(testSubscriptionOfferList) whenever(mockSubscriptionsManager.subscriptionStatus()).thenReturn(UNKNOWN) assertTrue(subscriptions.shouldLaunchPrivacyProForUrl("https://duckduckgo.com/pro")) diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt index 5cac8f322433..87a48f06dafd 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt @@ -62,6 +62,7 @@ class LegacyProSettingViewModelTest { @Test fun whenOnResumeEmitViewState() = runTest { whenever(subscriptionsManager.subscriptionStatus).thenReturn(flowOf(SubscriptionStatus.EXPIRED)) + whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn(emptyList()) viewModel.onCreate(mock()) viewModel.viewState.test { diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModelTest.kt index fd1a9f387a39..8e35b5277bfb 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ProSettingViewModelTest.kt @@ -62,6 +62,7 @@ class ProSettingViewModelTest { @Test fun whenOnResumeEmitViewState() = runTest { whenever(subscriptionsManager.subscriptionStatus).thenReturn(flowOf(SubscriptionStatus.EXPIRED)) + whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn(emptyList()) viewModel.onCreate(mock()) viewModel.viewState.test { diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt index 287e0dbf0fed..68c1c2ad47f3 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/ui/SubscriptionWebViewViewModelTest.kt @@ -15,10 +15,13 @@ import com.duckduckgo.subscriptions.api.SubscriptionStatus.INACTIVE import com.duckduckgo.subscriptions.api.SubscriptionStatus.UNKNOWN import com.duckduckgo.subscriptions.impl.CurrentPurchase import com.duckduckgo.subscriptions.impl.JSONObjectAdapter +import com.duckduckgo.subscriptions.impl.PricingPhase import com.duckduckgo.subscriptions.impl.PrivacyProFeature import com.duckduckgo.subscriptions.impl.SubscriptionOffer import com.duckduckgo.subscriptions.impl.SubscriptionsChecker import com.duckduckgo.subscriptions.impl.SubscriptionsConstants +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.MONTHLY_PLAN_US +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants.YEARLY_PLAN_US import com.duckduckgo.subscriptions.impl.SubscriptionsManager import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.ui.SubscriptionWebViewViewModel.Command @@ -196,17 +199,22 @@ class SubscriptionWebViewViewModelTest { @Test fun whenGetSubscriptionOptionsThenSendCommand() = runTest { - privacyProFeature.allowPurchase().setRawStoredState(Toggle.State(enable = true)) - - whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn( + val testSubscriptionOfferList = listOf( + SubscriptionOffer( + planId = MONTHLY_PLAN_US, + offerId = null, + pricingPhases = listOf(PricingPhase(formattedPrice = "$1", billingPeriod = "P1M")), + features = setOf(SubscriptionsConstants.NETP), + ), SubscriptionOffer( - monthlyPlanId = "monthly", - monthlyFormattedPrice = "$1", - yearlyPlanId = "yearly", - yearlyFormattedPrice = "$10", + planId = YEARLY_PLAN_US, + offerId = null, + pricingPhases = listOf(PricingPhase(formattedPrice = "$10", billingPeriod = "P1Y")), features = setOf(SubscriptionsConstants.NETP), ), ) + whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn(testSubscriptionOfferList) + privacyProFeature.allowPurchase().setRawStoredState(Toggle.State(enable = true)) viewModel.commands().test { viewModel.processJsCallbackMessage("test", "getSubscriptionOptions", "id", JSONObject("{}")) @@ -218,14 +226,15 @@ class SubscriptionWebViewViewModelTest { assertEquals("id", response.id) assertEquals("test", response.featureName) assertEquals("getSubscriptionOptions", response.method) - assertEquals("yearly", params?.options?.first()?.id) - assertEquals("monthly", params?.options?.last()?.id) + assertEquals(YEARLY_PLAN_US, params?.options?.first()?.id) + assertEquals(MONTHLY_PLAN_US, params?.options?.last()?.id) } } @Test fun whenGetSubscriptionsAndNoSubscriptionOfferThenSendCommandWithEmptyData() = runTest { privacyProFeature.allowPurchase().setRawStoredState(Toggle.State(enable = true)) + whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn(emptyList()) viewModel.commands().test { viewModel.processJsCallbackMessage("test", "getSubscriptionOptions", "id", JSONObject("{}")) @@ -246,16 +255,22 @@ class SubscriptionWebViewViewModelTest { @Test fun whenGetSubscriptionsAndToggleOffThenSendCommandWithEmptyData() = runTest { - privacyProFeature.allowPurchase().setRawStoredState(Toggle.State(enable = false)) - whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn( + val testSubscriptionOfferList = listOf( SubscriptionOffer( - monthlyPlanId = "monthly", - monthlyFormattedPrice = "$1", - yearlyPlanId = "yearly", - yearlyFormattedPrice = "$10", + planId = MONTHLY_PLAN_US, + offerId = null, + pricingPhases = listOf(PricingPhase(formattedPrice = "$1", billingPeriod = "P1M")), + features = setOf(SubscriptionsConstants.NETP), + ), + SubscriptionOffer( + planId = YEARLY_PLAN_US, + offerId = null, + pricingPhases = listOf(PricingPhase(formattedPrice = "$10", billingPeriod = "P1Y")), features = setOf(SubscriptionsConstants.NETP), ), ) + privacyProFeature.allowPurchase().setRawStoredState(Toggle.State(enable = false)) + whenever(subscriptionsManager.getSubscriptionOffer()).thenReturn(testSubscriptionOfferList) viewModel.commands().test { viewModel.processJsCallbackMessage("test", "getSubscriptionOptions", "id", JSONObject("{}")) From 239c0dd97f6c49926767ca4a06372d9e01edfdaa Mon Sep 17 00:00:00 2001 From: Dax Mobile <44842493+daxmobile@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:33:40 +1100 Subject: [PATCH 26/32] Update autoconsent to v12.4.0 (#5422) Task/Issue URL: https://app.asana.com/0/1209022585506290/1209022585506290 Autoconsent Release: https://github.com/duckduckgo/autoconsent/releases/tag/v12.4.0 ## Description Updates Autoconsent to version [v12.4.0](https://github.com/duckduckgo/autoconsent/releases/tag/v12.4.0). ### Autoconsent v12.4.0 release notes See release notes [here](https://github.com/duckduckgo/autoconsent/blob/v12.4.0/CHANGELOG.md) ## Steps to test This release has been tested during Autoconsent development. You can check the release notes for more information. 1. Make sure that there's no unexpected failures in CI checks 2. (optional) smoke test some of the sites mentioned in the release notes 3. If there are problems, reach out to a CPM DRI Co-authored-by: muodov <2726132+muodov@users.noreply.github.com> --- autoconsent/autoconsent-impl/libs/autoconsent-bundle.js | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js b/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js index 696b1e255825..d6b1d6810b73 100644 --- a/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js +++ b/autoconsent/autoconsent-impl/libs/autoconsent-bundle.js @@ -442,4 +442,4 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. *) - */const Ce=new class{constructor(e,t=null,o=null){if(this.id=a(),this.rules=[],this.foundCmp=null,this.state={cosmeticFiltersOn:!1,filterListReported:!1,lifecycle:"loading",prehideOn:!1,findCmpAttempts:0,detectedCmps:[],detectedPopups:[],heuristicPatterns:[],heuristicSnippets:[],selfTest:null},r.sendContentMessage=e,this.sendContentMessage=e,this.rules=[],this.updateState({lifecycle:"loading"}),this.addDynamicRules(),t)this.initialize(t,o);else{o&&this.parseDeclarativeRules(o);e({type:"init",url:window.location.href}),this.updateState({lifecycle:"waitingForInitResponse"})}this.domActions=new C(this)}initialize(e,t){const o=g(e);if(o.logs.lifecycle&&console.log("autoconsent init",window.location.href),this.config=o,o.enabled){if(t&&this.parseDeclarativeRules(t),e.enableFilterList){try{0}catch(e){console.error("Error parsing filter list",e)}"loading"===document.readyState?window.addEventListener("DOMContentLoaded",(()=>{this.applyCosmeticFilters()})):this.applyCosmeticFilters()}if(this.rules=function(e,t){return e.filter((e=>(!t.disabledCmps||!t.disabledCmps.includes(e.name))&&(t.enableCosmeticRules||!e.isCosmetic)))}(this.rules,o),e.enablePrehide)if(document.documentElement)this.prehideElements();else{const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.prehideElements()};window.addEventListener("DOMContentLoaded",e)}if("loading"===document.readyState){const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.start()};window.addEventListener("DOMContentLoaded",e)}else this.start();this.updateState({lifecycle:"initialized"})}else o.logs.lifecycle&&console.log("autoconsent is disabled")}addDynamicRules(){w.forEach((e=>{this.rules.push(new e(this))}))}parseDeclarativeRules(e){e.consentomatic&&Object.keys(e.consentomatic).forEach((t=>{this.addConsentomaticCMP(t,e.consentomatic[t])})),e.autoconsent&&e.autoconsent.forEach((e=>{this.addDeclarativeCMP(e)}))}addDeclarativeCMP(e){this.rules.push(new u(e,this))}addConsentomaticCMP(e,t){this.rules.push(new m(`com_${e}`,t))}start(){!function(e,t=500){globalThis.requestIdleCallback?requestIdleCallback(e,{timeout:t}):setTimeout(e,0)}((()=>this._start()))}async _start(){const e=this.config.logs;e.lifecycle&&console.log(`Detecting CMPs on ${window.location.href}`),this.updateState({lifecycle:"started"});const t=await this.findCmp(this.config.detectRetries);if(this.updateState({detectedCmps:t.map((e=>e.name))}),0===t.length)return e.lifecycle&&console.log("no CMP found",location.href),this.config.enablePrehide&&this.undoPrehide(),this.filterListFallback();this.updateState({lifecycle:"cmpDetected"});const o=[],i=[];for(const e of t)e.isCosmetic?i.push(e):o.push(e);let c=!1,n=await this.detectPopups(o,(async e=>{c=await this.handlePopup(e)}));if(0===n.length&&(n=await this.detectPopups(i,(async e=>{c=await this.handlePopup(e)}))),0===n.length)return e.lifecycle&&console.log("no popup found"),this.config.enablePrehide&&this.undoPrehide(),!1;if(n.length>1){const t={msg:"Found multiple CMPs, check the detection rules.",cmps:n.map((e=>e.name))};e.errors&&console.warn(t.msg,t.cmps),this.sendContentMessage({type:"autoconsentError",details:t})}return c}async findCmp(e){const t=this.config.logs;this.updateState({findCmpAttempts:this.state.findCmpAttempts+1});const o=[];for(const e of this.rules)try{if(!e.checkRunContext())continue;await e.detectCmp()&&(t.lifecycle&&console.log(`Found CMP: ${e.name} ${window.location.href}`),this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:e.name}),o.push(e))}catch(o){t.errors&&console.warn(`error detecting ${e.name}`,o)}return this.detectHeuristics(),0===o.length&&e>0?(await this.domActions.wait(500),this.findCmp(e-1)):o}detectHeuristics(){if(this.config.enableHeuristicDetection){const{patterns:e,snippets:t}=function(){const e=document.documentElement.innerText,t=[],o=[];for(const i of be){const c=e.match(i);c&&(t.push(i.toString()),o.push(...c.map((e=>e.substring(0,200)))))}return{patterns:t,snippets:o}}();e.length>0&&(e.length!==this.state.heuristicPatterns.length||this.state.heuristicPatterns.some(((t,o)=>t!==e[o])))&&(this.config.logs.lifecycle&&console.log("Heuristic patterns found",e,t),this.updateState({heuristicPatterns:e,heuristicSnippets:t}))}}async detectPopup(e){if(await this.waitForPopup(e).catch((t=>(this.config.logs.errors&&console.warn(`error waiting for a popup for ${e.name}`,t),!1))))return this.updateState({detectedPopups:this.state.detectedPopups.concat([e.name])}),this.sendContentMessage({type:"popupFound",cmp:e.name,url:location.href}),e;throw new Error("Popup is not shown")}async detectPopups(e,t){const o=e.map((e=>this.detectPopup(e)));await Promise.any(o).then((e=>{this.detectHeuristics(),t(e)})).catch((()=>null));const i=await Promise.allSettled(o),c=[];for(const e of i)"fulfilled"===e.status&&c.push(e.value);return c}async handlePopup(e){return this.updateState({lifecycle:"openPopupDetected"}),this.config.enablePrehide&&!this.state.prehideOn&&this.prehideElements(),this.state.cosmeticFiltersOn&&this.undoCosmetics(),this.foundCmp=e,"optOut"===this.config.autoAction?await this.doOptOut():"optIn"===this.config.autoAction?await this.doOptIn():(this.config.logs.lifecycle&&console.log("waiting for opt-out signal...",location.href),!0)}async doOptOut(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptOut"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt out on ${window.location.href}`),t=await this.foundCmp.optOut(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt out result ${t}`)):(e.errors&&console.log("no CMP to opt out"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optOutResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:this.foundCmp&&this.foundCmp.hasSelfTest,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optOutSucceeded":"optOutFailed"}),t}async doOptIn(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptIn"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt in on ${window.location.href}`),t=await this.foundCmp.optIn(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt in result ${t}`)):(e.errors&&console.log("no CMP to opt in"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optInResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:!1,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optInSucceeded":"optInFailed"}),t}async doSelfTest(){const e=this.config.logs;let t;return this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: self-test on ${window.location.href}`),t=await this.foundCmp.test()):(e.errors&&console.log("no CMP to self test"),t=!1),this.sendContentMessage({type:"selfTestResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,url:location.href}),this.updateState({selfTest:t}),t}async waitForPopup(e,t=5,o=500){const i=this.config.logs;i.lifecycle&&console.log("checking if popup is open...",e.name);const c=await e.detectPopup().catch((t=>(i.errors&&console.warn(`error detecting popup for ${e.name}`,t),!1)));return!c&&t>0?(await this.domActions.wait(o),this.waitForPopup(e,t-1,o)):(i.lifecycle&&console.log(e.name,"popup is "+(c?"open":"not open")),c)}prehideElements(){const e=this.config.logs,t=this.rules.filter((e=>e.prehideSelectors&&e.checkRunContext())).reduce(((e,t)=>[...e,...t.prehideSelectors]),["#didomi-popup,.didomi-popup-container,.didomi-popup-notice,.didomi-consent-popup-preferences,#didomi-notice,.didomi-popup-backdrop,.didomi-screen-medium"]);return this.updateState({prehideOn:!0}),setTimeout((()=>{this.config.enablePrehide&&this.state.prehideOn&&!["runningOptOut","runningOptIn"].includes(this.state.lifecycle)&&(e.lifecycle&&console.log("Process is taking too long, unhiding elements"),this.undoPrehide())}),this.config.prehideTimeout||2e3),this.domActions.prehide(t.join(","))}undoPrehide(){return this.updateState({prehideOn:!1}),this.domActions.undoPrehide()}async applyCosmeticFilters(e){if(!this.filtersEngine)return!1;const t=this.config?.logs;setTimeout((()=>{if(this.state.cosmeticFiltersOn&&!this.state.filterListReported){const o=this.domActions.elementVisible(function(e){if(e)return e.replace(/\s*{[^\\}]*}\s*/g,",").replace(/,$/,"");return""}(e),"any");o?(t?.lifecycle&&console.log("Prehide cosmetic filters matched",location.href),this.reportFilterlist()):t?.lifecycle&&console.log("Prehide cosmetic filters didn't match",location.href)}}),2e3),this.updateState({cosmeticFiltersOn:!0});try{this.cosmeticStyleSheet=await this.domActions.createOrUpdateStyleSheet(e,this.cosmeticStyleSheet),t?.lifecycle&&console.log("[cosmetics]",this.cosmeticStyleSheet,location.href),document.adoptedStyleSheets.push(this.cosmeticStyleSheet)}catch(e){return this.config.logs&&console.error("Error applying cosmetic filters",e),!1}return!0}undoCosmetics(){this.updateState({cosmeticFiltersOn:!1}),this.config.logs.lifecycle&&console.log("[undocosmetics]",this.cosmeticStyleSheet,location.href),this.domActions.removeStyleSheet(this.cosmeticStyleSheet)}reportFilterlist(){this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:"filterList"}),this.sendContentMessage({type:"popupFound",cmp:"filterList",url:location.href}),this.updateState({filterListReported:!0})}filterListFallback(){return this.updateState({lifecycle:"nothingDetected"}),!1}updateState(e){Object.assign(this.state,e),this.sendContentMessage({type:"report",instanceId:this.id,url:window.location.href,mainFrame:window.top===window.self,state:this.state})}async receiveMessageCallback(e){const t=this.config?.logs;switch(t?.messages&&console.log("received from background",e,window.location.href),e.type){case"initResp":this.initialize(e.config,e.rules);break;case"optIn":await this.doOptIn();break;case"optOut":await this.doOptOut();break;case"selfTest":await this.doSelfTest();break;case"evalResp":!function(e,t){const o=r.pending.get(e);o?(r.pending.delete(e),o.timer&&window.clearTimeout(o.timer),o.resolve(t)):console.warn("no eval #",e)}(e.id,e.result)}}}((e=>{AutoconsentAndroid.process(JSON.stringify(e))}),null,we);window.autoconsentMessageCallback=e=>{Ce.receiveMessageCallback(e)}}(); + */const Ce=new class{constructor(e,t=null,o=null){if(this.id=a(),this.rules=[],this.foundCmp=null,this.state={cosmeticFiltersOn:!1,filterListReported:!1,lifecycle:"loading",prehideOn:!1,findCmpAttempts:0,detectedCmps:[],detectedPopups:[],heuristicPatterns:[],heuristicSnippets:[],selfTest:null},r.sendContentMessage=e,this.sendContentMessage=e,this.rules=[],this.updateState({lifecycle:"loading"}),this.addDynamicRules(),t)this.initialize(t,o);else{o&&this.parseDeclarativeRules(o);e({type:"init",url:window.location.href}),this.updateState({lifecycle:"waitingForInitResponse"})}this.domActions=new C(this)}initialize(e,t){const o=g(e);if(o.logs.lifecycle&&console.log("autoconsent init",window.location.href),this.config=o,o.enabled){if(t&&this.parseDeclarativeRules(t),e.enableFilterList){try{0}catch(e){console.error("Error parsing filter list",e)}"loading"===document.readyState?window.addEventListener("DOMContentLoaded",(()=>{this.applyCosmeticFilters()})):this.applyCosmeticFilters()}if(this.rules=function(e,t){return e.filter((e=>(!t.disabledCmps||!t.disabledCmps.includes(e.name))&&(t.enableCosmeticRules||!e.isCosmetic)))}(this.rules,o),e.enablePrehide)if(document.documentElement)this.prehideElements();else{const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.prehideElements()};window.addEventListener("DOMContentLoaded",e)}if("loading"===document.readyState){const e=()=>{window.removeEventListener("DOMContentLoaded",e),this.start()};window.addEventListener("DOMContentLoaded",e)}else this.start();this.updateState({lifecycle:"initialized"})}else o.logs.lifecycle&&console.log("autoconsent is disabled")}addDynamicRules(){w.forEach((e=>{this.rules.push(new e(this))}))}parseDeclarativeRules(e){e.consentomatic&&Object.keys(e.consentomatic).forEach((t=>{this.addConsentomaticCMP(t,e.consentomatic[t])})),e.autoconsent&&e.autoconsent.forEach((e=>{this.addDeclarativeCMP(e)}))}addDeclarativeCMP(e){this.rules.push(new u(e,this))}addConsentomaticCMP(e,t){this.rules.push(new m(`com_${e}`,t))}start(){!function(e,t=500){globalThis.requestIdleCallback?requestIdleCallback(e,{timeout:t}):setTimeout(e,0)}((()=>this._start()))}async _start(){const e=this.config.logs;e.lifecycle&&console.log(`Detecting CMPs on ${window.location.href}`),this.updateState({lifecycle:"started"});const t=await this.findCmp(this.config.detectRetries);if(this.updateState({detectedCmps:t.map((e=>e.name))}),0===t.length)return e.lifecycle&&console.log("no CMP found",location.href),this.config.enablePrehide&&this.undoPrehide(),this.filterListFallback();this.updateState({lifecycle:"cmpDetected"});const o=[],i=[];for(const e of t)e.isCosmetic?i.push(e):o.push(e);let c=!1,n=await this.detectPopups(o,(async e=>{c=await this.handlePopup(e)}));if(0===n.length&&(n=await this.detectPopups(i,(async e=>{c=await this.handlePopup(e)}))),0===n.length)return e.lifecycle&&console.log("no popup found"),this.config.enablePrehide&&this.undoPrehide(),!1;if(n.length>1){const t={msg:"Found multiple CMPs, check the detection rules.",cmps:n.map((e=>e.name))};e.errors&&console.warn(t.msg,t.cmps),this.sendContentMessage({type:"autoconsentError",details:t})}return c}async findCmp(e){const t=this.config.logs;this.updateState({findCmpAttempts:this.state.findCmpAttempts+1});const o=[];for(const e of this.rules)try{if(!e.checkRunContext())continue;await e.detectCmp()&&(t.lifecycle&&console.log(`Found CMP: ${e.name} ${window.location.href}`),this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:e.name}),o.push(e))}catch(o){t.errors&&console.warn(`error detecting ${e.name}`,o)}return this.detectHeuristics(),0===o.length&&e>0?(await this.domActions.wait(500),this.findCmp(e-1)):o}detectHeuristics(){if(this.config.enableHeuristicDetection){const{patterns:e,snippets:t}=function(){const e=document.documentElement.innerText,t=[],o=[];for(const i of be){const c=e.match(i);c&&(t.push(i.toString()),o.push(...c.map((e=>e.substring(0,200)))))}return{patterns:t,snippets:o}}();e.length>0&&(e.length!==this.state.heuristicPatterns.length||this.state.heuristicPatterns.some(((t,o)=>t!==e[o])))&&(this.config.logs.lifecycle&&console.log("Heuristic patterns found",e,t),this.updateState({heuristicPatterns:e,heuristicSnippets:t}))}}async detectPopup(e){if(await this.waitForPopup(e).catch((t=>(this.config.logs.errors&&console.warn(`error waiting for a popup for ${e.name}`,t),!1))))return this.updateState({detectedPopups:this.state.detectedPopups.concat([e.name])}),this.sendContentMessage({type:"popupFound",cmp:e.name,url:location.href}),e;throw new Error("Popup is not shown")}async detectPopups(e,t){const o=e.map((e=>this.detectPopup(e)));await Promise.any(o).then((e=>{this.detectHeuristics(),t(e)})).catch((()=>{}));const i=await Promise.allSettled(o),c=[];for(const e of i)"fulfilled"===e.status&&c.push(e.value);return c}async handlePopup(e){return this.updateState({lifecycle:"openPopupDetected"}),this.config.enablePrehide&&!this.state.prehideOn&&this.prehideElements(),this.state.cosmeticFiltersOn&&this.undoCosmetics(),this.foundCmp=e,"optOut"===this.config.autoAction?await this.doOptOut():"optIn"===this.config.autoAction?await this.doOptIn():(this.config.logs.lifecycle&&console.log("waiting for opt-out signal...",location.href),!0)}async doOptOut(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptOut"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt out on ${window.location.href}`),t=await this.foundCmp.optOut(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt out result ${t}`)):(e.errors&&console.log("no CMP to opt out"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optOutResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:this.foundCmp&&this.foundCmp.hasSelfTest,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optOutSucceeded":"optOutFailed"}),t}async doOptIn(){const e=this.config.logs;let t;return this.updateState({lifecycle:"runningOptIn"}),this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: opt in on ${window.location.href}`),t=await this.foundCmp.optIn(),e.lifecycle&&console.log(`${this.foundCmp.name}: opt in result ${t}`)):(e.errors&&console.log("no CMP to opt in"),t=!1),this.config.enablePrehide&&this.undoPrehide(),this.sendContentMessage({type:"optInResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,scheduleSelfTest:!1,url:location.href}),t&&!this.foundCmp.isIntermediate?(this.sendContentMessage({type:"autoconsentDone",cmp:this.foundCmp.name,isCosmetic:this.foundCmp.isCosmetic,url:location.href}),this.updateState({lifecycle:"done"})):this.updateState({lifecycle:t?"optInSucceeded":"optInFailed"}),t}async doSelfTest(){const e=this.config.logs;let t;return this.foundCmp?(e.lifecycle&&console.log(`CMP ${this.foundCmp.name}: self-test on ${window.location.href}`),t=await this.foundCmp.test()):(e.errors&&console.log("no CMP to self test"),t=!1),this.sendContentMessage({type:"selfTestResult",cmp:this.foundCmp?this.foundCmp.name:"none",result:t,url:location.href}),this.updateState({selfTest:t}),t}async waitForPopup(e,t=5,o=500){const i=this.config.logs;i.lifecycle&&console.log("checking if popup is open...",e.name);const c=await e.detectPopup().catch((t=>(i.errors&&console.warn(`error detecting popup for ${e.name}`,t),!1)));return!c&&t>0?(await this.domActions.wait(o),this.waitForPopup(e,t-1,o)):(i.lifecycle&&console.log(e.name,"popup is "+(c?"open":"not open")),c)}prehideElements(){const e=this.config.logs,t=this.rules.filter((e=>e.prehideSelectors&&e.checkRunContext())).reduce(((e,t)=>[...e,...t.prehideSelectors]),["#didomi-popup,.didomi-popup-container,.didomi-popup-notice,.didomi-consent-popup-preferences,#didomi-notice,.didomi-popup-backdrop,.didomi-screen-medium"]);return this.updateState({prehideOn:!0}),setTimeout((()=>{this.config.enablePrehide&&this.state.prehideOn&&!["runningOptOut","runningOptIn"].includes(this.state.lifecycle)&&(e.lifecycle&&console.log("Process is taking too long, unhiding elements"),this.undoPrehide())}),this.config.prehideTimeout||2e3),this.domActions.prehide(t.join(","))}undoPrehide(){return this.updateState({prehideOn:!1}),this.domActions.undoPrehide()}async applyCosmeticFilters(e){if(!this.filtersEngine)return!1;const t=this.config?.logs;setTimeout((()=>{if(this.state.cosmeticFiltersOn&&!this.state.filterListReported){const o=this.domActions.elementVisible(function(e){if(e)return e.replace(/\s*{[^\\}]*}\s*/g,",").replace(/,$/,"");return""}(e),"any");o?(t?.lifecycle&&console.log("Prehide cosmetic filters matched",location.href),this.reportFilterlist()):t?.lifecycle&&console.log("Prehide cosmetic filters didn't match",location.href)}}),2e3),this.updateState({cosmeticFiltersOn:!0});try{this.cosmeticStyleSheet=await this.domActions.createOrUpdateStyleSheet(e,this.cosmeticStyleSheet),t?.lifecycle&&console.log("[cosmetics]",this.cosmeticStyleSheet,location.href),document.adoptedStyleSheets.push(this.cosmeticStyleSheet)}catch(e){return this.config.logs&&console.error("Error applying cosmetic filters",e),!1}return!0}undoCosmetics(){this.updateState({cosmeticFiltersOn:!1}),this.config.logs.lifecycle&&console.log("[undocosmetics]",this.cosmeticStyleSheet,location.href),this.domActions.removeStyleSheet(this.cosmeticStyleSheet)}reportFilterlist(){this.sendContentMessage({type:"cmpDetected",url:location.href,cmp:"filterList"}),this.sendContentMessage({type:"popupFound",cmp:"filterList",url:location.href}),this.updateState({filterListReported:!0})}filterListFallback(){return this.updateState({lifecycle:"nothingDetected"}),!1}updateState(e){Object.assign(this.state,e),this.sendContentMessage({type:"report",instanceId:this.id,url:window.location.href,mainFrame:window.top===window.self,state:this.state})}async receiveMessageCallback(e){const t=this.config?.logs;switch(t?.messages&&console.log("received from background",e,window.location.href),e.type){case"initResp":this.initialize(e.config,e.rules);break;case"optIn":await this.doOptIn();break;case"optOut":await this.doOptOut();break;case"selfTest":await this.doSelfTest();break;case"evalResp":!function(e,t){const o=r.pending.get(e);o?(r.pending.delete(e),o.timer&&window.clearTimeout(o.timer),o.resolve(t)):console.warn("no eval #",e)}(e.id,e.result)}}}((e=>{AutoconsentAndroid.process(JSON.stringify(e))}),null,we);window.autoconsentMessageCallback=e=>{Ce.receiveMessageCallback(e)}}(); diff --git a/package-lock.json b/package-lock.json index 808ba7c07941..92da53232608 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,7 @@ "name": "ddg-android", "version": "1.0.0", "dependencies": { - "@duckduckgo/autoconsent": "^12.3.0", + "@duckduckgo/autoconsent": "^12.4.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.1", @@ -47,9 +47,9 @@ } }, "node_modules/@duckduckgo/autoconsent": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/@duckduckgo/autoconsent/-/autoconsent-12.3.0.tgz", - "integrity": "sha512-mOW11Ve9DRKDkjFtAjXAP3Jd5E22YqI+4+6NTPNnOud2/02QyhM8l1vK//hTR6cmXXWZiFknpuv6qckuwMKivw==", + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/@duckduckgo/autoconsent/-/autoconsent-12.4.0.tgz", + "integrity": "sha512-k7pNvq9IdPURoAhboAWx+xDMnIHKJ9JY74eft/aOOv1Lj5P8Bjv63ERyvttK5ugzvJvVyUR9GNp3DcQF/izlmA==", "license": "MPL-2.0", "dependencies": { "@ghostery/adblocker": "^2.0.4", diff --git a/package.json b/package.json index 9f531394a0c7..7e476d429a01 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "rollup-plugin-terser": "^7.0.2" }, "dependencies": { - "@duckduckgo/autoconsent": "^12.3.0", + "@duckduckgo/autoconsent": "^12.4.0", "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.1", From 70d0aa835e7cc4e8dddc20412942fc7f035ce743 Mon Sep 17 00:00:00 2001 From: Mike Scamell Date: Mon, 6 Jan 2025 08:47:09 +0000 Subject: [PATCH 27/32] Update Settings: Translations (#5412) Task/Issue URL: https://app.asana.com/0/0/1208870901574431/f ### Description All new translations for the Update Settings feature. --------- Co-authored-by: Dax The Translator --- app/src/main/res/values-bg/strings.xml | 28 +++++++++---------- app/src/main/res/values-cs/strings.xml | 28 +++++++++---------- app/src/main/res/values-da/strings.xml | 28 +++++++++---------- app/src/main/res/values-de/strings.xml | 28 +++++++++---------- app/src/main/res/values-el/strings.xml | 28 +++++++++---------- app/src/main/res/values-es/strings.xml | 28 +++++++++---------- app/src/main/res/values-et/strings.xml | 28 +++++++++---------- app/src/main/res/values-fi/strings.xml | 28 +++++++++---------- app/src/main/res/values-fr/strings.xml | 28 +++++++++---------- app/src/main/res/values-hr/strings.xml | 28 +++++++++---------- app/src/main/res/values-hu/strings.xml | 28 +++++++++---------- app/src/main/res/values-it/strings.xml | 28 +++++++++---------- app/src/main/res/values-lt/strings.xml | 28 +++++++++---------- app/src/main/res/values-lv/strings.xml | 28 +++++++++---------- app/src/main/res/values-nb/strings.xml | 28 +++++++++---------- app/src/main/res/values-nl/strings.xml | 28 +++++++++---------- app/src/main/res/values-pl/strings.xml | 28 +++++++++---------- app/src/main/res/values-pt/strings.xml | 28 +++++++++---------- app/src/main/res/values-ro/strings.xml | 28 +++++++++---------- app/src/main/res/values-ru/strings.xml | 28 +++++++++---------- app/src/main/res/values-sk/strings.xml | 28 +++++++++---------- app/src/main/res/values-sl/strings.xml | 28 +++++++++---------- app/src/main/res/values-sv/strings.xml | 28 +++++++++---------- app/src/main/res/values-tr/strings.xml | 28 +++++++++---------- app/src/main/res/values/strings.xml | 28 +++++++++---------- .../res/values-bg/strings-autoconsent.xml | 2 +- .../res/values-cs/strings-autoconsent.xml | 2 +- .../res/values-da/strings-autoconsent.xml | 2 +- .../res/values-de/strings-autoconsent.xml | 2 +- .../res/values-el/strings-autoconsent.xml | 2 +- .../res/values-es/strings-autoconsent.xml | 2 +- .../res/values-et/strings-autoconsent.xml | 2 +- .../res/values-fi/strings-autoconsent.xml | 2 +- .../res/values-fr/strings-autoconsent.xml | 2 +- .../res/values-hr/strings-autoconsent.xml | 2 +- .../res/values-hu/strings-autoconsent.xml | 2 +- .../res/values-it/strings-autoconsent.xml | 2 +- .../res/values-lt/strings-autoconsent.xml | 2 +- .../res/values-lv/strings-autoconsent.xml | 2 +- .../res/values-nb/strings-autoconsent.xml | 2 +- .../res/values-nl/strings-autoconsent.xml | 2 +- .../res/values-pl/strings-autoconsent.xml | 2 +- .../res/values-pt/strings-autoconsent.xml | 2 +- .../res/values-ro/strings-autoconsent.xml | 2 +- .../res/values-ru/strings-autoconsent.xml | 2 +- .../res/values-sk/strings-autoconsent.xml | 2 +- .../res/values-sl/strings-autoconsent.xml | 2 +- .../res/values-sv/strings-autoconsent.xml | 2 +- .../res/values-tr/strings-autoconsent.xml | 2 +- .../main/res/values/strings-autoconsent.xml | 2 +- .../res/values-bg/strings-autofill-impl.xml | 2 +- .../res/values-cs/strings-autofill-impl.xml | 2 +- .../res/values-da/strings-autofill-impl.xml | 2 +- .../res/values-de/strings-autofill-impl.xml | 2 +- .../res/values-el/strings-autofill-impl.xml | 2 +- .../res/values-es/strings-autofill-impl.xml | 2 +- .../res/values-et/strings-autofill-impl.xml | 2 +- .../res/values-fi/strings-autofill-impl.xml | 2 +- .../res/values-fr/strings-autofill-impl.xml | 2 +- .../res/values-hr/strings-autofill-impl.xml | 2 +- .../res/values-hu/strings-autofill-impl.xml | 2 +- .../res/values-it/strings-autofill-impl.xml | 2 +- .../res/values-lt/strings-autofill-impl.xml | 2 +- .../res/values-lv/strings-autofill-impl.xml | 2 +- .../res/values-nb/strings-autofill-impl.xml | 2 +- .../res/values-nl/strings-autofill-impl.xml | 2 +- .../res/values-pl/strings-autofill-impl.xml | 2 +- .../res/values-pt/strings-autofill-impl.xml | 2 +- .../res/values-ro/strings-autofill-impl.xml | 2 +- .../res/values-ru/strings-autofill-impl.xml | 2 +- .../res/values-sk/strings-autofill-impl.xml | 2 +- .../res/values-sl/strings-autofill-impl.xml | 2 +- .../res/values-sv/strings-autofill-impl.xml | 2 +- .../res/values-tr/strings-autofill-impl.xml | 2 +- .../main/res/values/strings-autofill-impl.xml | 2 +- .../main/res/values-bg/strings-common-ui.xml | 6 ++-- .../main/res/values-cs/strings-common-ui.xml | 6 ++-- .../main/res/values-da/strings-common-ui.xml | 6 ++-- .../main/res/values-de/strings-common-ui.xml | 6 ++-- .../main/res/values-el/strings-common-ui.xml | 6 ++-- .../main/res/values-es/strings-common-ui.xml | 6 ++-- .../main/res/values-et/strings-common-ui.xml | 6 ++-- .../main/res/values-fi/strings-common-ui.xml | 6 ++-- .../main/res/values-fr/strings-common-ui.xml | 6 ++-- .../main/res/values-hr/strings-common-ui.xml | 6 ++-- .../main/res/values-hu/strings-common-ui.xml | 6 ++-- .../main/res/values-it/strings-common-ui.xml | 6 ++-- .../main/res/values-lt/strings-common-ui.xml | 6 ++-- .../main/res/values-lv/strings-common-ui.xml | 6 ++-- .../main/res/values-nb/strings-common-ui.xml | 6 ++-- .../main/res/values-nl/strings-common-ui.xml | 6 ++-- .../main/res/values-pl/strings-common-ui.xml | 6 ++-- .../main/res/values-pt/strings-common-ui.xml | 6 ++-- .../main/res/values-ro/strings-common-ui.xml | 6 ++-- .../main/res/values-ru/strings-common-ui.xml | 6 ++-- .../main/res/values-sk/strings-common-ui.xml | 6 ++-- .../main/res/values-sl/strings-common-ui.xml | 6 ++-- .../main/res/values-sv/strings-common-ui.xml | 6 ++-- .../main/res/values-tr/strings-common-ui.xml | 6 ++-- .../src/main/res/values/strings-common-ui.xml | 6 ++-- .../res/values-bg/strings-subscriptions.xml | 1 + .../res/values-cs/strings-subscriptions.xml | 1 + .../res/values-da/strings-subscriptions.xml | 1 + .../res/values-de/strings-subscriptions.xml | 1 + .../res/values-el/strings-subscriptions.xml | 1 + .../res/values-es/strings-subscriptions.xml | 1 + .../res/values-et/strings-subscriptions.xml | 1 + .../res/values-fi/strings-subscriptions.xml | 1 + .../res/values-fr/strings-subscriptions.xml | 1 + .../res/values-hr/strings-subscriptions.xml | 1 + .../res/values-hu/strings-subscriptions.xml | 1 + .../res/values-it/strings-subscriptions.xml | 1 + .../res/values-lt/strings-subscriptions.xml | 1 + .../res/values-lv/strings-subscriptions.xml | 1 + .../res/values-nb/strings-subscriptions.xml | 1 + .../res/values-nl/strings-subscriptions.xml | 1 + .../res/values-pl/strings-subscriptions.xml | 1 + .../res/values-pt/strings-subscriptions.xml | 1 + .../res/values-ro/strings-subscriptions.xml | 1 + .../res/values-ru/strings-subscriptions.xml | 1 + .../res/values-sk/strings-subscriptions.xml | 1 + .../res/values-sl/strings-subscriptions.xml | 1 + .../res/values-sv/strings-subscriptions.xml | 1 + .../res/values-tr/strings-subscriptions.xml | 1 + .../src/main/res/values/donottranslate.xml | 22 --------------- .../main/res/values/strings-subscriptions.xml | 1 + .../src/main/res/values-bg/strings-sync.xml | 2 +- .../src/main/res/values-cs/strings-sync.xml | 2 +- .../src/main/res/values-da/strings-sync.xml | 2 +- .../src/main/res/values-de/strings-sync.xml | 2 +- .../src/main/res/values-el/strings-sync.xml | 2 +- .../src/main/res/values-es/strings-sync.xml | 2 +- .../src/main/res/values-et/strings-sync.xml | 2 +- .../src/main/res/values-fi/strings-sync.xml | 2 +- .../src/main/res/values-fr/strings-sync.xml | 2 +- .../src/main/res/values-hr/strings-sync.xml | 2 +- .../src/main/res/values-hu/strings-sync.xml | 2 +- .../src/main/res/values-it/strings-sync.xml | 2 +- .../src/main/res/values-lt/strings-sync.xml | 2 +- .../src/main/res/values-lv/strings-sync.xml | 2 +- .../src/main/res/values-nb/strings-sync.xml | 2 +- .../src/main/res/values-nl/strings-sync.xml | 2 +- .../src/main/res/values-pl/strings-sync.xml | 2 +- .../src/main/res/values-pt/strings-sync.xml | 2 +- .../src/main/res/values-ro/strings-sync.xml | 2 +- .../src/main/res/values-ru/strings-sync.xml | 2 +- .../src/main/res/values-sk/strings-sync.xml | 2 +- .../src/main/res/values-sl/strings-sync.xml | 2 +- .../src/main/res/values-sv/strings-sync.xml | 2 +- .../src/main/res/values-tr/strings-sync.xml | 2 +- .../src/main/res/values/strings-sync.xml | 2 +- 151 files changed, 525 insertions(+), 522 deletions(-) delete mode 100644 subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index b8ede3d5b2b8..f5d1f62abc61 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -125,7 +125,7 @@ Настройки Настройки Поверителност - Защита на поверителността + Защита на поверителността Външен вид Персонализиране За нас @@ -135,7 +135,7 @@ Защита на имейл Блокирайте имейл тракерите и скрийте своя адрес Още от DuckDuckGo - Следващи стъпки + Следващи стъпки Светла Тема Тъмен @@ -158,15 +158,15 @@ Защита от проследяване в мрежата Активирано по подразбиране Настройки - Основни настройки + Основни настройки Разрешения Синхронизиране и архивиране Fire Button - Изчистване на данни - Добавяне на приспособлението към началния екран - Задайте позицията на адресната лента - Активиране на гласово търсене - DuckDuckGo на други платформи + Изчистване на данни + Добавяне на приспособлението към началния екран + Задайте позицията на адресната лента + Активиране на гласово търсене + DuckDuckGo на други платформи поверително търсене @@ -192,7 +192,7 @@ Защита от проследяване в мрежата Защитата от проследяване в мрежата е активирана Научете повече]]> - Learn More]]> + Научете повече]]> Защита от изскачащи прозорци за бисквитки @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Изчистване на данни Разрешения @@ -213,7 +213,7 @@ Запази Автоматично изчистване… - Automatically Clear Data… + Автоматично изчистване на данните… Автоматично изчистване… Няма Раздели @@ -230,10 +230,10 @@ Относно DuckDuckGo - About + За нас Добре дошли на наша страна! DuckDuckGo е независима компания, основана през 2008 г., за защита на личните данни в интернет за всеки, на когото му е омръзнало да бъде проследяван онлайн и иска лесно решение на проблема. Ние сме доказателство, че можете да получите реална и безкомпромисна защита на личните данни онлайн.\n\nБраузърът DuckDuckGo притежава функциите, които очаквате от един основен браузър, като отметки, раздели, пароли и много други, както и редица мощни защити на поверителността, които повечето популярни браузъри не предлагат по подразбиране. Този уникален и комплексен набор от защити на поверителността предлага сигурност при онлайн дейностите – търсене, сърфиране, изпращане на имейли и др.\n\nЗа да работят, нашите защити на поверителността не изискват да имате технически познания или да се извършвате сложни настройки. Необходимо е да използвате браузъра DuckDuckGo на всички Ваши устройства и ще получите поверителност по подразбиране.\n\nНо ако искате да надникнете зад кулисите и да разберете как работят защитите на поверителността на DuckDuckGo, можете да намерите повече информация на нашите страници за помощ. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo е независима компания за защита на личните данни в интернет, основана през 2008 г., предлагаща продукт, подходящ за всеки, на когото му е омръзнало да бъде проследяван онлайн и иска лесно решение. Ние сме доказателство, че можеш да получиш реална защита на личните данни онлайн без компромиси.\n\nБраузърът DuckDuckGo притежава функциите, които очаквате от един основен браузър, като отметки, раздели, пароли и много други, както и редица мощни защити на поверителността, които повечето популярни браузъри не предлагат по подразбиране. Този уникален и комплексен набор от защити на поверителността предлага сигурност при онлайн дейностите – търсене, сърфиране, изпращане на имейли и др.\n\nЗа да работят, нашите защити на поверителността не изискват да имате технически познания или да се извършвате сложни настройки. Необходимо е само да използвате браузъра DuckDuckGo на всички свои устройства и ще получите поверителност по подразбиране.\n\nНо ако искате да надникнете зад кулисите и да разберете как работят защитите на поверителността на DuckDuckGo, можете да намерите повече информация на нашите страници за помощ. Няма предложения @@ -702,7 +702,7 @@ Пароли - Пароли и автоматично попълване + Пароли и автоматично попълване Паролата е запазена Паролата е актуализирана diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index b046ab5bbfef..1c563fc20170 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -125,7 +125,7 @@ Nastavení Nastavení Soukromí - Ochrana osobních údajů + Ochrana osobních údajů Vzhled Přizpůsobit Informace @@ -135,7 +135,7 @@ Ochrana e-mailu Blokování trackerů v e-mailu a skrytí adresy Další od DuckDuckGo - Další kroky + Další kroky Světlo Barevný motiv Tmavé @@ -158,15 +158,15 @@ Ochrana před sledováním na webu Ve výchozím nastavení povoleno Nastavení - Hlavní nastavení + Hlavní nastavení Oprávnění Synchronizace a zálohování Fire Button - Vymazání dat - Přidat widget na domovskou obrazovku - Nastavte pozici adresního řádku - Povolit hlasové vyhledávání - DuckDuckGo na jiných platformách + Vymazání dat + Přidat widget na domovskou obrazovku + Nastavte pozici adresního řádku + Povolit hlasové vyhledávání + DuckDuckGo na jiných platformách Soukromé vyhledávání @@ -192,7 +192,7 @@ Ochrana před sledováním na webu Ochrana před sledováním na webu je povolená Další informace]]> - Learn More]]> + Další informace]]> Ochrana před vyskakovacími okny ohledně cookies @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Vymazání dat Oprávnění @@ -213,7 +213,7 @@ Uložit Automatické vymazání… - Automatically Clear Data… + Automaticky vymazat data… Automatické vymazání… Žádný Karty @@ -230,10 +230,10 @@ O DuckDuckGo - About + Informace Vítejte na Kačeří straně! DuckDuckGo je nezávislá společnost založená v roce 2008, která se zabývá ochranou soukromí pro všechny, kdo už mají dost sledování na internetu a chtějí snadné řešení. Jsme důkazem, že skutečná ochrana soukromí na internetu nemusí mít kompromisy.\n\nProhlížeč DuckDuckGo má všechno, co od prohlížeče očekáváš, jako jsou záložky, karty, hesla a další funkce. A k tomu má víc než desítku účinných funkcí na ochranu soukromí, které většina oblíbených prohlížečů ve výchozím nastavení nenabízí. Tahle jedinečná komplexní sada na ochranu soukromí pomáhá chránit tvoje aktivity na internetu od vyhledávání přes prohlížení až po posílání e-mailů.\n\nAby naše ochrana soukromí fungovala, nemusíš znát technické detaily ani řešit žádná složitá nastavení. Stačí přejít na prohlížeč DuckDuckGo ve všech zařízeních a dostaneš soukromí pro všechny své aktivity.\n\nJestli chceš nahlédnout pod pokličku, víc informací o tom, jak ochrana soukromí DuckDuckGo funguje, najdeš v naší nápovědě. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo je nezávislá společnost založená v roce 2008, která se zabývá ochranou soukromí pro všechny, kdo už mají dost sledování na internetu a chtějí snadné řešení. Jsme důkazem, že skutečná ochrana soukromí na internetu nemusí mít kompromisy.\n\nProhlížeč DuckDuckGo má všechno, co od prohlížeče očekáváš, jako jsou záložky, karty, hesla a další funkce. A k tomu má víc než desítku účinných funkcí na ochranu soukromí, které většina oblíbených prohlížečů ve výchozím nastavení nenabízí. Tahle jedinečná komplexní sada na ochranu soukromí pomáhá chránit tvoje aktivity na internetu od vyhledávání přes prohlížení až po posílání e-mailů.\n\nAby naše ochrana soukromí fungovala, nemusíš znát technické detaily ani řešit žádná složitá nastavení. Stačí přejít na prohlížeč DuckDuckGo ve všech zařízeních a dostaneš soukromí pro všechny své aktivity.\n\nJestli chceš nahlédnout pod pokličku, víc informací o tom, jak ochrana soukromí DuckDuckGo funguje, najdeš v naší nápovědě. Žádné návrhy @@ -702,7 +702,7 @@ Hesla - Hesla a automatické vyplňování + Hesla a automatické vyplňování Heslo je uložené Heslo je aktualizované diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index d52b38933a8a..fe84551a3e7c 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -125,7 +125,7 @@ Indstillinger Indstillinger Privatliv - Beskyttelse af privatlivet + Beskyttelse af privatlivet udseende Tilpas Omkring @@ -135,7 +135,7 @@ E-mailbeskyttelse Bloker e-mailtrackere, og skjul din adresse Mere fra DuckDuckGo - Næste trin + Næste trin Let Tema Mørk @@ -158,15 +158,15 @@ Beskyttelse mod sporing på nettet Aktiveret som standard Indstillinger - Generelle indstillinger + Generelle indstillinger Tilladelser Synkronisering og sikkerhedskopiering Fire Button - Datarydning - Tilføj widget til startskærmen - Angiv placeringen af adresselinjen - Aktivér stemmesøgning - DuckDuckGo på andre platforme + Datarydning + Tilføj widget til startskærmen + Angiv placeringen af adresselinjen + Aktivér stemmesøgning + DuckDuckGo på andre platforme Privat søgning @@ -192,7 +192,7 @@ Beskyttelse mod sporing på nettet Beskyttelse mod sporing på nettet er aktiveret Lær mere]]> - Learn More]]> + Mere info]]> Beskyttelse mod pop op-beskeder om cookies @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Datarydning Tilladelser @@ -213,7 +213,7 @@ Gem Ryd automatisk … - Automatically Clear Data… + Ryd data automatisk… Ryd automatisk … Ingen Faner @@ -230,10 +230,10 @@ Om DuckDuckGo - About + Omkring Velkommen til Duck siden DuckDuckGo er en uafhængig virksomhed, grundlagt i 2008, der beskytter privatlivet på internettet for alle, der er trætte af at blive sporet online og ønsker en nem løsning. Vi er bevis på, at du kan få ægte beskyttelse af privatlivet online uden at gå på kompromis.\n\nDuckDuckGo-browseren kommer med de funktioner, du forventer af en standardbrowser, som bogmærker, faner, adgangskoder og meget mere, plus over et dusin kraftfulde beskyttelser af privatlivet, som ikke tilbydes i de fleste populære browsere som standard. Dette unikke og omfattende sæt af beskyttelsesfunktioner hjælper med at beskytte dine onlineaktiviteter, fra søgning til browsing, e-mailing og meget mere.\n\nVores beskyttelse af privatlivet fungerer, uden at du behøver at vide noget om de tekniske detaljer eller håndtere komplicerede indstillinger. Det eneste, du skal gøre, er at skifte din browser til DuckDuckGo på alle dine enheder, så får du privatliv som standard.\n\nMen hvis du gerne vil have et kig under motorhjelmen, kan du finde flere oplysninger om, hvordan DuckDuckGos beskyttelse af privatlivet fungerer, på vores hjælpesider - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo er det uafhængige internetprivatlivsfirma, grundlagt i 2008, for alle, der er trætte af at blive sporet online og ønsker en nem løsning. Vi er bevis på, at du kan få ægte beskyttelse af privatlivet online uden at gå på kompromis.\n\nDuckDuckGo-browseren kommer med de funktioner, du forventer af en standardbrowser, som bogmærker, faner, adgangskoder og meget mere, plus over et dusin kraftfulde beskyttelser af privatlivet, som ikke tilbydes i de fleste populære browsere som standard. Dette unikke og omfattende sæt af beskyttelsesfunktioner hjælper med at beskytte dine onlineaktiviteter, fra søgning til browsing, e-mailing og meget mere.\n\nVores beskyttelse af privatlivet fungerer, uden at du behøver at vide noget om de tekniske detaljer eller håndtere komplicerede indstillinger. Det eneste, du skal gøre, er at skifte din browser til DuckDuckGo på alle dine enheder, så får du privatliv som standard.\n\nMen hvis du gerne vil have et kig under motorhjelmen, kan du finde flere oplysninger om, hvordan DuckDuckGos beskyttelse af privatlivet fungerer, på vores hjælpesider Ingen forslag @@ -702,7 +702,7 @@ Adgangskoder - Adgangskoder og automatisk udfyldning + Adgangskoder og automatisk udfyldning Adgangskode gemt Adgangskode opdateret diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 18d2439fd6e4..185c9c7de9cc 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -125,7 +125,7 @@ Einstellungen Einstellungen Privatsphäre - Datenschutz + Datenschutz Aussehen Anpassen Über @@ -135,7 +135,7 @@ E-Mail-Schutz E-Mail-Tracker blockieren und deine Adresse verbergen Mehr von DuckDuckGo - Nächste Schritte + Nächste Schritte Hell Thema Dunkel @@ -158,15 +158,15 @@ Web Tracking Protection Standardmäßig aktiviert Einstellungen - Haupteinstellungen + Haupteinstellungen Berechtigungen Synchronisieren und sichern Fire Button - Datenlöschung - Widget zum Startbildschirm hinzufügen - Position deiner Adressleiste festlegen - Sprachsuche aktivieren - DuckDuckGo auf anderen Plattformen + Datenlöschung + Widget zum Startbildschirm hinzufügen + Position deiner Adressleiste festlegen + Sprachsuche aktivieren + DuckDuckGo auf anderen Plattformen Private Suche @@ -192,7 +192,7 @@ Web Tracking Protection Web Tracking Protection ist aktiviert Mehr erfahren]]> - Learn More]]> + Mehr erfahren]]> Cookie-Pop-up-Schutz @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Datenlöschung Berechtigungen @@ -213,7 +213,7 @@ Speichern Automatisches Löschen von … - Automatically Clear Data… + Daten automatisch löschen … Automatisches Löschen von … Gar nichts Tabs @@ -230,10 +230,10 @@ Über DuckDuckGo - About + Über Willkommen auf der Duck-len Seite! DuckDuckGo ist die unabhängige Firma für Internet-Datenschutz, das 2008 für alle gegründet wurde, die es leid sind, online getrackt zu werden, und eine einfache Lösung suchen. Wir sind der Beweis, dass du echten Online-Datenschutz ohne Kompromisse erhalten kannst.\n\nDer DuckDuckGo-Browser verfügt über die Funktionen, die von einem Go-to-Browser erwartet werden, darunter Lesezeichen, Tabs, Passwörter und mehr. Hinzu kommen über ein Dutzend leistungsstarke Datenschutzfunktionen, die in den meisten gängigen Browsern standardmäßig nicht angeboten werden. Dieser einzigartige, umfassende Datenschutz hilft dir, deine Online-Aktivitäten zu schützen – von der Suche über das Browsen bis hin zu E-Mails und vielem mehr.\n\nUnser Datenschutz funktioniert, ohne dass du etwas über die technischen Details wissen oder dich mit komplizierten Einstellungen auseinandersetzen musst. Du musst lediglich den Browser auf allen deinen Geräten auf DuckDuckGo umstellen und schon erhältst du echte Privatsphäre als Standard.\n\nWenn du jedoch einen Blick unter die Haube werfen möchtest, findest du auf unseren Hilfeseiten mehr Informationen darüber, wie der Datenschutz bei DuckDuckGo funktioniert. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo ist die unabhängige Firma für Internet-Datenschutz, die 2008 für alle gegründet wurde, die es leid sind, online getrackt zu werden, und eine einfache Lösung suchen. Wir sind der Beweis, dass du echten Online-Datenschutz ohne Kompromisse erhalten kannst.\n\nDer DuckDuckGo-Browser verfügt über die Funktionen, die du von deinem bevorzugten Browser erwartest, darunter Lesezeichen, Tabs, Passwörter und mehr. Hinzu kommen über ein Dutzend leistungsstarke Datenschutzfunktionen, die in den meisten gängigen Browsern standardmäßig nicht angeboten werden. Dieser einzigartige, umfassende Datenschutz hilft dir, deine Online-Aktivitäten zu schützen – von der Suche über das Browsen bis hin zu E-Mails und vielem mehr.\n\nUnser Datenschutz funktioniert, ohne dass du etwas über die technischen Details wissen oder dich mit komplizierten Einstellungen auseinandersetzen musst. Du musst lediglich den Browser auf allen deinen Geräten auf DuckDuckGo umstellen und schon erhältst du echte Privatsphäre als Standard.\n\nWenn du jedoch einen Blick hinter die Kulissen werfen möchtest, findest du auf unseren Hilfeseiten mehr Informationen darüber, wie der Datenschutz bei DuckDuckGo funktioniert. Keine Vorschläge @@ -702,7 +702,7 @@ Passwörter - Passwörter und Autovervollständigen + Passwörter und Autovervollständigen Passwort gespeichert Passwort aktualisiert diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 6e3a7d380d09..1cf111eaa565 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -125,7 +125,7 @@ Ρυθμίσεις Ρυθμίσεις Ιδιωτικότητα - Προστασία προσωπικών δεδομένων + Προστασία προσωπικών δεδομένων Εμφάνιση Προσαρμογή Σχετικά @@ -135,7 +135,7 @@ Προστασία email Αποκλείστε εφαρμογές παρακολούθησης email και αποκρύψτε τη διεύθυνσή σας Περισσότερα από το DuckDuckGo - Επόμενα βήματα + Επόμενα βήματα Φωτεινό Θέμα Σκοτεινό @@ -158,15 +158,15 @@ Προστασία παρακολούθησης ιστού Ενεργοποιημένο βάσει προεπιλογής Ρυθμίσεις - Κύριες ρυθμίσεις + Κύριες ρυθμίσεις Δικαιώματα Συγχρονισμός και δημιουργία αντιγράφων ασφαλείας Κουμπί Φωτιά - Διαγραφή δεδομένων - Προσθήκη μικροεφαρμογής στην Αρχική οθόνη - Ορίστε τη θέση της γραμμής διευθύνσεών σας - Ενεργοποίηση φωνητικής αναζήτησης - Το DuckDuckGo σε άλλες πλατφόρμες + Διαγραφή δεδομένων + Προσθήκη μικροεφαρμογής στην Αρχική οθόνη + Ορίστε τη θέση της γραμμής διευθύνσεών σας + Ενεργοποίηση φωνητικής αναζήτησης + Το DuckDuckGo σε άλλες πλατφόρμες ιδιωτική αναζήτηση @@ -192,7 +192,7 @@ Προστασία παρακολούθησης ιστού Η προστασία παρακολούθησης ιστού είναι ενεργοποιημένη Μάθετε περισσότερα]]> - Learn More]]> + Μάθετε περισσότερα]]> Προστασία αναδυόμενων παραθύρων για cookies @@ -201,7 +201,7 @@ Κουμπί Φωτιά - Data Clearing + Διαγραφή δεδομένων Δικαιώματα @@ -213,7 +213,7 @@ Αποθήκευση Αυτόματη εκκαθάριση… - Automatically Clear Data… + Αυτόματη απαλοιφή δεδομένων... Αυτόματη εκκαθάριση… Κανένα Καρτέλες @@ -230,10 +230,10 @@ Σχετικά με το DuckDuckGo - About + Σχετικά Καλωσορίσατε στην πλευρά της Πάπιας! Το DuckDuckGo αποτελεί την ανεξάρτητη εταιρεία προστασίας προσωπικών δεδομένων στο διαδίκτυο που ιδρύθηκε το 2008 για όσους έχουν βαρεθεί να παρακολουθούνται στο διαδίκτυο και επιθυμούν μια εύκολη λύση. Αποτελούμε τρανή απόδειξη ότι μπορείτε να αποκτήσετε πραγματική προστασία του απορρήτου σας στο διαδίκτυο χωρίς συμβιβασμούς.\n\nΤο πρόγραμμα περιήγησης DuckDuckGo διαθέτει τις λειτουργίες που περιμένετε από ένα πρόγραμμα περιήγησης, όπως σελιδοδείκτες, καρτέλες, κωδικούς πρόσβασης και πολλά άλλα, καθώς και πάνω από δώδεκα ισχυρές λειτουργίες προστασίας απορρήτου που δεν προσφέρονται από τα περισσότερα δημοφιλή προγράμματα περιήγησης βάσει προεπιλογής. Αυτό το μοναδικά ολοκληρωμένο σύνολο προστασίας του απορρήτου συμβάλλει στην προστασία των διαδικτυακών δραστηριοτήτων σας, από αναζήτηση έως περιήγηση, αποστολή email και πολλά άλλα.\n\nΗ προστασία απορρήτου μας λειτουργεί χωρίς να χρειάζεται να γνωρίζετε τις τεχνικές λεπτομέρειες ή να ασχολείστε με περίπλοκες ρυθμίσεις. Το μόνο που έχετε να κάνετε είναι να αλλάξετε το πρόγραμμα περιήγησής σας σε DuckDuckGo σε όλες τις συσκευές σας και θα έχετε ιδιωτικότητα βάσει προεπιλογής.\n\nΑλλά αν θέλετε να ρίξετε μια αναλυτική ματιά, μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με το πώς λειτουργούν οι προστασίες απορρήτου του DuckDuckGo στις σελίδες της ενότητας Βοήθεια - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + Το DuckDuckGo αποτελεί την ανεξάρτητη εταιρεία προστασίας προσωπικών δεδομένων στο διαδίκτυο που ιδρύθηκε το 2008 για όσους έχουν βαρεθεί να παρακολουθούνται στο διαδίκτυο και επιθυμούν μια εύκολη λύση. Αποτελούμε τρανή απόδειξη ότι μπορείτε να αποκτήσετε πραγματική προστασία του απορρήτου σας στο διαδίκτυο χωρίς συμβιβασμούς.\n\nΤο πρόγραμμα περιήγησης DuckDuckGo διαθέτει τις λειτουργίες που περιμένετε από ένα πρόγραμμα περιήγησης, όπως σελιδοδείκτες, καρτέλες, κωδικούς πρόσβασης και πολλά άλλα, καθώς και πάνω από δώδεκα ισχυρές λειτουργίες προστασίας απορρήτου που δεν προσφέρονται από τα περισσότερα δημοφιλή προγράμματα περιήγησης βάσει προεπιλογής. Αυτό το μοναδικά ολοκληρωμένο σύνολο προστασίας του απορρήτου συμβάλλει στην προστασία των διαδικτυακών δραστηριοτήτων σας, από αναζήτηση έως περιήγηση, αποστολή email και πολλά άλλα.\n\nΗ προστασία απορρήτου μας λειτουργεί χωρίς να χρειάζεται να γνωρίζετε τις τεχνικές λεπτομέρειες ή να ασχολείστε με περίπλοκες ρυθμίσεις. Το μόνο που έχετε να κάνετε είναι να αλλάξετε το πρόγραμμα περιήγησής σας σε DuckDuckGo σε όλες τις συσκευές σας και θα έχετε ιδιωτικότητα βάσει προεπιλογής.\n\nΑλλά αν θέλετε να ρίξετε μια αναλυτική ματιά, μπορείτε να βρείτε περισσότερες πληροφορίες σχετικά με το πώς λειτουργούν οι προστασίες απορρήτου του DuckDuckGo στις σελίδες της ενότητας Βοήθεια Δεν υπάρχουν προτάσεις @@ -702,7 +702,7 @@ Κωδικοί πρόσβασης - Κωδικοί πρόσβασης και Αυτόματη συμπλήρωση + Κωδικοί πρόσβασης και Αυτόματη συμπλήρωση Αποθηκευμένος κωδικός πρόσβασης Ο κωδικός πρόσβασης ενημερώθηκε diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6d7a8b9c355a..c112cef65c27 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -125,7 +125,7 @@ Ajustes Ajustes Privacidad - Protecciones de privacidad + Protecciones de privacidad Apariencia Personalizar Sobre @@ -135,7 +135,7 @@ Protección del correo electrónico Bloquea los rastreadores de correo electrónico y oculta tu dirección Más sobre DuckDuckGo - Próximos pasos + Próximos pasos Claro Temas Oscuro @@ -158,15 +158,15 @@ Protección de rastreo en la web Habilitado de forma predeterminada Ajustes - Ajustes principales + Ajustes principales Permisos Sincronización y copia de seguridad Fire Button - Eliminación de datos - Añadir widget a la pantalla de inicio - Establece la posición de la barra de direcciones - Habilitar búsqueda por voz - DuckDuckGo en otras plataformas + Eliminación de datos + Añadir widget a la pantalla de inicio + Establece la posición de la barra de direcciones + Habilitar búsqueda por voz + DuckDuckGo en otras plataformas Búsqueda Privada @@ -192,7 +192,7 @@ Protección de rastreo en la web La protección de rastreo en la web está habilitada Más información]]> - Learn More]]> + Más información]]> Protección contra ventanas emergentes de cookies @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Eliminación de datos Permisos @@ -213,7 +213,7 @@ Guardar Borrar automáticamente… - Automatically Clear Data… + Borrar datos automáticamente… Borrar automáticamente… Ninguno Pestañas @@ -230,10 +230,10 @@ Acerca de DuckDuckGo - About + Sobre Bienvenidas al \"Lado Pato\"! DuckDuckGo es la empresa de privacidad en internet independiente fundada en 2008 para quienes estén cansados de ser rastreados en línea y quieran una solución sencilla. Somos la prueba de que es posible obtener protección de privacidad real en línea sin concesiones.\n\nEl navegador DuckDuckGo incluye las funciones que esperas de un navegador de referencia, como favoritos, pestañas, contraseñas y más, así como más de una docena de potentes funciones de protección de privacidad que no ofrecen los navegadores más populares de forma predeterminada. Este conjunto completo de funciones de protección de privacidad ayuda a proteger tu actividad en línea, desde la búsqueda hasta la navegación, el correo electrónico y mucho más.\n\nNuestra protección de privacidad funciona sin necesidad de conocimientos técnicos y sin tener que lidiar con configuraciones complicadas. Lo único que tienes que hacer es cambiar el navegador a DuckDuckGo en todos tus dispositivos y obtener privacidad de forma predeterminada.\n\nSin embargo, si quieres conocer los entresijos, puedes encontrar más información sobre cómo funciona la protección de privacidad de DuckDuckGo en nuestras páginas de ayuda - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo es la empresa de privacidad en internet independiente fundada en 2008 para quienes estén cansados de ser rastreados en línea y quieran una solución sencilla. Somos la prueba de que es posible obtener protección de privacidad real en línea sin concesiones.\n\nEl navegador DuckDuckGo incluye las funciones que esperas de un navegador de referencia, como favoritos, pestañas, contraseñas y más, así como más de una docena de potentes funciones de protección de privacidad que no ofrecen los navegadores más populares de forma predeterminada. Este conjunto completo de funciones de protección de privacidad ayuda a proteger tu actividad en línea, desde la búsqueda hasta la navegación, el correo electrónico y mucho más.\n\nNuestra protección de privacidad funciona sin necesidad de conocimientos técnicos y sin tener que lidiar con configuraciones complicadas. Lo único que tienes que hacer es cambiar el navegador a DuckDuckGo en todos tus dispositivos y obtener privacidad de forma predeterminada.\n\nSin embargo, si quieres conocer los entresijos, puedes encontrar más información sobre cómo funciona la protección de privacidad de DuckDuckGo en nuestras páginas de ayuda No hay sugerencias @@ -702,7 +702,7 @@ Contraseñas - Contraseñas y autocompletar + Contraseñas y autocompletar Contraseña guardada Contraseña actualizada diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 0f050b0aa069..b48f3acf6661 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -125,7 +125,7 @@ Sätted Sätted Privaatsus - Privaatsuskaitsed + Privaatsuskaitsed Välimus Kohanda Teave @@ -135,7 +135,7 @@ E-posti kaitse Blokeeri meilijälgurid ja peida oma aadress Veel DuckDuckGo\'lt - Järgmised sammud + Järgmised sammud Hele Teema Tume @@ -158,15 +158,15 @@ Veebijälgimise kaitse Vaikimisi sisse lülitatud Sätted - Peamised seaded + Peamised seaded Load Sünkroonimine ja varundamine Fire Button - Andmete kustutamine - Lisa vidin avakuvale - Määra aadressiriba asukoht - Luba häälotsing - DuckDuckGo muudel platvormidel + Andmete kustutamine + Lisa vidin avakuvale + Määra aadressiriba asukoht + Luba häälotsing + DuckDuckGo muudel platvormidel Privaatne otsing @@ -192,7 +192,7 @@ Veebijälgimise kaitse Veebijälgimise kaitse on lubatud Lisateave]]> - Learn More]]> + Loe edasi]]> Küpsiste hüpikakna kaitse @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Andmete kustutamine Load @@ -213,7 +213,7 @@ Salvesta Kustuta automaatselt… - Automatically Clear Data… + Kustuta andmed automaatselt… Kustuta automaatselt… Puudub Vahelehed @@ -230,10 +230,10 @@ DuckDuckGo\'st - About + Teave Tere tulemast Pardipoolele! DuckDuckGo on 2008. aastal asutatud sõltumatu internetiprivaatsuse ettevõte igaühele, kellel on kõrini varjatud jälgimisest internetis ja kes soovib lihtsat lahendust selle vältimiseks. Me oleme tõestuseks, et internetis on võimalik saada tõelist privaatsuskaitset ilma kompromisse tegemata.\n\nDuckDuckGo brauseril on kõik funktsioonid, mida sa brauserilt ootad, nagu järjehoidjad, vahekaardid, paroolid ja palju muud, lisaks sellele aga ka üle tosina võimsa privaatsuskaitse funktsiooni, mida enamik populaarsemaid brausereid vaikimisi ei paku. See ainulaadselt terviklik privaatsuskaitse aitab kaitsta sinu tegevust internetis alates otsingutest kuni sirvimiseni, meilide saatmiseni ja palju muuni.\n\nMeie privaatsuskaitse toimib ilma, et peaks teadma midagi tehnilistest nüanssidest või tegelema keeruliste seadistustega. Ainus, mis sa pead tegema, on vahetada oma brauser kõigis seadmetes DuckDuckGo vastu – ja vaikeprivaatsus ongi tagatud.\n\nKui aga soovid piiluda kapoti alla, leiad lisateavet DuckDuckGo privaatsuskaitse tööpõhimõtete kohta meie abilehtedelt - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo on 2008. aastal asutatud sõltumatu internetiprivaatsuse ettevõte kõigile, kes on väsinud jälgimisest internetis ja soovivad lihtsat lahendust. Me oleme tõestuseks, et internetis on võimalik saada tõelist privaatsuskaitset ilma kompromisse tegemata.\n\nDuckDuckGo brauseril on kõik funktsioonid, mida sa brauserilt ootad, nagu järjehoidjad, vahekaardid, paroolid ja palju muud, lisaks sellele aga ka üle tosina võimsa privaatsuskaitse, mida enamik populaarsemaid brausereid vaikimisi ei paku. See ainulaadselt terviklik privaatsuskaitsekomplekt aitab kaitsta sinu tegevusi internetis, alates otsingutest kuni sirvimiseni, meilide saatmiseni ja palju muuni.\n\nMeie privaatsuskaitse toimib ilma, et peaksid teadma midagi tehnilistest nüanssidest või tegelema keeruliste seadistustega. Ainus, mida sa pead tegema, on vahetada oma brauser kõigis seadmetes DuckDuckGo vastu ja vaikeprivaatsus on tagatud.\n\nKui aga soovid piiluda kapoti alla, leiad lisateavet DuckDuckGo privaatsuskaitse tööpõhimõtete kohta meie abilehtedelt Ettepanekud puuduvad @@ -702,7 +702,7 @@ Paroolid - Paroolid ja automaatne täitmine + Paroolid ja automaatne täitmine Parool salvestatud Parool uuendatud diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index f6603cea34ef..66af8f933dc6 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -125,7 +125,7 @@ Asetukset Asetukset Tietosuoja - Yksityisyyden suoja + Yksityisyyden suoja Ulkoasu Mukauta Tietoa meistä @@ -135,7 +135,7 @@ Sähköpostisuojaus Estä sähköpostiseuraajat ja piilota osoitteesi Lisää DuckDuckGolta - Seuraavat vaiheet + Seuraavat vaiheet Vaalea Teema Tumma @@ -158,15 +158,15 @@ Verkkoseurannan suojaus Oletusarvoisesti käytössä Asetukset - Pääasetukset + Pääasetukset Käyttöoikeudet Synkronoi ja varmuuskopioi Fire-painike - Datan tyhjentäminen - Lisää widget aloitusnäyttöön - Aseta osoitekentän sijainti - Ota käyttöön äänihaku - DuckDuckGo muilla alustoilla + Datan tyhjentäminen + Lisää widget aloitusnäyttöön + Aseta osoitekentän sijainti + Ota käyttöön äänihaku + DuckDuckGo muilla alustoilla Yksityinen haku @@ -192,7 +192,7 @@ Verkkoseurannan suojaus Verkkoseurantasuojaus on käytössä Lisätietoja]]> - Learn More]]> + Lue lisää]]> Evästeiden ponnahdusikkuna -suojaus @@ -201,7 +201,7 @@ Fire-painike - Data Clearing + Datan tyhjentäminen Käyttöoikeudet @@ -213,7 +213,7 @@ Tallenna Tyhjennä automaattisesti… - Automatically Clear Data… + Tyhjennä tiedot automaattisesti... Tyhjennä automaattisesti… Ei mitään Välilehdet @@ -230,10 +230,10 @@ Tietoa DuckDuckGo:sta - About + Tietoa meistä Tervetuloa Duckin puolelle! DuckDuckGo on vuonna 2008 perustettu riippumaton internetissä tietosuojaa tarjoava yritys niille, jotka ovat kyllästyneet siihen, että heitä seurataan netissä, ja haluavat yksinkertaisen ratkaisun. Olemme todiste siitä, että voit saada todellista tietosuojaa verkossa ilman kompromisseja.\n\nDuckDuckGo-selaimessa on kaikki parhaiden selainten ominaisuudet, kuten kirjanmerkit, välilehdet, salasanat ja paljon muuta, sekä yli kymmenkunta tehokasta tietosuojausta, joita ei ole oletuksena useimmissa suosituissa selaimissa. Tämä ainutlaatuisen kattava tietosuoja auttaa turvaamaan haut, selaamisen, sähköpostin lähettämiseen ja muun toimintasi verkossa.\n\nTietosuojamme toimivat, vaikka et tietäisi mitään teknisistä yksityiskohdista tai osaisi käsitellä monimutkaisia asetuksia. Sinun tarvitsee vain vaihtaa selaimesi DuckDuckGohon kaikilla laitteillasi, ja saat tietosuojan oletuksena.\n\nJos kuitenkin haluat kurkistaa konepellin alle, lisätietoja DuckDuckGon tietosuojan toiminnasta on ohjesivuillamme. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo on vuonna 2008 perustettu riippumaton internetin tietosuoja-alan yritys kaikille, jotka ovat kyllästyneet siihen, että heitä seurataan verkossa, ja haluavat helpon ratkaisun. Olemme todiste siitä, että voit saada todellista tietosuojaa verkossa ilman kompromisseja.\n\nDuckDuckGo-selaimessa on kaikki selainten perusominaisuudet, kuten kirjanmerkit, välilehdet ja salasanat, sekä yli kymmenen tehokasta tietosuojausta, joita ei ole oletuksena useimmissa suosituissa selaimissa. Tämä ainutlaatuisen kattava tietosuojapaketti auttaa suojaamaan verkkoaktiviteettisi, kuten hakemisen, selaamisen ja sähköpostin lähettämisen.\n\nTietosuojamme toimivat, vaikka et tietäisi mitään teknisistä yksityiskohdista tai osaisi käsitellä monimutkaisia asetuksia. Sinun tarvitsee vain vaihtaa selaimesi DuckDuckGohon kaikissa laitteissasi, ja saat tietosuojan oletuksena.\n\nJos kuitenkin haluat kurkistaa konepellin alle, löydät lisätietoja DuckDuckGon tietosuojan toiminnasta on ohjesivuiltamme. Ei ehdotuksia @@ -702,7 +702,7 @@ Salasanat - Salasanat ja automaattinen täyttö + Salasanat ja automaattinen täyttö Salasana tallennettu Salasana päivitetty diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 54ccc021f15d..742463b18ff4 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -125,7 +125,7 @@ Paramètres Paramètres Confidentialité - Protections de la confidentialité + Protections de la confidentialité Apparence Personnaliser À propos @@ -135,7 +135,7 @@ Protection des e-mails Bloquez les traqueurs d\'e-mails et masquez votre adresse Plus de la part de DuckDuckGo - Étapes suivantes + Étapes suivantes Clair Thème Sombre @@ -158,15 +158,15 @@ Protection contre le pistage sur le Web Activation par défaut Paramètres - Réglages principaux + Réglages principaux Autorisations Synchronisation et sauvegarde Fire Button - Effacement des données - Ajouter le widget à l\'écran d\'accueil - Définissez la position de votre barre d\'adresse - Activez la recherche vocale - DuckDuckGo sur d\'autres plateformes + Effacement des données + Ajouter le widget à l\'écran d\'accueil + Définissez la position de votre barre d\'adresse + Activez la recherche vocale + DuckDuckGo sur d\'autres plateformes Recherche privée @@ -192,7 +192,7 @@ Protection contre le pistage sur le Web La protection contre le pistage sur le Web est activée En savoir plus]]> - Learn More]]> + En savoir plus]]> Protection contre les fenêtres contextuelles des cookies @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Effacement des données Autorisations @@ -213,7 +213,7 @@ Enregistrer Effacer automatiquement… - Automatically Clear Data… + Effacer automatiquement les données… Effacer automatiquement… Aucune Onglets @@ -230,10 +230,10 @@ À propos de DuckDuckGo - About + À propos Bienvenue du côté Duck ! DuckDuckGo est une société indépendante de confidentialité sur internet fondée en 2008, destinée à tous ceux qui en ont assez d\'être suivis en ligne et qui veulent une solution simple. Nous sommes la preuve que vous pouvez bénéficier d\'une véritable protection de la confidentialité en ligne, sans avoir à faire de compromis.\n\nLe navigateur DuckDuckGo est doté des fonctionnalités que vous attendez d\'un navigateur de référence, comme les signets, les onglets et les mots de passe, entre autres, auxquels s\'ajoutent plus d\'une douzaine de protections puissantes de la confidentialité que la plupart des navigateurs populaires ne proposent pas par défaut.Cet ensemble unique et complet de protections de la confidentialité permet de préserver vos activités en ligne, de la recherche à la navigation, en passant par l\'envoi d\'e-mails, etc.\n\nInutile de s\'y connaître en détails techniques ou de gérer des paramètres complexes pour faire fonctionner nos protections de la confidentialité. Il vous suffit d\'opter pour le navigateur DuckDuckGo sur tous vos appareils afin de pouvoir bénéficier de la confidentialité par défaut.\n\nMais si vous voulez vous faire une idée, vous trouverez plus d\'informations sur le fonctionnement des protections de la confidentialité DuckDuckGo sur nos pages d\'aide - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo est une société indépendante de confidentialité sur internet fondée en 2008, destinée à tous ceux qui en ont assez d\'être suivis en ligne et qui veulent une solution simple. Nous sommes la preuve que vous pouvez bénéficier d\'une véritable protection de la confidentialité en ligne, sans avoir à faire de compromis.\n\nLe navigateur DuckDuckGo est doté des fonctionnalités que vous attendez d\'un navigateur de référence, comme les signets, les onglets et les mots de passe, entre autres, auxquels s\'ajoutent plus d\'une douzaine de protections puissantes de la confidentialité que la plupart des navigateurs populaires ne proposent pas par défaut. Cet ensemble unique et complet de protections de la confidentialité permet de préserver vos activités en ligne, de la recherche à la navigation, en passant par l\'envoi d\'e-mails, etc.\n\nInutile de s\'y connaître en détails techniques ou de gérer des paramètres complexes pour faire fonctionner nos protections de la confidentialité. Il vous suffit d\'opter pour le navigateur DuckDuckGo sur tous vos appareils afin de pouvoir bénéficier de la confidentialité par défaut.\n\nMais si vous voulez vous faire une idée, vous trouverez plus d\'informations sur le fonctionnement des protections de la confidentialité DuckDuckGo sur nos pages d\'aide Aucune suggestion @@ -702,7 +702,7 @@ Mots de passe - Mots de passe et saisie automatique + Mots de passe et saisie automatique Le mot de passe a été enregistré Le mot de passe a été modifié diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index e3ed8bb26d06..59257f9b1974 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -125,7 +125,7 @@ Postavke Postavke Zaštita privatnosti - Zaštita privatnosti + Zaštita privatnosti Izgled Prilagodba O @@ -135,7 +135,7 @@ Zaštita e-pošte Blokiraj programe za praćenje e-pošte i sakrij svoju adresu Više od DuckDuckGoa - Sljedeći koraci + Sljedeći koraci Svijetla Tema Tamna @@ -158,15 +158,15 @@ Zaštita od praćenja na webu Omogućeno prema zadanim postavkama Postavke - Glavne postavke + Glavne postavke Dozvole Sinkronizacija i sigurnosno kopiranje Fire Button - Brisanje podataka - Dodajte widget na početni zaslon - Postavi položaj adresne trake - Omogući glasovno pretraživanje - DuckDuckGo na drugim platformama + Brisanje podataka + Dodajte widget na početni zaslon + Postavi položaj adresne trake + Omogući glasovno pretraživanje + DuckDuckGo na drugim platformama Privatno pretraživanje @@ -192,7 +192,7 @@ Zaštita od praćenja na webu Zaštita od praćenja na webu je omogućena Saznaj više]]> - Learn More]]> + Saznaj više]]> Zaštita od skočnih prozora kolačića @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Brisanje podataka Dozvole @@ -213,7 +213,7 @@ Spremi Automatski obriši… - Automatically Clear Data… + Automatsko brisanje podataka… Automatski obriši… Nijedno Kartice @@ -230,10 +230,10 @@ O DuckDuckGou - About + O Dobrodošli na našu stranu! DuckDuckGo neovisna je tvrtka za privatnost na internetu osnovana 2008. godine namijenjena svakome tko je umoran od toga da ga prate na internetu i želi jednostavno rješenje za to. Mi smo dokaz da je prava zaštita privatnosti na internetu moguća bez kompromisa.\n\nPreglednik DuckDuckGo dolazi sa značajkama koje očekuješ od preglednika, poput oznaka, kartica, lozinki i još mnogo toga; ali uz to, pruža se više od desetak moćnih zaštita privatnosti koje se zadano ne nude u najpopularnijim preglednicima. Ovaj jedinstveno sveobuhvatan skup zaštite privatnosti pomaže u zaštiti tvojih mrežnih aktivnosti, od pretraživanja do pregledavanja, slanja e-pošte i još mnogo toga.\n\nNaša zaštita privatnosti funkcionira bez potrebe da znamo bilo što o tehničkim detaljima ili da se bavimo kompliciranim postavkama. Sve što trebaš učiniti jest prebaciti svoj preglednik na DuckDuckGo na svim svojim uređajima i prema zadanim postavkama dobivaš našu zaštitu privatnosti.\n\nAli ako želiš \"zaviriti ispod haube\", više informacija o tome kako DuckDuckGo zaštita privatnosti funkcionira možeš pronaći na našim stranicama pomoći - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo je neovisna tvrtka za privatnost na internetu osnovana 2008. godine za sve koji su umorni od praćenja na internetu i žele jednostavno rješenje. Mi smo dokaz da možeš dobiti pravu zaštitu privatnosti na internetu, bez kompromisa.\n\nPreglednik DuckDuckGo sadrži značajke koje očekuješ od preglednika, poput oznaka, kartica, lozinki i još mnogo toga; ali uz to, pruža se više od desetak moćnih zaštita privatnosti koje se zadano ne nude u najpopularnijim preglednicima. Ovaj jedinstveno sveobuhvatan skup zaštita privatnosti pomaže u zaštiti tvojih mrežnih aktivnosti, od pretraživanja do pregledavanja, slanja e-pošte i još mnogo toga.\n\nNaša zaštita privatnosti funkcionira bez potrebe da znamo bilo što o tehničkim detaljima ili da se bavimo kompliciranim postavkama. Sve što trebaš učiniti jest prebaciti svoj preglednik na DuckDuckGo na svim svojim uređajima i prema zadanim postavkama dobivaš našu zaštitu privatnosti.\n\nAli ako želiš \"zaviriti ispod haube\", više informacija o tome kako DuckDuckGo zaštita privatnosti funkcionira možeš pronaći na našim stranicama pomoći Nema prijedloga @@ -702,7 +702,7 @@ Lozinke - Lozinke i automatsko popunjavanje + Lozinke i automatsko popunjavanje Lozinka je spremljena Lozinka je ažurirana diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index ef40fe740b8b..d6e0ecc361ab 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -125,7 +125,7 @@ Beállítások Beállítások Adatvédelem - Adatvédelem + Adatvédelem Megjelenés Testreszabás További információ @@ -135,7 +135,7 @@ E-mail védelem E-mail nyomkövetők letiltása, és a cím elrejtése Továbbiak a DuckDuckGótól - Következő lépések + Következő lépések Világos Kinézet Sötét @@ -158,15 +158,15 @@ Webes követés elleni védelem Alapértelmezés szerint engedélyezve Beállítások - Főbeállítások + Főbeállítások Engedélyek Szinkronizálás és biztonsági mentés Tűz gomb - Adattörlés - Minialkalmazás hozzáadása a kezdőképernyőhöz - Állítsd be a címsor elhelyezkedését - Beszédhangalapú keresés engedélyezése - DuckDuckGo más platformokhoz + Adattörlés + Minialkalmazás hozzáadása a kezdőképernyőhöz + Állítsd be a címsor elhelyezkedését + Beszédhangalapú keresés engedélyezése + DuckDuckGo más platformokhoz Privát Keresés @@ -192,7 +192,7 @@ Webes követés elleni védelem A webes követés elleni védelem engedélyezve van További részletek]]> - Learn More]]> + További részletek]]> Felugró sütiablak elleni védelem @@ -201,7 +201,7 @@ Tűz gomb - Data Clearing + Adattörlés Engedélyek @@ -213,7 +213,7 @@ Mentés Automatikus törlés… - Automatically Clear Data… + Adatok automatikus törlése… Automatikus törlés… Nincs Lapok @@ -230,10 +230,10 @@ A DuckDuckGóról - About + További információ Isten hozott a Kacsa oldalon! A 2008-ban alapított független internetes adatvédelmi cég, a DuckDuckGo egyszerű megoldást kínál azoknak, akiknek elegük van abból, hogy állandóan nyomon követik őket az interneten. Mi vagyunk annak a bizonyítéka, hogy kompromisszumok nélkül is lehet valódi online adatvédelmet biztosítani.\n\nA DuckDuckGo böngésző rendelkezik a böngészőktől elvárt funkciókkal, mint például könyvjelzők, lapok, jelszavak és egyéb funkciók, valamint több mint egy tucat olyan hatékony adatvédelmi megoldással, amelyet a legtöbb népszerű böngésző nem kínál alapértelmezés szerint. Ezek az egyedülállóan átfogó adatvédelmi megoldások segítenek megvédeni online tevékenységeid, legyen szó keresésről, böngészésről, e-mailezésről vagy sok minden másról.\n\nAdatvédelmi megoldásaink anélkül működnek, hogy bármit is tudnod kellene a technikai részletekről vagy bonyolult beállításokkal kellene foglalkoznod. Mindössze annyit kell tenned, hogy minden eszközödön a DuckDuckGo böngészőre váltasz, és máris igénybe veheted az alapértelmezés szerinti adatvédelmet.\n\nHa azonban szeretnél bepillantani a motorháztető alá is, a súgóoldalainkon további információkat találhatsz a DuckDuckGo adatvédelmi megoldásainak működéséről. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + A 2008-ban alapított független internetes adatvédelmi cég, a DuckDuckGo egyszerű megoldást kínál azoknak, akiknek elegük van abból, hogy állandóan nyomon követik őket az interneten. Mi vagyunk annak a bizonyítéka, hogy kompromisszumok nélkül is lehet valódi online adatvédelmet biztosítani.\n\nA DuckDuckGo böngésző rendelkezik a böngészőktől elvárt funkciókkal, mint például könyvjelzők, lapok, jelszavak és egyéb funkciók, valamint több mint egy tucat olyan hatékony adatvédelmi megoldással, amelyet a legtöbb népszerű böngésző nem kínál alapértelmezés szerint. Ezek az egyedülállóan átfogó adatvédelmi megoldások segítenek megvédeni online tevékenységeid, legyen szó keresésről, böngészésről, e-mailezésről vagy sok minden másról.\n\nAdatvédelmi megoldásaink anélkül működnek, hogy bármit is tudnod kellene a technikai részletekről vagy bonyolult beállításokkal kellene foglalkoznod. Mindössze annyit kell tenned, hogy minden eszközödön a DuckDuckGo böngészőre váltasz, és máris igénybe veheted az alapértelmezés szerinti adatvédelmet.\n\nHa azonban szeretnél bepillantani a motorháztető alá is, a súgóoldalainkon további információkat találhatsz a DuckDuckGo adatvédelmi megoldásainak működéséről. Nincs javaslat @@ -702,7 +702,7 @@ Jelszavak - Jelszavak és automatikus kitöltés + Jelszavak és automatikus kitöltés Jelszó mentve Jelszó frissítve diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3a82c16bd0ed..6935fb532072 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -125,7 +125,7 @@ Impostazioni Impostazioni Privacy - Protezioni della Privacy + Protezioni della Privacy Aspetto Personalizza Informazioni @@ -135,7 +135,7 @@ Protezione email Blocca i sistemi di tracciamento delle email e nascondi il tuo indirizzo Ulteriori informazioni su DuckDuckGo - Passaggi successivi + Passaggi successivi Chiaro Tema Scuro @@ -158,15 +158,15 @@ Protezione dal tracciamento web Abilitato per impostazione predefinita Impostazioni - Impostazioni principali + Impostazioni principali Autorizzazioni Sincronizzazione e backup Fire Button - Cancellazione dati - Aggiungi widget alla schermata iniziale - Imposta la posizione della barra degli indirizzi - Abilita ricerca vocale - DuckDuckGo su altre piattaforme + Cancellazione dati + Aggiungi widget alla schermata iniziale + Imposta la posizione della barra degli indirizzi + Abilita ricerca vocale + DuckDuckGo su altre piattaforme Ricerca privata @@ -192,7 +192,7 @@ Protezione dal tracciamento web La protezione dal tracciamento Web è abilitata Ulteriori informazioni]]> - Learn More]]> + Ulteriori informazioni]]> Protezione pop-up dei cookie @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Cancellazione dati Autorizzazioni @@ -213,7 +213,7 @@ Salva Elimina automaticamente… - Automatically Clear Data… + Cancellazione automatica dei dati… Elimina automaticamente… Nessuno Schede @@ -230,10 +230,10 @@ Info su DuckDuckGo - About + Informazioni Dax the Duck ti dà il benvenuto! Fondata nel 2008, DuckDuckGo è un\'azienda indipendente che tutela la privacy online per tutti coloro che sono stanchi di essere tracciati online e vogliono una soluzione semplice. Siamo la dimostrazione che si può garantire una vera protezione della privacy online senza compromessi.\n\nIl browser DuckDuckGo è ricco di funzioni essenziali come i segnalibri, le schede, le password e molto altro ancora, oltre a numerose e potenti protezioni della privacy che normalmente non vengono offerte dai browser più comuni. Stiamo parlando di uno straordinario set completo per la protezione della privacy, che aiuta a proteggere le attività online, dalla ricerca alla navigazione, alle e-mail e molto altro ancora.\n\nCon le nostre protezioni della privacy non è necessario conoscere particolari tecnici o dover affrontare configurazioni complesse. È sufficiente scegliere il browser DuckDuckGo su tutti i dispositivi personali per avere automaticamente garantita la privacy.\n\nPer saperne di più su come funzionano le protezioni della privacy di DuckDuckGo, è possibile consultare le nostre pagine di aiuto - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo è un\'azienda indipendente che tutela la privacy online fondata nel 2008 per tutti coloro che sono stanchi di essere tracciati online e vogliono una soluzione semplice. Puoi ottenere una vera protezione della privacy online senza compromessi.\n\nIl browser DuckDuckGo è ricco di funzioni essenziali come i segnalibri, le schede, le password e molto altro ancora, oltre a numerose e potenti protezioni della privacy che normalmente non vengono offerte dai browser più comuni. Stiamo parlando di uno straordinario set completo per la protezione della privacy, che aiuta a proteggere le attività online, dalla ricerca alla navigazione, alle e-mail e molto altro ancora.\n\nCon le nostre protezioni della privacy non è necessario conoscere particolari tecnici o affrontare configurazioni complesse. È sufficiente scegliere il browser DuckDuckGo su tutti i dispositivi personali per avere automaticamente garantita la privacy.\n\nPer saperne di più su come funzionano le protezioni della privacy di DuckDuckGo, è possibile consultare le nostre pagine di aiuto Nessun suggerimento @@ -702,7 +702,7 @@ Password - Password e compilazione automatica + Password e compilazione automatica Password salvata Password aggiornata diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index fc99c6757361..ebbc6f118e07 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -125,7 +125,7 @@ Nustatymai Nustatymai Privatumas - Privatumo apsaugos priemonės + Privatumo apsaugos priemonės Išvaizda Tinkinti Apie @@ -135,7 +135,7 @@ El. pašto apsauga Blokuokite el. laiškų sekimo priemones ir paslėpkite savo adresą Daugiau iš „DuckDuckGo“ - Tolesni veiksmai + Tolesni veiksmai Šviesi Tema Tamsi @@ -158,15 +158,15 @@ Apsauga nuo žiniatinklio sekimo Įjungta pagal numatytuosius nustatymus Nustatymai - Pagrindiniai nustatymai + Pagrindiniai nustatymai Leidimai Sinchronizuoti ir kurti atsarginę kopiją Mygtukas „Fire“ - Duomenų valymas - Įtraukti valdiklį į pagrindinį ekraną - Nustatykite adreso juostos padėtį - Įgalinti paiešką balsu - „DuckDuckGo“ kitose platformose + Duomenų valymas + Įtraukti valdiklį į pagrindinį ekraną + Nustatykite adreso juostos padėtį + Įgalinti paiešką balsu + „DuckDuckGo“ kitose platformose privati paieška @@ -192,7 +192,7 @@ Apsauga nuo žiniatinklio sekimo Žiniatinklio sekimo apsauga įjungta Sužinokite daugiau]]> - Learn More]]> + Sužinoti daugiau]]> Apsauga nuo slapukų iškylančiųjų langų @@ -201,7 +201,7 @@ Mygtukas „Fire“ - Data Clearing + Duomenų valymas Leidimai @@ -213,7 +213,7 @@ Išsaugoti Valyti automatiškai… - Automatically Clear Data… + Automatiškai išvalyti duomenis… Valyti automatiškai… Jokie Kortelės @@ -230,10 +230,10 @@ Apie „DuckDuckGo“ - About + Apie Sveiki prisijungę prie „Duck“! „DuckDuckGo“ yra nepriklausoma interneto privatumo bendrovė, įkurta 2008 metais ir skirta visiems, kurie pavargo nuo sekimo internete ir nori lengvo sprendimo. Esame įrodymas, kad galite gauti tikrą privatumo apsaugą internete be kompromisų.\n\n„DuckDuckGo“ naršyklėje yra funkcijų, kurių tikitės iš pagrindinės naršyklės, pavyzdžiui, žymės, skirtukai, slaptažodžiai ir kt., taip pat daugiau nei tuzinas galingų privatumo apsaugos priemonių, kurios nesiūlomos daugumoje populiarių naršyklių. Šis unikalus išsamus privatumo apsaugos rinkinys padeda apsaugoti jūsų veiklą internete – nuo paieškos iki naršymo, el. pašto ir kt.\n\nMūsų privatumo apsaugos priemonės veikia nereikalaudamos nieko žinoti apie technines detales ar naudotis sudėtingais nustatymais. Tereikia visuose įrenginiuose perjungti naršyklę į „DuckDuckGo“ ir privatumas bus užtikrintas pagal numatytuosius nustatymus.\n\nTačiau jei norite daugiau informacijos apie tai, kaip veikia „DuckDuckGo“ privatumo apsaugos priemonės, žiūrėkite mūsų pagalbos puslapius. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + „DuckDuckGo“ yra nepriklausoma interneto privatumo bendrovė, įkurta 2008 metais ir skirta visiems, kurie pavargo nuo sekimo internete ir nori lengvo sprendimo. Esame įrodymas, kad gali gauti tikrą privatumo apsaugą internete be kompromisų.\n\n„DuckDuckGo“ naršyklėje yra funkcijų, kurių tikiesi iš pagrindinės naršyklės, pavyzdžiui, žymės, skirtukai, slaptažodžiai ir kt., taip pat daugiau nei tuzinas galingų privatumo apsaugos priemonių, kurių negali pasiūlyti dauguma populiarių naršyklių. Šis unikalus išsamus privatumo apsaugos rinkinys padeda apsaugoti tavo veiklą internete – nuo paieškos iki naršymo, el. pašto ir kt.\n\nMūsų privatumo apsaugos priemonės veikia taip, kad nereikia išmanyti techninių detalių ar naudotis sudėtingais nustatymais. Tereikia visuose įrenginiuose perjungti naršyklę į „DuckDuckGo“ ir privatumas bus užtikrintas pagal numatytuosius nustatymus.\n\nTačiau jei nori daugiau informacijos apie tai, kaip veikia „DuckDuckGo“ privatumo apsaugos priemonės, ją rasi mūsų pagalbos puslapiuose. Pasiūlymų nėra @@ -702,7 +702,7 @@ Slaptažodžiai - Slaptažodžiai ir automatinis užpildymas + Slaptažodžiai ir automatinis užpildymas Slaptažodis išsaugotas Slaptažodis atnaujintas diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 43fe0f712888..8d4a23d32822 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -125,7 +125,7 @@ Iestatījumi Iestatījumi Privātums - Privātuma aizsardzība + Privātuma aizsardzība Izskats Pielāgošana Par @@ -135,7 +135,7 @@ E-pasta aizsardzība Bloķē e-pasta izsekotājus un paslēp savu adresi Vairāk no DuckDuckGo - Nākamie soļi + Nākamie soļi Gaišs Fons Tumšs @@ -158,15 +158,15 @@ Tīmekļa izsekošanas aizsardzība Iespējots pēc noklusējuma Iestatījumi - Galvenie iestatījumi + Galvenie iestatījumi Atļaujas Sinhronizācija un dublēšana Fire Button - Datu notīrīšana - Pievienot logrīku sākuma ekrānam - Iestati adreses joslas pozīciju - Iespējot balss meklēšanu - DuckDuckGo citās platformās + Datu notīrīšana + Pievienot logrīku sākuma ekrānam + Iestati adreses joslas pozīciju + Iespējot balss meklēšanu + DuckDuckGo citās platformās Privāta meklēšana @@ -192,7 +192,7 @@ Tīmekļa izsekošanas aizsardzība Ir iespējota tīmekļa izsekošanas aizsardzība Uzzināt vairāk]]> - Learn More]]> + Uzzināt vairāk]]> Sīkfailu uznirstošo logu aizsardzība @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Datu notīrīšana Atļaujas @@ -213,7 +213,7 @@ Saglabāt Automātiski notīrīt… - Automatically Clear Data… + Automātiski notīrīt datus… Automātiski notīrīt… Nav Cilnes @@ -230,10 +230,10 @@ Par DuckDuckGo - About + Par Sveicināti Duck pusē! DuckDuckGo ir neatkarīgs 2008. gadā dibināts interneta privātuma uzņēmums ikvienam, kam ir apnikusi izsekošana tiešsaistē un kas vēlas vienkāršu risinājumu. Mēs esam pierādījums tam, ka tiešsaistē var iegūt reālu privātuma aizsardzību bez kompromisiem.\n\nDuckDuckGo pārlūkprogrammā ir visas funkcijas, ko gaidi no sava pārlūka: grāmatzīmes, cilnes, paroles u.c., kā arī vairāk nekā desmit spēcīgu privātuma aizsardzības funkciju, kas nav pieejamas vairumā populārāko pārlūkprogrammu pēc noklusējuma. Šis unikāli visaptverošais privātuma aizsardzības komplekts palīdz aizsargāt tavas darbības tiešsaistē, sākot no meklēšanas līdz pārlūkošanai, e-pasta sūtīšanai u.c.\n\nMūsu privātuma aizsardzība darbojas vienmēr – tev nav jāpārzina sarežģīti tehniskie aspekti vai iestatījumi. Tev vienkārši jālieto DuckDuckGo pārlūks visās savās ierīcēs, un privātums būs tavs standarta risinājums.\n\nBet, ja vēlies paskatīties, kas lācītim vēderā, vairāk informācijas par to, kā darbojas DuckDuckGo privātuma aizsardzība, vari atrast mūsu palīdzības lapās - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo ir neatkarīgs interneta konfidencialitātes uzņēmums, kas dibināts 2008. gadā un ir pieejams visiem, kam ir apnikusi izsekošana tiešsaistē un kas vēlas vienkāršu risinājumu. Mēs esam pierādījums tam, ka tiešsaistē ir iespējams saņemt reālu privātuma aizsardzību bez kompromisiem.\n\nDuckDuckGo pārlūkprogrammā ir visi līdzekļi, ko vari sagaidīt no sava pārlūka: grāmatzīmes, cilnes, paroles un citas iespējas, kā arī vairāk nekā desmit spēcīgas privātuma aizsardzības funkcijas, kas pēc noklusējuma nav pieejamas vairumā populārāko pārlūkprogrammu. Šis unikāli visaptverošais privātuma aizsardzības komplekts palīdz aizsargāt tavas darbības tiešsaistē, sākot no meklēšanas līdz pārlūkošanai, e-pasta ziņojumu sūtīšanai u.c.\n\nMūsu privātuma aizsardzība darbojas bez nepieciešamības zināt tehniskas detaļas vai vajadzības tikt galā ar sarežģītiem iestatījumiem. Tev vienkārši jāsāk lietot DuckDuckGo pārlūks visās savās ierīcēs, un tavs privātums tiks nodrošināts pēc noklusējuma.\n\nTaču, ja tu vēlies paskatīties, kas lācītim vēderā, vairāk informācijas par to, kā darbojas DuckDuckGo privātuma aizsardzība, vari atrast mūsu palīdzības lapās Nav ieteikumu @@ -702,7 +702,7 @@ Paroles - Paroles un automātiskā aizpildīšana + Paroles un automātiskā aizpildīšana Parole saglabāta Parole atjaunināta diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 6419cd0cfa06..3fe9aa5dfe7f 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -125,7 +125,7 @@ Innstillinger Innstillinger Personvern - Personvern + Personvern Utseende Tilpass Om @@ -135,7 +135,7 @@ E-postbeskyttelse Blokker e-postsporere og skjul adressen din Mer fra DuckDuckGo - Neste trinn + Neste trinn Lyst Utseende Mørk @@ -158,15 +158,15 @@ Beskyttelse mot nettsporing Aktivert som standard Innstillinger - Hovedinnstillinger + Hovedinnstillinger Tillatelser Synkronisering og sikkerhetskopiering Fire Button - Sletting av data - Legg til widgeten på startskjermen - Angi plassering av adressefeltet - Aktiver talesøk - DuckDuckGo på andre plattformer + Sletting av data + Legg til widgeten på startskjermen + Angi plassering av adressefeltet + Aktiver talesøk + DuckDuckGo på andre plattformer Privat søk @@ -192,7 +192,7 @@ Beskyttelse mot nettsporing Nettsporingsbeskyttelse er aktivert Finn ut mer]]> - Learn More]]> + Finn ut mer]]> Beskyttelse mot popup-vinduer om informasjonskapsler @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Sletting av data Tillatelser @@ -213,7 +213,7 @@ Lagre Tøm automatisk … - Automatically Clear Data… + Slett data automatisk … Tøm automatisk … Ingen Faner @@ -230,10 +230,10 @@ Om DuckDuckGo - About + Om Velkommen til «the Duck Side»! DuckDuckGo er et uavhengig personvernselskap som ble grunnlagt i 2008, for alle som er lei av å bli sporet på nettet og vil ha en enkel løsning. Vi er beviset på at ekte personvern er mulig på nettet uten å fire på kravene.\n\nDuckDuckGo-nettleseren inneholder funksjonene du kan forvente deg av en vanlig nettleser, som bokmerker, faner, passord og lignende, samt en rekke kraftige personvernfunksjoner, som ikke tilbys som standard i de fleste populære nettleserne. Disse usedvanlig omfattende personvernfunksjonene bidrar til å beskytte nettaktivitetene dine, fra søk til surfing, e-poster med mer.\n\nPersonvernfunksjonene fungerer uten at du behøver å kunne noe om de tekniske detaljene eller forholde deg til kompliserte innstillinger. Det eneste du behøver å gjøre, er å bytte nettleser til DuckDuckGo på alle enhetene dine, så får du personvern som standard.\n\nMen hvis du vil ta en titt under panseret, finner du mer informasjon om hvordan DuckDuckGos personvern fungerer på våre hjelpesider - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo er et uavhengig personvernselskap som ble grunnlagt i 2008, for alle som er lei av å bli sporet på nettet og vil ha en enkel løsning. Vi er beviset på at ekte personvern er mulig på nettet uten å fire på kravene.DuckDuckGo-nettleseren inneholder funksjonene du kan forvente deg av en vanlig nettleser, som bokmerker, faner, passord og lignende, samt en rekke kraftige personvernfunksjoner, som ikke tilbys som standard i de fleste populære nettleserne. Disse usedvanlig omfattende personvernfunksjonene bidrar til å beskytte nettaktivitetene dine, fra søk til surfing, e-poster med mer.\n\nPersonvernfunksjonene fungerer uten at du behøver å kunne noe om de tekniske detaljene eller forholde deg til kompliserte innstillinger. Det eneste du behøver å gjøre, er å bytte nettleser til DuckDuckGo på alle enhetene dine, så får du personvern som standard.\n\nMen hvis du vil ta en titt under panseret, finner du mer informasjon om hvordan DuckDuckGos personvern fungerer på våre hjelpesider Ingen forslag @@ -702,7 +702,7 @@ Passord - Passord og autofyll + Passord og autofyll Passordet er lagret Passordet er oppdatert diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 6f66a126f11f..50d5b1e30e8b 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -125,7 +125,7 @@ Instellingen Instellingen Privacy - Privacybescherming + Privacybescherming Uiterlijk Aanpassen Over @@ -135,7 +135,7 @@ E-mailbescherming Blokkeer e-mailtrackers en verberg je adres Meer over DuckDuckGo - Volgende stappen + Volgende stappen Licht Thema Donker @@ -158,15 +158,15 @@ Bescherming tegen webtracking Standaard ingeschakeld Instellingen - Hoofdinstellingen + Hoofdinstellingen Toestemmingen Synchronisatie en back-up Fire Button - Gegevens wissen - Widget toevoegen aan startscherm - Positie van adresbalk instellen - Zoeken via spraak inschakelen - DuckDuckGo op andere platforms + Gegevens wissen + Widget toevoegen aan startscherm + Positie van adresbalk instellen + Zoeken via spraak inschakelen + DuckDuckGo op andere platforms Privé-zoekopdracht @@ -192,7 +192,7 @@ Bescherming tegen webtracking Bescherming tegen webtracking is ingeschakeld Meer informatie]]> - Learn More]]> + Meer informatie]]> Bescherming tegen cookiepop-ups @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Gegevens wissen Toestemmingen @@ -213,7 +213,7 @@ Opslaan Automatisch wissen… - Automatically Clear Data… + Gegevens automatisch wissen... Automatisch wissen… Geen Tabbladen @@ -230,10 +230,10 @@ Over DuckDuckGo - About + Over Welkom bij de Duck kant! DuckDuckGo is het onafhankelijke internetprivacybedrijf, opgericht in 2008, voor iedereen die het beu is om online gevolgd te worden en daar een eenvoudige oplossing voor wil. Wij zijn het bewijs dat je privacy op internet écht beschermd kan worden zonder compromissen.\n\nDe DuckDuckGo-browser bevat alle functies die je van een gewone browser mag verwachten, zoals bladwijzers, tabbladen, wachtwoorden en meer, plus meer dan een dozijn krachtige functies voor privacybescherming die je standaard niet vindt in de populairste browsers. Deze unieke, uitgebreide privacybescherming helpt je online activiteiten te beschermen – of je nu zoekt, surft of mailt.\n\nJe hoeft niets te weten over de technische details of ingewikkelde instellingen om te profiteren van onze privacybescherming. Je hoeft alleen maar DuckDuckGo op al je apparaten te installeren en geniet dan standaard van privacy.\n\nWil je toch een kijkje nemen onder de motorkap? Op onze hulppagina\'s vind je meer informatie over hoe de privacybescherming van DuckDuckGo werkt. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo is het onafhankelijke internetprivacybedrijf, opgericht in 2008, voor iedereen die het beu is om online gevolgd te worden en daar een eenvoudige oplossing voor wil. Wij zijn het bewijs dat je echte privacybescherming online kunt krijgen zonder compromissen.\n\nDe DuckDuckGo-browser bevat alle functies die je van een gewone browser mag verwachten, zoals bladwijzers, tabbladen, wachtwoorden en meer, plus meer dan een dozijn krachtige privacybeschermingsfuncties die je standaard niet vindt in de populairste browsers. Deze unieke, uitgebreide set privacybeschermingen helpt je online activiteiten te beschermen, van zoeken tot browsen, e-mailen en meer.\n\nJe hoeft niets te weten over de technische details of ingewikkelde instellingen om te profiteren van onze privacybescherming. Je hoeft alleen maar je browser op al je apparaten naar DuckDuckGo te veranderen en je krijgt standaard privacy.\n\nWil je toch iets meer weten? Op onze hulppagina\'svind je meer informatie over hoe de privacybescherming van DuckDuckGo werkt. Geen suggesties @@ -702,7 +702,7 @@ Wachtwoorden - Wachtwoorden en automatisch invullen + Wachtwoorden en automatisch invullen Wachtwoord opgeslagen Wachtwoord bijgewerkt diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d93adc2d3e9d..0763bdda5bd8 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -125,7 +125,7 @@ Ustawienia Ustawienia Prywatność - Mechanizmy Ochrony Prywatności + Mechanizmy Ochrony Prywatności Wygląd Spersonalizuj Informacje @@ -135,7 +135,7 @@ Ochrona poczty e-mail Zablokuj skrypty śledzące pocztę e-mail i ukryj swój adres Więcej możliwości DuckDuckGo - Dalsze kroki + Dalsze kroki Jasny Motyw Ciemny @@ -158,15 +158,15 @@ Ochrona przed śledzeniem w sieci Domyślnie włączone Ustawienia - Ustawienia główne + Ustawienia główne Uprawnienia Synchronizacja i kopia zapasowa Przycisk zabezpieczenia - Czyszczenie danych - Dodaj widżet do ekranu głównego - Ustaw pozycję paska adresu - Włącz wyszukiwanie głosowe - DuckDuckGo na innych platformach + Czyszczenie danych + Dodaj widżet do ekranu głównego + Ustaw pozycję paska adresu + Włącz wyszukiwanie głosowe + DuckDuckGo na innych platformach Prywatne Wyszukiwanie @@ -192,7 +192,7 @@ Ochrona przed śledzeniem w sieci Ochrona przed śledzeniem w sieci jest włączona Dowiedz się więcej]]> - Learn More]]> + Dowiedz się więcej]]> Ochrona przed wyskakującymi okienkami dotyczącymi plików cookie @@ -201,7 +201,7 @@ Przycisk zabezpieczenia - Data Clearing + Czyszczenie danych Uprawnienia @@ -213,7 +213,7 @@ Zapisz Usuwaj automatycznie… - Automatically Clear Data… + Automatyczne czyszczenie danych… Usuwaj automatycznie… Brak Karty @@ -230,10 +230,10 @@ O DuckDuckGo - About + Informacje Witaj po Kaczej Stronie Mocy! DuckDuckGo to założona w 2008 roku niezależna firma zajmująca się prywatnością w Internecie dla osób, które mają dosyć śledzenia online i poszukują łatwego w obsłudze rozwiązania. Jesteśmy dowodem na to, że możesz uzyskać prawdziwą ochronę prywatności online bez kompromisów.\n\nWszechstronna przeglądarka DuckDuckGo jest wyposażona w funkcje, których potrzebujesz, takie jak zakładki, karty, hasła i inne, a także kilkanaście zaawansowanych mechanizmów ochrony prywatności, które nie są domyślnie oferowane w większości popularnych przeglądarek. Ten wyjątkowo zaawansowany zestaw mechanizmów ochrony prywatności pomaga chronić działania w Internecie, od wyszukiwania po przeglądanie, obsługę wiadomości e-mail i nie tylko.\n\nDo korzystania z mechanizmów ochrony prywatności nie jest wymagana znajomość szczegółów technicznych ani skomplikowane ustawienia. Aby uzyskać ochronę prywatności, wystarczy ustawić na wszystkich urządzeniach domyślną przeglądarkę DuckDuckGo.\n\nJeśli interesują Cię szczegóły techniczne, więcej informacji o działaniu mechanizmów ochrony prywatności DuckDuckGo można znaleźć na stronach pomocy - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo to założona w 2008 roku niezależna firma zajmująca się prywatnością w Internecie dla osób, które mają dosyć śledzenia online i poszukują łatwego w obsłudze rozwiązania. Jesteśmy dowodem na to, że możesz uzyskać prawdziwą ochronę prywatności online bez kompromisów.\n\nWszechstronna przeglądarka DuckDuckGo jest wyposażona w funkcje, których potrzebujesz, takie jak zakładki, karty, hasła i inne, a także kilkanaście zaawansowanych mechanizmów ochrony prywatności, które nie są domyślnie oferowane w większości popularnych przeglądarek. Ten wyjątkowo zaawansowany zestaw mechanizmów ochrony prywatności pomaga chronić działania w Internecie, od wyszukiwania po przeglądanie, obsługę wiadomości e-mail i nie tylko.\n\nDo korzystania z mechanizmów ochrony prywatności nie jest wymagana znajomość szczegółów technicznych ani skomplikowane ustawienia. Aby uzyskać ochronę prywatności, wystarczy ustawić na wszystkich urządzeniach domyślną przeglądarkę DuckDuckGo.\n\nJeśli interesują Cię szczegóły techniczne, więcej informacji o działaniu mechanizmów ochrony prywatności w DuckDuckGo można znaleźć na stronach pomocy Brak sugestii @@ -702,7 +702,7 @@ Hasła - Hasła i autouzupełnianie + Hasła i autouzupełnianie Hasło zapisane Zaktualizowano hasło diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index a3471869a360..dda8d508af00 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -125,7 +125,7 @@ Definições Definições Privacidade - Proteções de Privacidade + Proteções de Privacidade Aparência Personalizar Acerca de @@ -135,7 +135,7 @@ Proteção de e-mail Bloqueie rastreadores de e-mail e oculte o seu endereço. Mais da DuckDuckGo - Passos seguintes + Passos seguintes Claro Tema Escuro @@ -158,15 +158,15 @@ Proteção contra rastreamento na internet Ativado por predefinição Definições - Definições Principais + Definições Principais Permissões Sincronização e cópia de segurança Botão de proteção - Limpeza de Dados - Adicionar widget ao ecrã inicial - Define a Posição da Barra de Endereços - Ativar Pesquisa por Voz - DuckDuckGo Noutras Plataformas + Limpeza de Dados + Adicionar widget ao ecrã inicial + Define a Posição da Barra de Endereços + Ativar Pesquisa por Voz + DuckDuckGo Noutras Plataformas Pesquisa Privada @@ -192,7 +192,7 @@ Proteção contra rastreamento na internet A proteção contra rastreamento na Internet está ativada Sabe mais]]> - Learn More]]> + Sabe mais]]> Proteção contra pop-ups de cookies @@ -201,7 +201,7 @@ Botão de proteção - Data Clearing + Limpeza de Dados Permissões @@ -213,7 +213,7 @@ Guardar Limpar automaticamente… - Automatically Clear Data… + Limpar os dados automaticamente… Limpar automaticamente… Nenhum Separadores @@ -230,10 +230,10 @@ Sobre o DuckDuckGo - About + Acerca de Bem-vindo ao Duck Side! A DuckDuckGo é a empresa independente de privacidade na Internet fundada em 2008 para quem está cansado de ser rastreado online e quer uma solução simples. Somos a prova de que podes proteger a tua privacidade online sem compromissos.\n\nO navegador DuckDuckGo vem com as funcionalidades que esperas num navegador de referência, como marcadores, separadores, palavras-passe, entre outras, além de mais de uma dúzia de proteções de privacidade poderosas que os navegadores mais populares não oferecem por predefinição. Este conjunto especialmente abrangente de proteções de privacidade ajuda a proteger as tuas atividades online, desde a pesquisa à navegação, e-mails, entre outras.\n\nPara utilizares as nossas proteções de privacidade, não tens de saber nada sobre os detalhes técnicos nem lidar com definições complicadas. Tudo o que tens de fazer é mudar o teu navegador para o DuckDuckGo em todos os teus dispositivos e desfrutar de privacidade como predefinição.\n\nMas, se quiseres espreitar os bastidores, podes consultar mais informações sobre como funcionam as proteções de privacidade do DuckDuckGo nas nossas páginas de ajuda - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + A DuckDuckGo é a empresa independente de privacidade na Internet fundada em 2008 para quem está cansado de ser rastreado online e quer uma solução simples. Somos a prova de que podes usufruir de proteção da privacidade real online sem compromissos.\n\nO navegador DuckDuckGo vem com as funcionalidades que esperas num navegador de referência, como marcadores, separadores, palavras-passe, entre outras, além de dezenas de proteções de privacidade poderosas que os navegadores mais populares não oferecem por predefinição. Este conjunto especialmente abrangente de proteções de privacidade ajuda a proteger as tuas atividades online, desde a pesquisa à navegação, e-mails, entre outras.\n\nPara utilizares as nossas proteções de privacidade, não tens de saber nada sobre os detalhes técnicos nem lidar com definições complicadas. Tudo o que tens de fazer é mudar o teu navegador para o DuckDuckGo em todos os teus dispositivos e desfrutar de privacidade como predefinição.\n\nMas, se quiseres espreitar os bastidores, podes consultar mais informações sobre como funcionam as proteções de privacidade do DuckDuckGo nas nossas páginas de ajuda Sem sugestões @@ -702,7 +702,7 @@ Palavras-passe - Palavras-passe e preenchimento automático + Palavras-passe e preenchimento automático Palavra-passe guardada Palavra-passe atualizada diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index e1e67455396a..d1cf1b911445 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -125,7 +125,7 @@ Setări Setări Confidențialitate - Măsuri de protecție a confidențialității + Măsuri de protecție a confidențialității Aspect Personalizare Despre @@ -135,7 +135,7 @@ Protecția comunicațiilor prin e-mail Blochează tehnologiile de urmărire prin e-mail și ascunde-ți adresa Mai multe de la DuckDuckGo - Pașii următori + Pașii următori Luminoasă Temă Intunecată @@ -158,15 +158,15 @@ Protecție împotriva urmăririi pe web Activat în mod implicit Setări - Setări principale + Setări principale Permisiuni Sincronizare și copiere de rezervă Butonul Foc - Ștergerea datelor - Adaugă un widget la ecranul de întâmpinare - Setează poziția barei de adrese - Activează căutarea vocală - DuckDuckGo pe alte platforme + Ștergerea datelor + Adaugă un widget la ecranul de întâmpinare + Setează poziția barei de adrese + Activează căutarea vocală + DuckDuckGo pe alte platforme Căutare Confidențială @@ -192,7 +192,7 @@ Protecție împotriva urmăririi pe web Protecția împotriva urmăririi pe web este activată Află mai multe]]> - Learn More]]> + Află mai multe]]> Protecție pentru ferestre pop-up aferente modulelor cookie @@ -201,7 +201,7 @@ Butonul Foc - Data Clearing + Ștergerea datelor Permisiuni @@ -213,7 +213,7 @@ Salvează Ștergere automată… - Automatically Clear Data… + Șterge automat datele… Ștergere automată… Niciuna File @@ -230,10 +230,10 @@ Despre DuckDuckGo - About + Despre Welcome to the Duck Side! DuckDuckGo este o companie independentă înființată în 2008, care oferă confidențialitate pe internet pentru toți cei care s-au săturat să fie urmăriți online și doresc o soluție simplă.Suntem dovada că protecția confidențialității online fără compromisuri este reală.\n\nBrowserul DuckDuckGo oferă funcțiile la care vă așteptați de la browserul preferat, cum ar fi marcajele, filele, parolele și multe altele, plus peste o duzină de protecții ale confidențialității remarcabile, care nu sunt oferite implicit în majoritatea browserelor populare.Acest set unic și cuprinzător de măsuri de protecție a confidențialității vă ajută să vă protejați activitățile online, de la căutări la navigare, e-mailuri și multe altele.\n\nMăsurile noastre robuste de protecție a confidențialității funcționează fără a fi nevoie să cunoașteți detalii tehnice sau să aveți de-a face cu setări complicate.Tot ce trebuie să faceți este să folosiți browserul DuckDuckGo pe toate dispozitivele și veți beneficia automat de confidențialitate.\n\nDar dacă doriți să aflați detaliile din culise, puteți găsi mai multe informații despre modul în care funcționează protecțiile de confidențialitate DuckDuckGo pe paginile noastre de ajutor - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo este compania independentă de confidențialitate pe internet, fondată în 2008, pentru toți cei care s-au săturat să fie urmăriți online și își doresc o soluție simplă. Suntem dovada faptului că poți obține o protecție reală a confidențialității online, fără compromisuri.\n\nBrowserul DuckDuckGo oferă funcțiile la care te așteptai de la browserul preferat, cum ar fi marcajele, filele, parolele și multe altele, plus peste o duzină de funcții de protecție a confidențialității remarcabile, care nu sunt oferite implicit în majoritatea browserelor populare. Acest set unic și cuprinzător de măsuri de protecție a confidențialității te ajută să îți protejezi activitățile online, de la căutări la navigare, e-mailuri și multe altele.\n\nMăsurile noastre robuste de protecție a confidențialității funcționează fără a necesita cunoștințe tehnice din partea ta și fără a fi nevoie să faci setări complicate. Tot ce trebuie să faci este să folosești browserul DuckDuckGo pe toate dispozitivele și vei beneficia implicit de confidențialitate.\n\nDar, dacă dorești să afli detalii din culise, poți găsi mai multe informații despre modul în care funcționează măsurile de protecție a confidențialității DuckDuckGo în paginile noastre de ajutor Fără sugestii @@ -702,7 +702,7 @@ Parole - Parole și completare automată + Parole și completare automată Parolă salvată Parolă actualizată diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index d7febdee7052..01d4c3022e88 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -125,7 +125,7 @@ Настройки Настройки Конфиденциальность - Защита конфиденциальности + Защита конфиденциальности Внешний вид Собственная настройка О нас @@ -135,7 +135,7 @@ Защита электронной почты Блокировка почтовых трекеров и скрытие адреса DuckDuckGo также предлагает... - Дальнейшие шаги + Дальнейшие шаги Светлая Тема Тёмная @@ -158,15 +158,15 @@ Защита от отслеживания онлайн Включено по умолчанию Настройки - Основные настройки + Основные настройки Разрешения Синхронизация и резервное копирование Кнопка «Тревога» - Очистка данных - Добавьте виджет на домашний экран - Настроить положение адресной строки - Включить голосовой поиск - DuckDuckGo для других платформ + Очистка данных + Добавьте виджет на домашний экран + Настроить положение адресной строки + Включить голосовой поиск + DuckDuckGo для других платформ Частный поиск @@ -192,7 +192,7 @@ Защита от отслеживания онлайн Включена защита от отслеживания онлайн Подробнее...]]> - Learn More]]> + Подробнее...]]> Защита от всплывающих окон куки @@ -201,7 +201,7 @@ Кнопка «Тревога» - Data Clearing + Очистка данных Разрешения @@ -213,7 +213,7 @@ Сохранить Автоматически сбрасывать… - Automatically Clear Data… + Автоудаление данных... Автоматически сбрасывать… Ничего Вкладки @@ -230,10 +230,10 @@ Несколько слов о DuckDuckGo - About + О нас Добро пожаловать на Утиную сторону! DuckDuckGo — основанная в 2008 году независимая компания, специализирующаяся на защите личных данных в Интернете. Мы предлагаем простое решение тем, кто хочет, чтобы за ними перестали следить онлайн. DuckDuckGo своим примером показывает, что защита конфиденциальности онлайн возможна без всяких компромиссов.\n\nВ универсальном браузере DuckDuckGo вы найдете все те же привычные функции — вкладки, закладки, пароли и многое другое, а также более десятка мощных средств защиты личной информации, которых нет в стандартных настройках других популярных веб-обозревателей . Такой исчерпывающий набор инструментов может скрыть от посторонних глаз всю сетевую активность, включая поиск, навигацию и почту.\n\nСредства защиты конфиденциальности не требуют от пользователей знания технических особенностей или понимания сложных настроек .Достаточно сменить свой браузер на DuckDuckGo на всех устройствах, и конфиденциальность станет вашим режимом по умолчанию.\n\nЕсли же вас интересует «подноготная», подробную информацию об особенностях защиты DuckDuckGo можно найти на страницах справки. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo — независимая компания, которая c 2008 года предоставляет услуги защиты личных данных в интернете. Мы предлагаем простое решение для тех, кому надоело отслеживание онлайн. Своим примером DuckDuckGo показывает, что защита конфиденциальности в Сети не требует компромиссов.\n\nВ универсальном браузере DuckDuckGo вы найдете все те же привычные функции — вкладки, закладки, пароли — плюс более десятка мощных средств защиты личной информации, которых нет в стандартных настройках других популярных веб-обозревателей. Наш всесторонний набор инструментов скроет от посторонних глаз всю вашу онлайн-активность, включая поиск, просмотр сайтов и чтение почты.\n\nСервисы DuckDuckGo не требуют особых технических познаний или работы со сложными настройками. Достаточно сменить свой браузер на DuckDuckGo на всех устройствах, и конфиденциальность онлайн станет вашим спутником по умолчанию.\n\nЕсли же вас интересует «подноготная», подробную информацию об особенностях защиты DuckDuckGo можно найти на наших справочных страницах. Нет предложений @@ -702,7 +702,7 @@ Пароли - Пароли и автозаполнение + Пароли и автозаполнение Пароль сохранен Пароль обновлен diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 5b6cb48094d7..4299561c9d6c 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -125,7 +125,7 @@ Nastavenia Nastavenia Súkromie - Ochrana súkromia + Ochrana súkromia Vzhľad Prispôsobiť O @@ -135,7 +135,7 @@ Ochrana e-mailu Zablokujte nástroje na sledovanie e‑mailov a skryte vašu adresu Viac od DuckDuckGo - Ďalšie kroky + Ďalšie kroky Svetlá Motív Tmavý @@ -158,15 +158,15 @@ Ochrana pred sledovaním webu Predvolene povolené Nastavenia - Hlavné nastavenia + Hlavné nastavenia Oprávnenia Synchronizácia a zálohovanie Tlačidlo Fire - Vymazanie údajov - Pridať miniaplikáciu na domovskú obrazovku - Nastavenie polohy panela s adresou - Povoliť hlasové vyhľadávanie - DuckDuckGo na iných platformách + Vymazanie údajov + Pridať miniaplikáciu na domovskú obrazovku + Nastavenie polohy panela s adresou + Povoliť hlasové vyhľadávanie + DuckDuckGo na iných platformách Súkromné vyhľadávanie @@ -192,7 +192,7 @@ Ochrana pred sledovaním webu Ochrana pred sledovaním webu je povolená Zistiť viac]]> - Learn More]]> + Zisti viac]]> Ochrana proti automatickému otváraniu okien o súboroch cookie @@ -201,7 +201,7 @@ Tlačidlo Fire - Data Clearing + Vymazanie údajov Oprávnenia @@ -213,7 +213,7 @@ Uložiť Automaticky vymazať… - Automatically Clear Data… + Vymazať údaje automaticky… Automaticky vymazať… Žiadne Karty @@ -230,10 +230,10 @@ O DuckDuckGo - About + O Vitajte na Duck Side! DuckDuckGo je nezávislá spoločnosť na ochranu súkromia na internete založená v roku 2008 pre všetkých, ktorých už nebaví sledovanie na internete a chcú jednoduché riešenie. Sme dôkazom, že skutočnú online ochranu súkromia môžete získať bez kompromisov.\n\nPrehliadač DuckDuckGo je vybavený funkciami, ktoré očakávate od prehliadača, ako sú záložky, karty, heslá a ďalšie funkcie, a viac ako tuctom výkonných prvkov na ochranu súkromia, ktoré väčšina populárnych prehliadačov štandardne neponúka. Tento jedinečne komplexný súbor ochrany súkromia pomáha chrániť vaše online aktivity od vyhľadávania po prehliadanie, posielanie e-mailov a ďalšie.\n\nNaša ochrana súkromia funguje bez toho, aby ste museli poznať technické detaily alebo riešiť zložité nastavenia. Stačí prepnúť prehliadač na DuckDuckGo vo všetkých zariadeniach a získate predvolené súkromie.\n\nAk však máte záujem o podrobnejšie preskúmanie, viac informácií o tom, ako funguje ochrana súkromia v službe DuckDuckGo, nájdete na našich stránkach pomoci. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo je nezávislá spoločnosť zaoberajúca sa ochranou súkromia na internete, ktorá bola založená v roku 2008 pre všetkých, ktorých už nebaví sledovanie na internete a chcú jednoduché riešenie. Sme dôkazom, že skutočnú online ochranu súkromia môžeš získať bez kompromisov.\n\nPrehliadač DuckDuckGo je vybavený funkciami, ktoré od prehliadača očakávaš, ako sú záložky, karty, heslá a ďalšie, a má viac ako tucet výkonných prvkov na ochranu súkromia, ktoré väčšina obľúbených štandardne neponúka. Tento jedinečne komplexný súbor ochrany súkromia pomáha chrániť tvoje online aktivity od vyhľadávania cez prehliadanie, až po posielanie e-mailov a ďalšie.\n\nNaša ochrana súkromia funguje bez toho, aby si musel poznať technické detaily alebo riešiť zložité nastavenia. Stačí prepnúť prehliadač na DuckDuckGo vo všetkých zariadeniach a získaš predvolené súkromie.\n\nAk však chceš nahliadnuť pod kapotu a zistiť viac informácií o tom, ako funguje ochrana súkromia v službe DuckDuckGo, nájdeš ich na našich stránkach pomoci. Žiadne návrhy @@ -702,7 +702,7 @@ Heslo - Heslá a automatické dopĺňanie + Heslá a automatické dopĺňanie Uložené heslo Aktualizácia hesla diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index bab5f652e4d8..319455a81a48 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -125,7 +125,7 @@ Nastavitve Nastavitve Zasebnost - Zaščita zasebnosti + Zaščita zasebnosti Izgled Prilagodi O nas @@ -135,7 +135,7 @@ Zaščita e-pošte Blokirajte sledilnike e-pošte in skrijte svoj naslov Več od iskalnika DuckDuckGo - Naslednji koraki + Naslednji koraki Luč Videz Temna @@ -158,15 +158,15 @@ Zaščita pred spletnim sledenjem Privzeto omogočeno Nastavitve - Glavne nastavitve + Glavne nastavitve Dovoljenja Sinhronizacija in varnostno kopiranje Gumb Fire Button - Počiščenje podatkov - Dodajte pripomoček na domači zaslon - Nastavitev položaja naslovne vrstice - Omogočanje glasovnega iskanja - DuckDuckGo na drugih platformah + Počiščenje podatkov + Dodajte pripomoček na domači zaslon + Nastavitev položaja naslovne vrstice + Omogočanje glasovnega iskanja + DuckDuckGo na drugih platformah zasebno iskanje @@ -192,7 +192,7 @@ Zaščita pred spletnim sledenjem Zaščita spletnega sledenja je omogočena Več o tem]]> - Learn More]]> + Več o tem]]> Zaščita pred pojavnimi okni piškotkov @@ -201,7 +201,7 @@ Gumb Fire Button - Data Clearing + Počiščenje podatkov Dovoljenja @@ -213,7 +213,7 @@ Shrani Samodejno počisti … - Automatically Clear Data… + Samodejno počisti podatke… Samodejno počisti … Brez Zavihki @@ -230,10 +230,10 @@ O DuckDuckGo - About + O nas Dobrodošli na strani Duck! DuckDuckGo je neodvisno podjetje za zasebnost v internetu, ustanovljeno leta 2008, in je namenjeno vsem, ki so naveličani sledenja v spletu in si želijo preproste rešitve. Dokazujemo, da je v spletu mogoče zagotoviti pravo zaščito zasebnosti brez sklepanja kompromisov.\n\nBrskalnik DuckDuckGo ima funkcije, ki jih pričakujete od priljubljenega brskalnika, kot so zaznamki, zavihki, gesla in drugo, ter več kot deset zmogljivih zaščit zasebnosti, ki jih večina priljubljenih brskalnikov ne ponuja privzeto. Ta edinstveni celovit sklop zaščite zasebnosti pomaga zaščititi vaše spletne dejavnosti, od iskanja do brskanja, pošiljanja e-pošte in še več.\n\nNaša zaščita zasebnosti deluje, ne da bi se vam bilo treba spoznati na tehnične podrobnosti ali se ukvarjati z zapletenimi nastavitvami. Vse, kar morate storiti, je, da brskalnik preklopite na DuckDuckGo v vseh napravah in zasebnost bo privzeta.\n\nČe pa želite pogledati v mehanizem delovanja, lahko več informacij o delovanju zaščite zasebnosti DuckDuckGo najdete na naših straneh s pomočjo. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo je neodvisno podjetje za zasebnost na internetu, ustanovljeno leta 2008, in je namenjeno vsem, ki so naveličani sledenja v spletu in si želijo preproste rešitve. Dokazujemo, da je v spletu mogoče zagotoviti pravo zaščito zasebnosti brez sklepanja kompromisov.\n\nBrskalnik DuckDuckGo ima funkcije, ki jih pričakujete od priljubljenega brskalnika, kot so zaznamki, zavihki, gesla in drugo, ter več kot deset zmogljivih zaščit zasebnosti, ki jih večina priljubljenih brskalnikov ne ponuja privzeto. Ta edinstveni celovit sklop zaščite zasebnosti pomaga zaščititi vaše spletne dejavnosti, od iskanja do brskanja, pošiljanja e-pošte in še več.\n\nNaša zaščita zasebnosti deluje, ne da bi se vam bilo treba spoznati na tehnične podrobnosti ali se ukvarjati z zapletenimi nastavitvami. Vse, kar morate storiti, je, da brskalnik preklopite na DuckDuckGo v vseh napravah in zasebnost bo privzeta.\n\nČe pa želite pogledati v mehanizem delovanja, lahko več informacij o delovanju zaščite zasebnosti DuckDuckGo najdete na naših straneh s pomočjo. Ni predlogov @@ -702,7 +702,7 @@ Gesla - Gesla in samodejno izpolnjevanje + Gesla in samodejno izpolnjevanje Geslo je shranjeno Geslo je posodobljeno diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 8b443f498634..767c19da9fab 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -125,7 +125,7 @@ Inställningar Inställningar Sekretess - Integritetsskydd + Integritetsskydd Utseende Anpassa Om @@ -135,7 +135,7 @@ E-postskydd Blockera e-postspårare och dölj din adress Mer från DuckDuckGo - Nästa steg + Nästa steg Ljus Tema Mörk @@ -158,15 +158,15 @@ Web Tracking Protection Aktiverat som standard Inställningar - Huvudinställningar + Huvudinställningar Behörigheter Synkronisering och säkerhetskopiering Fire Button - Datarensning - Lägg till widget på startsidan - Ange din adressfältsposition - Aktivera röstsökning - DuckDuckGo på andra plattformar + Datarensning + Lägg till widget på startsidan + Ange din adressfältsposition + Aktivera röstsökning + DuckDuckGo på andra plattformar Privatsökning @@ -192,7 +192,7 @@ Web Tracking Protection Skydd för webbspårning är aktiverat Mer information]]> - Learn More]]> + Läs mer]]> Skydd mot popup-fönster för cookies @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Datarensning Behörigheter @@ -213,7 +213,7 @@ Spara Autorensning … - Automatically Clear Data… + Rensa data automatiskt … Autorensning … Inga Flikar @@ -230,10 +230,10 @@ Om DuckDuckGo - About + Om Välkommen till Duck-sidan! DuckDuckGo är det oberoende integritetsskyddsföretaget som grundades 2008 för alla som är trötta på att bli spårade online och vill ha en enkel lösning. Vi är beviset på att man kan få riktigt integritetsskydd på nätet utan att kompromissa.\n\nWebbläsaren DuckDuckGo har de funktioner man förväntar sig av en pålitlig webbläsare, som bokmärken, flikar, lösenord och mycket annat. Den har även ett tiotal kraftfulla integritetsskydd som inte erbjuds som standard i de flesta vanliga webbläsare. Den här omfattande uppsättningen av integritetsskydd hjälper dig att skydda dina onlineaktiviteter, från sökning och surfning till e-post och mycket mer.\n\nVårt integritetsskydd fungerar utan att du behöver känna till de tekniska detaljerna eller ta itu med komplicerade inställningar. Det enda du behöver göra är att byta webbläsare till DuckDuckGo på alla dina enheter för att få integritet som standard.\n\nMen om du vill ta en titt under huven, så finns det mer information om hur integritetsskyddet hos DuckDuckGo fungerar på våra hjälpsidor. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo är det oberoende integritetsskyddsföretaget som grundades 2008 för alla som är trötta på att bli spårade online och vill ha en enkel lösning. Vi är beviset på att man kan få riktigt integritetsskydd på nätet utan att kompromissa.\n\nWebbläsaren DuckDuckGo har de funktioner man förväntar sig av en pålitlig webbläsare, som bokmärken, flikar, lösenord och mycket annat. Den har även ett tiotal kraftfulla integritetsskydd som inte erbjuds som standard i de flesta vanliga webbläsare. Den här omfattande uppsättningen av integritetsskydd hjälper dig att skydda dina onlineaktiviteter, från sökning och surfning till e-post och mycket mer.\n\nVårt integritetsskydd fungerar utan att du behöver känna till de tekniska detaljerna eller ta itu med komplicerade inställningar. Det enda du behöver göra är att byta webbläsare till DuckDuckGo på alla dina enheter för att få integritet som standard.\n\nMen om du vill ta en titt under huven, så finns det mer information om hur integritetsskyddet hos DuckDuckGo fungerar på våra hjälpsidor. Inga förslag @@ -702,7 +702,7 @@ Lösenord - Lösenord och automatisk ifyllning + Lösenord och automatisk ifyllning Lösenord sparat Lösenordet har uppdaterats diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index f765dee9e5a4..0e53f06855c7 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -125,7 +125,7 @@ Ayarlar Ayarlar Gizlilik - Gizlilik Korumaları + Gizlilik Korumaları Görünüm Özelleştir Hakkında @@ -135,7 +135,7 @@ E-posta Koruması E-posta izleyicileri engelleyin ve adresinizi gizleyin DuckDuckGo\'dan Daha Fazlası - Sonraki Adımlar + Sonraki Adımlar Açık Tema Koyu @@ -158,15 +158,15 @@ Web İzleme Koruması Varsayılan olarak etkinleştirildi Ayarlar - Ana Ayarlar + Ana Ayarlar İzinler Senkronizasyon ve Yedekleme Fire Button - Veri Temizleme - Widget\'ı Ana Ekrana Ekle - Adres Çubuğu Konumunuzu Ayarlayın - Sesli Arama\'yı Etkinleştir - Diğer Platformlarda DuckDuckGo + Veri Temizleme + Widget\'ı Ana Ekrana Ekle + Adres Çubuğu Konumunuzu Ayarlayın + Sesli Arama\'yı Etkinleştir + Diğer Platformlarda DuckDuckGo Gizli Arama @@ -192,7 +192,7 @@ Web İzleme Koruması Web İzleme Engelleyici Etkinleştirildi Daha fazla bilgi edin]]> - Learn More]]> + Daha Fazla Bilgi]]> Çerez Açılır Pencere Engelleyici @@ -201,7 +201,7 @@ Fire Button - Data Clearing + Veri Temizleme İzinler @@ -213,7 +213,7 @@ Kaydet Otomatik Olarak Temizle... - Automatically Clear Data… + Verileri Otomatik Olarak Temizle… Otomatik olarak temizle... Yok Sekmeler @@ -230,10 +230,10 @@ DuckDuckGo Hakkında - About + Hakkında Duck Side\'a hoş geldiniz! DuckDuckGo, çevrim içi takip edilmeyi hiç istemeyen ve pratik bir çözüm arayan herkese hizmet veren, 2008 yılında kurulmuş bağımsız bir İnternet gizlilik şirketidir. Biz, çevrim içi ortamda ödün vermeden gerçek gizlilik koruması elde edebileceğinizin kanıtıyız.\n\nDuckDuckGo tarayıcı; yer imleri, sekmeler, parolalar ve daha fazlası gibi bir tarayıcıdan beklediğiniz özelliklerin yanı sıra varsayılan olarak çoğu popüler tarayıcıda sunulmayan ondan fazla güçlü gizlilik koruması ile birlikte gelir. Son derece kapsamlı olan bu gizlilik koruma seti, aramadan gezinmeye, e-posta göndermeye ve daha fazlasına kadar çevrim içi etkinliklerinizde koruma sağlamaya yardımcı olur.\n\nGizlilik korumalarımız, teknik ayrıntılar hakkında hiçbir şey bilmenize veya karmaşık ayarlarla uğraşmanıza gerek kalmadan çalışır. Tüm cihazlarınızda tarayıcı olarak DuckDuckGo\'yu kullanarak aradığınız gizliliği sağlayabilirsiniz.\n\nAncak ayrıntılara göz atmak istiyorsanız, DuckDuckGo gizlilik korumalarının nasıl çalıştığıyla ilgili daha fazla bilgiyi yardım sayfalarımızdabulabilirsiniz. - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo, internette izlenmek istemeyen ve kolay bir çözüm arayan herkes için 2008 yılında kurulan bağımsız bir internet gizlilik şirketidir. Çevrimiçi ortamda ödün vermeden gerçek gizlilik koruması elde edebileceğinizin kanıtıyız.\n\nDuckDuckGo tarayıcı yer işaretleri, sekmeler, parolalar ve daha fazlası gibi bir tarayıcıdan beklediğiniz özelliklerin yanı sıra varsayılan olarak çoğu popüler tarayıcıda olmayan ondan fazla güçlü gizlilik koruması sunar. Bu benzersiz kapsamlı gizlilik koruma seti, aramadan gezinmeye, e-posta göndermeye ve daha fazlasına kadar internetteki etkinliklerinizi korumaya yardımcı olur.\n\nGizlilik korumalarımız, teknik ayrıntılar hakkında hiçbir şey bilmek veya karmaşık ayarlarla uğraşmak gerekmeksizin çalışır. Tüm cihazlarınızda kullandığınız tarayıcıyı DuckDuckGo\'ya değiştirip varsayılan olarak gizlilik elde edin.\n\nAncak kaputun altına bir göz atmak istiyorsanız, DuckDuckGo gizlilik korumalarının işleyişi hakkında daha fazla bilgiyi yardım sayfalarımızda bulabilirsiniz. Öneri yok @@ -702,7 +702,7 @@ Şifreler - Şifreler ve Otomatik Doldurma + Şifreler ve Otomatik Doldurma Şifre kaydedildi Şifre güncellendi diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e5016e54ca41..4312819e041d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -124,7 +124,7 @@ Settings Settings Privacy - Privacy Protections + Privacy Protections Appearance Customize About @@ -134,7 +134,7 @@ Email Protection Block email trackers and hide your address More From DuckDuckGo - Next Steps + Next Steps Light Theme Dark @@ -157,15 +157,15 @@ Web Tracking Protection Enabled by default Settings - Main Settings + Main Settings Permissions Sync & Backup Fire Button - Data Clearing - Add Widget to HomeScreen - Set Your Address Bar Position - Enable Voice Search - DuckDuckGo on Other Platforms + Data Clearing + Add Widget to HomeScreen + Set Your Address Bar Position + Enable Voice Search + DuckDuckGo on Other Platforms Private Search @@ -191,7 +191,7 @@ Web Tracking Protection Web Tracking Protection is Enabled Learn More]]> - Learn More]]> + Learn More]]> Cookie Pop-Up Protection @@ -200,7 +200,7 @@ Fire Button - Data Clearing + Data Clearing Permissions @@ -212,7 +212,7 @@ Save Automatically Clear… - Automatically Clear Data… + Automatically Clear Data… Automatically clear… None Tabs @@ -229,10 +229,10 @@ About DuckDuckGo - About + About Welcome to the Duck Side! DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who’s tired of being tracked online and wants an easy solution. We’re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages - DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages + DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who\'s tired of being tracked online and wants an easy solution. We\'re proof you can get real privacy protection online without tradeoffs.\n\nThe DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over a dozen powerful privacy protections not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more.\n\nOur privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default.\n\nBut if you do want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our help pages No Suggestions @@ -701,7 +701,7 @@ Passwords - Passwords & Autofill + Passwords & Autofill Password saved Password updated diff --git a/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml index 0c8c4500bd9d..fe8fbc4ea78d 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-bg/strings-autoconsent.xml @@ -19,6 +19,6 @@ Защита от изскачащи прозорци за бисквитки Научете повече]]> - Learn More]]> + Научете повече]]> Позволете на DuckDuckGo да се погрижи за изскачащите прозорци за бисквитки \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml index b4b2661b1d69..498bbf1ce1ae 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-cs/strings-autoconsent.xml @@ -19,6 +19,6 @@ Ochrana před vyskakovacími okny ohledně cookies Další informace]]> - Learn More]]> + Další informace]]> Nech správu vyskakovacích oken ohledně cookie na DuckDuckGo \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml index a9337280c790..951d6d5bd2b1 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-da/strings-autoconsent.xml @@ -19,6 +19,6 @@ Beskyttelse mod pop op-beskeder om cookies Lær mere]]> - Learn More]]> + Mere info]]> Lad DuckDuckGo håndtere pop op-beskeder om cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml index 5053c6bfd861..c04b096ae8d0 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-de/strings-autoconsent.xml @@ -19,6 +19,6 @@ Cookie-Pop-up-Schutz Mehr erfahren]]> - Learn More]]> + Mehr erfahren]]> Lass Cookie-Pop-ups von DuckDuckGo verwalten \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml index 0167027c5e6d..19571e5effff 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-el/strings-autoconsent.xml @@ -19,6 +19,6 @@ Προστασία αναδυόμενων παραθύρων για cookies Μάθετε περισσότερα]]> - Learn More]]> + Μάθετε περισσότερα]]> Επιτρέψτε στο DuckDuckGo να διαχειρίζεται τα αναδυόμενα παράθυρα για cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml index afc320dc5d55..e24fe321d4b9 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-es/strings-autoconsent.xml @@ -19,6 +19,6 @@ Protección contra ventanas emergentes de cookies Más información]]> - Learn More]]> + Más información]]> Deja que DuckDuckGo gestione las ventanas emergentes de cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml index c398ee2a7674..741b4fc15ce1 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-et/strings-autoconsent.xml @@ -19,6 +19,6 @@ Küpsiste hüpikakna kaitse Lisateave]]> - Learn More]]> + Loe edasi]]> Lase DuckDuckGol küpsiste hüpikaknaid hallata \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml index 171392945f45..653166965881 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-fi/strings-autoconsent.xml @@ -19,6 +19,6 @@ Evästeiden ponnahdusikkuna -suojaus Lue lisää]]> - Learn More]]> + Lue lisää]]> Anna DuckDuckGo hoitaa evästeiden ponnahdusikkunat \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml index 2c1f501bb5e2..8de92c5e3f5d 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-fr/strings-autoconsent.xml @@ -19,6 +19,6 @@ Protection contre les fenêtres contextuelles des cookies En savoir plus]]> - Learn More]]> + En savoir plus]]> Laisser DuckDuckGo gérer les fenêtres contextuelles des cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml index 5b9723046215..e5f695b3d017 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-hr/strings-autoconsent.xml @@ -19,6 +19,6 @@ Zaštita od kolačića i skočnih prozora Saznaj više]]> - Learn More]]> + Saznaj više]]> Neka DuckDuckGo upravlja skočnim prozorima kolačića \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml index 8c5052b8ac10..c042ed59c11f 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-hu/strings-autoconsent.xml @@ -19,6 +19,6 @@ Felugró sütiablak elleni védelem További részletek]]> - Learn More]]> + További részletek]]> A DuckDuckGo kezelje a felugró sütiablakokat \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml index 6545f894ef03..02d36e2c8c5d 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-it/strings-autoconsent.xml @@ -19,6 +19,6 @@ Protezione pop-up dei cookie Ulteriori informazioni]]> - Learn More]]> + Ulteriori informazioni]]> Lascia che DuckDuckGo gestisca i pop-up cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml index 159e567520ad..8f488a98bc4c 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-lt/strings-autoconsent.xml @@ -19,6 +19,6 @@ Apsauga nuo slapukų iškylančiųjų langų Sužinokite daugiau]]> - Learn More]]> + Sužinoti daugiau]]> Leiskite „DuckDuckGo“ tvarkyti slapukų iškylančiuosius langus \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml index d8482b77c129..9cd61e48186a 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-lv/strings-autoconsent.xml @@ -19,6 +19,6 @@ Sīkfailu uznirstošo logu aizsardzība Uzzināt vairāk]]> - Learn More]]> + Uzzināt vairāk]]> Ļauj DuckDuckGo apstrādāt sīkfailu uznirstošos logus \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml index 264bba2ad6d6..9b3e2ec984d1 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-nb/strings-autoconsent.xml @@ -19,6 +19,6 @@ Beskyttelse mot popup-vinduer om informasjonskapsler Finn ut mer]]> - Learn More]]> + Finn ut mer]]> La DuckDuckGo håndtere popup-vinduer om informasjonskapsler \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml index 7befb6466160..4aa7b8f3a740 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-nl/strings-autoconsent.xml @@ -19,6 +19,6 @@ Bescherming tegen cookiepop-ups Meer informatie]]> - Learn More]]> + Meer informatie]]> Laat DuckDuckGo cookiepop-ups verwerken \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml index 8d3e4a79fd00..404f9c40004b 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-pl/strings-autoconsent.xml @@ -19,6 +19,6 @@ Ochrona przed wyskakującymi okienkami dotyczącymi plików cookie Dowiedz się więcej]]> - Learn More]]> + Dowiedz się więcej]]> Pozwól DuckDuckGo zajmować się wyskakującymi okienkami plików cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml index 554917355673..ccde4a147ba2 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-pt/strings-autoconsent.xml @@ -19,6 +19,6 @@ Proteção contra pop-ups de cookies Sabe mais]]> - Learn More]]> + Sabe mais]]> Permitir que o DuckDuckGo lide com pop-ups de cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml index 855652fe9fd1..a43b71125b7b 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-ro/strings-autoconsent.xml @@ -19,6 +19,6 @@ Protecție pentru ferestre pop-up aferente modulelor cookie Află mai multe]]> - Learn More]]> + Află mai multe]]> Lasă DuckDuckGo să se ocupe de ferestrele pop-up aferente modulelor cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml index 5785e72f3081..049ff388ac60 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-ru/strings-autoconsent.xml @@ -19,6 +19,6 @@ Защита от всплывающих окон куки Подробнее...]]> - Learn More]]> + Подробнее...]]> Разрешить DuckDuckGo взять на себя окна выбора куки-файлов \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml index 696858e3def7..c5b403de7eca 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-sk/strings-autoconsent.xml @@ -19,6 +19,6 @@ Ochrana proti automatickému otváraniu okien o súboroch cookie Zistiť viac]]> - Learn More]]> + Zisti viac]]> Nechajte, aby sa DuckDuckGo postaral o vyskakovacie okná o súboroch cookie \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml index 9a7045f72872..bc1d1e212698 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-sl/strings-autoconsent.xml @@ -19,6 +19,6 @@ Zaščita pred pojavnimi okni piškotkov Več o tem]]> - Learn More]]> + Več o tem]]> Naj DuckDuckGo poskrbi za pojavna okna piškotkov \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml index af5f589a2b8e..b71ee8f05ea7 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-sv/strings-autoconsent.xml @@ -19,6 +19,6 @@ Skydd mot popup-fönster för cookies Läs mer]]> - Learn More]]> + Läs mer]]> Låt DuckDuckGo hantera popup-fönster för cookies \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml index a0dbf31ebb8d..061b1264189c 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values-tr/strings-autoconsent.xml @@ -19,6 +19,6 @@ Çerez Açılır Pencere Engelleyici Daha fazla bilgi edin]]> - Learn More]]> + Daha Fazla Bilgi]]> DuckDuckGo\'nun çerez açılır pencereleri için gereken işlemi yapmasına izin verin \ No newline at end of file diff --git a/autoconsent/autoconsent-impl/src/main/res/values/strings-autoconsent.xml b/autoconsent/autoconsent-impl/src/main/res/values/strings-autoconsent.xml index c7ec3261ee74..0ad9155d0165 100644 --- a/autoconsent/autoconsent-impl/src/main/res/values/strings-autoconsent.xml +++ b/autoconsent/autoconsent-impl/src/main/res/values/strings-autoconsent.xml @@ -19,6 +19,6 @@ Cookie Pop-Up Protection Learn More]]> - Learn More]]> + Learn More]]> Let DuckDuckGo handle cookie pop-ups \ No newline at end of file diff --git a/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml index 20dfcbeef06f..560adf3359ae 100644 --- a/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-bg/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Изход от настройката Пароли - Passwords & Autofill + Пароли и автоматично попълване Все още няма запазени пароли Запазване и автоматично попълване на паролите Паролите са криптирани. Никой освен Вас не може да ги види, дори ние. Научете повече diff --git a/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml index e1746d3e7e66..51578bcdb5fd 100644 --- a/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-cs/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Ukončit nastavení Hesla - Passwords & Autofill + Hesla a automatické vyplňování Zatím nemáš uložená žádná hesla Ukládání a automatické vyplňování hesel Hesla jsou šifrovaná. Nikdo kromě tebe je nevidí, dokonce ani my. Další informace diff --git a/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml index 9b8e43408d5d..9c76e5e42fc2 100644 --- a/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-da/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Afslut opsætning Adgangskoder - Passwords & Autofill + Adgangskoder og automatisk udfyldning Ingen adgangskoder gemt endnu Gem og udfyld adgangskoder automatisk Adgangskoderne er krypterede. Ingen andre end dig kan se dem, ikke engang os. Få mere at vide diff --git a/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml index eef314203da5..2239750e8e3e 100644 --- a/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-de/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Einrichtung beenden Passwörter - Passwords & Autofill + Passwörter und Autovervollständigen Noch keine Passwörter gespeichert Passwörter speichern und automatisch ausfüllen Passwörter sind verschlüsselt. Niemand außer dir kann sie sehen, nicht einmal wir. Mehr erfahren diff --git a/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml index fa0162c1971c..464b1ed30d21 100644 --- a/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-el/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Έξοδος από την εγκατάσταση Κωδικοί πρόσβασης - Passwords & Autofill + Κωδικοί πρόσβασης και Αυτόματη συμπλήρωση Δεν έχουν αποθηκευτεί ακόμα κωδικοί πρόσβασης Αποθήκευση και αυτόματη συμπλήρωση κωδικών πρόσβασης Οι κωδικοί πρόσβασης είναι κρυπτογραφημένοι. Κανείς άλλος εκτός από εσάς δεν μπορεί να τους βλέπει, ούτε καν εμείς. Μάθετε περισσότερα diff --git a/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml index e544cce783ec..7b056e724abd 100644 --- a/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-es/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Salir de Configuración Contraseñas - Passwords & Autofill + Contraseñas y autocompletar Aún no hay contraseñas guardadas Guardar y autocompletar contraseñas Las contraseñas están cifradas. Nadie más que tú puede verlas, ni siquiera nosotros. Más información diff --git a/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml index 47e442c59c81..7da15ec829f0 100644 --- a/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-et/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Välju seadistusest Paroolid - Passwords & Autofill + Paroolid ja automaatne täitmine Paroole ei ole veel salvestatud Paroolide salvestamine ja automaatne sisestamine Paroolid on krüpteeritud. Keegi peale sinu ei näe neid, isegi mitte meie. Lisateave diff --git a/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml index 4837eeb69dfe..9e0416f5847a 100644 --- a/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-fi/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Poistu asennuksesta Salasanat - Passwords & Autofill + Salasanat ja automaattinen täyttö Salasanoja ei ole vielä tallennettu Tallenna ja täytä salasanat automaattisesti Salasanat salataan. Kukaan muu kuin sinä ei näe niitä, emme edes me. Lue lisää diff --git a/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml index 8cf40be92c8b..9ac577989a39 100644 --- a/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-fr/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Quitter la configuration Mots de passe - Passwords & Autofill + Mots de passe et saisie automatique Aucun mot de passe n\'a été enregistré Enregistrer et saisir automatiquement les mots de passe Les mots de passe sont cryptés. Personne d\'autre que vous ne peut les voir, pas même nous. En savoir plus diff --git a/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml index d8e8a5059f4a..f50f9ce67c5d 100644 --- a/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-hr/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Izađi iz postavljanja Lozinke - Passwords & Autofill + Lozinke i automatsko popunjavanje Još nema spremljenih lozinki Spremi i automatski popuni lozinke Lozinke su šifrirane. Nitko osim tebe ne može ih vidjeti, čak ni mi. Saznaj više diff --git a/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml index 4211762391e9..913559c02765 100644 --- a/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-hu/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Kilépés a beállításokból Jelszavak - Passwords & Autofill + Jelszavak és automatikus kitöltés Még nincsenek mentett jelszavak Jelszavak mentése és automatikus kitöltése A jelszavak titkosítva vannak. Rajtad kívül senki sem láthatja őket, még mi sem. További tudnivalók diff --git a/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml index 5fff14d1c304..76ab8676a112 100644 --- a/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-it/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Esci dalla configurazione Password - Passwords & Autofill + Password e compilazione automatica Nessuna password ancora salvata Salva e compila automaticamente le password Le password sono crittografate. Nessuno tranne te può vederle, nemmeno noi. Ulteriori informazioni diff --git a/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml index 6383f5691ae7..1efd86f11bd2 100644 --- a/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-lt/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Išeiti iš sąrankos Slaptažodžiai - Passwords & Autofill + Slaptažodžiai ir automatinis užpildymas Dar nėra išsaugotų slaptažodžių Išsaugokite ir automatiškai užpildykite slaptažodžius Slaptažodžiai yra užšifruoti. Niekas, išskyrus jus, negali jų matyti – net mes. Sužinokite daugiau diff --git a/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml index 3c7dc117bd64..463bb4d215a1 100644 --- a/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-lv/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Iziet no iestatīšanas Paroles - Passwords & Autofill + Paroles un automātiskā aizpildīšana Vēl nav saglabāta neviena parole Saglabāt un automātiski aizpildīt paroles Paroles ir šifrētas. Neviens, izņemot tevi, tās nevar redzēt – pat mēs ne. Uzzināt vairāk diff --git a/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml index 3421c3c06351..e6bcedf78940 100644 --- a/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-nb/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Avslutt oppsett Passord - Passwords & Autofill + Passord og autofyll Ingen passord er lagret ennå Lagre og fyll ut passord automatisk Passord krypteres. Ingen andre enn du kan se dem, ikke engang vi. Les mer diff --git a/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml index 4e3fcf1255ba..1fbbdfdc55bb 100644 --- a/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-nl/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Instellen beëindigen Wachtwoorden - Passwords & Autofill + Wachtwoorden en automatisch invullen Nog geen wachtwoorden opgeslagen Wachtwoorden opslaan en automatisch invullen Wachtwoorden worden versleuteld. Niemand anders dan jij kunt ze zien, zelfs wij niet. Meer informatie diff --git a/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml index 6831fa90a799..7607d9e61eac 100644 --- a/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-pl/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Wyjdź z konfiguracji Hasła - Passwords & Autofill + Hasła i autouzupełnianie Nie zapisano jeszcze żadnych haseł Zapisuj i automatycznie uzupełniaj hasła Hasła są szyfrowane. Nikt poza Tobą ich nie widzi, nawet my. Dowiedz się więcej diff --git a/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml index be2002a88f2c..04a0413cdcb7 100644 --- a/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-pt/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Sair da instalação Palavras-passe - Passwords & Autofill + Palavras-passe e preenchimento automático Ainda não há palavras-passe guardadas Guardar e preencher palavras-passe automaticamente As palavras-passe estão encriptadas. Ninguém além de ti pode vê-las, nem mesmo nós. Sabe mais diff --git a/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml index 0d2f277e3747..354855215e6b 100644 --- a/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-ro/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Ieși din configurare Parole - Passwords & Autofill + Parole și completare automată Nici o parolă nu a fost salvată încă Salvează și completează automat parolele Parolele sunt criptate. Nimeni în afară de tine nu le poate vedea, nici măcar noi. Află mai multe diff --git a/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml index cb7e27006f72..1cbbd0b7d57b 100644 --- a/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-ru/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Выйти из настройки Пароли - Passwords & Autofill + Пароли и автозаполнение Сохраненных паролей пока нет Хранение и автозаполнение паролей Пароли подвергаются шифрованию. Никто, кроме вас, их не увидит. Даже мы. Подробнее... diff --git a/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml index 6a58616d76b1..c80eeffd3b59 100644 --- a/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-sk/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Odísť z nastavení Heslá - Passwords & Autofill + Heslá a automatické dopĺňanie Zatiaľ nie sú uložené žiadne heslá Ukladať a automaticky dopĺňať heslá Heslá sú zašifrované. Nikto okrem vás ich nemôže vidieť, dokonca ani my. Zistiť viac diff --git a/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml index bc09d5f78eed..dfde5e35e2ef 100644 --- a/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-sl/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Izhod iz nastavitev Gesla - Passwords & Autofill + Gesla in samodejno izpolnjevanje Nobeno geslo še ni shranjeno Shranite in samodejno izpolnite gesla Gesla so šifrirana. Nihče razen vas jih ne more videti, niti mi. Več o tem diff --git a/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml index 872e33e90207..e6797094f897 100644 --- a/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-sv/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Avsluta inställningen Lösenord - Passwords & Autofill + Lösenord och automatisk ifyllning Inga lösenord sparade ännu Spara och fyll i lösenord automatiskt Lösenorden är krypterade. Ingen annan än du kan se dem, inte ens vi. Läs mer diff --git a/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml index 6c771f39fb30..3cd7de0326a5 100644 --- a/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values-tr/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Kurulumdan Çık Şifreler - Passwords & Autofill + Şifreler ve Otomatik Doldurma Henüz şifre kaydedilmedi Şifreleri kaydedin ve otomatik doldurun Parolalar şifrelenir. Onları sizden başka kimse göremez. Biz bile. Daha Fazla Bilgi diff --git a/autofill/autofill-impl/src/main/res/values/strings-autofill-impl.xml b/autofill/autofill-impl/src/main/res/values/strings-autofill-impl.xml index 092dce600281..dfc38fe5506b 100644 --- a/autofill/autofill-impl/src/main/res/values/strings-autofill-impl.xml +++ b/autofill/autofill-impl/src/main/res/values/strings-autofill-impl.xml @@ -120,7 +120,7 @@ Exit Setup Passwords - Passwords & Autofill + Passwords & Autofill No passwords saved yet Save and Autofill Passwords Passwords are encrypted. Nobody but you can see them, not even us. Learn More diff --git a/common/common-ui/src/main/res/values-bg/strings-common-ui.xml b/common/common-ui/src/main/res/values-bg/strings-common-ui.xml index 25d47c4a7df1..8d990ba8b708 100644 --- a/common/common-ui/src/main/res/values-bg/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-bg/strings-common-ui.xml @@ -34,7 +34,7 @@ Отмени - Always On - On - Off + Винаги включено + Включен + Изключено
    diff --git a/common/common-ui/src/main/res/values-cs/strings-common-ui.xml b/common/common-ui/src/main/res/values-cs/strings-common-ui.xml index 64e3497e208e..a96d14489ffe 100644 --- a/common/common-ui/src/main/res/values-cs/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-cs/strings-common-ui.xml @@ -34,7 +34,7 @@ Zrušit - Always On - On - Off + Vždycky zapnuté + Aktivní + Vypnout
    diff --git a/common/common-ui/src/main/res/values-da/strings-common-ui.xml b/common/common-ui/src/main/res/values-da/strings-common-ui.xml index d7401d0009b2..9f2e4db0a1d7 100644 --- a/common/common-ui/src/main/res/values-da/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-da/strings-common-ui.xml @@ -34,7 +34,7 @@ Annullér - Always On - On - Off + Altid aktiv + Til + Fra
    diff --git a/common/common-ui/src/main/res/values-de/strings-common-ui.xml b/common/common-ui/src/main/res/values-de/strings-common-ui.xml index d68cb30d9ce3..bb3224374613 100644 --- a/common/common-ui/src/main/res/values-de/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-de/strings-common-ui.xml @@ -34,7 +34,7 @@ Abbrechen - Always On - On - Off + Immer aktiviert + Ein + Aus
    diff --git a/common/common-ui/src/main/res/values-el/strings-common-ui.xml b/common/common-ui/src/main/res/values-el/strings-common-ui.xml index 7a7d5d84c74b..65982e90f68c 100644 --- a/common/common-ui/src/main/res/values-el/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-el/strings-common-ui.xml @@ -34,7 +34,7 @@ Ακύρωση - Always On - On - Off + Πάντα σε λειτουργία + Ενεργό + Κλειστό
    diff --git a/common/common-ui/src/main/res/values-es/strings-common-ui.xml b/common/common-ui/src/main/res/values-es/strings-common-ui.xml index 2d981d50da10..f7ac54ba0fd5 100644 --- a/common/common-ui/src/main/res/values-es/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-es/strings-common-ui.xml @@ -34,7 +34,7 @@ Cancelar - Always On - On - Off + Siempre activado + Activado + Desactivado
    diff --git a/common/common-ui/src/main/res/values-et/strings-common-ui.xml b/common/common-ui/src/main/res/values-et/strings-common-ui.xml index f7c2ec340c32..f2ba4b3e449f 100644 --- a/common/common-ui/src/main/res/values-et/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-et/strings-common-ui.xml @@ -34,7 +34,7 @@ Tühista - Always On - On - Off + Alati sisse lülitatud + Sees + Väljas
    diff --git a/common/common-ui/src/main/res/values-fi/strings-common-ui.xml b/common/common-ui/src/main/res/values-fi/strings-common-ui.xml index 8b2e2c151394..68e238bf1475 100644 --- a/common/common-ui/src/main/res/values-fi/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-fi/strings-common-ui.xml @@ -34,7 +34,7 @@ Peruuta - Always On - On - Off + Aina käytössä + Päällä + Pois
    diff --git a/common/common-ui/src/main/res/values-fr/strings-common-ui.xml b/common/common-ui/src/main/res/values-fr/strings-common-ui.xml index df57afd0619d..38f1f210264d 100644 --- a/common/common-ui/src/main/res/values-fr/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-fr/strings-common-ui.xml @@ -34,7 +34,7 @@ Annuler - Always On - On - Off + Toujours activé + Activé + Off
    diff --git a/common/common-ui/src/main/res/values-hr/strings-common-ui.xml b/common/common-ui/src/main/res/values-hr/strings-common-ui.xml index 17cc43087cc3..e2660e1ca410 100644 --- a/common/common-ui/src/main/res/values-hr/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-hr/strings-common-ui.xml @@ -34,7 +34,7 @@ Odustani - Always On - On - Off + Uvijek uključeno + Uključeno + Isključeno
    diff --git a/common/common-ui/src/main/res/values-hu/strings-common-ui.xml b/common/common-ui/src/main/res/values-hu/strings-common-ui.xml index 615597fe7f63..9c3398ad509e 100644 --- a/common/common-ui/src/main/res/values-hu/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-hu/strings-common-ui.xml @@ -34,7 +34,7 @@ Mégsem - Always On - On - Off + Mindig be van kapcsolva + Be + Ki
    diff --git a/common/common-ui/src/main/res/values-it/strings-common-ui.xml b/common/common-ui/src/main/res/values-it/strings-common-ui.xml index 50d4faf502bf..d2857742065e 100644 --- a/common/common-ui/src/main/res/values-it/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-it/strings-common-ui.xml @@ -34,7 +34,7 @@ Annulla - Always On - On - Off + Sempre attiva + On + Disabilitato
    diff --git a/common/common-ui/src/main/res/values-lt/strings-common-ui.xml b/common/common-ui/src/main/res/values-lt/strings-common-ui.xml index 5eb4259353aa..f0702097b363 100644 --- a/common/common-ui/src/main/res/values-lt/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-lt/strings-common-ui.xml @@ -34,7 +34,7 @@ Atšaukti - Always On - On - Off + Visada įjungta + Įjungti + Išjungti
    diff --git a/common/common-ui/src/main/res/values-lv/strings-common-ui.xml b/common/common-ui/src/main/res/values-lv/strings-common-ui.xml index 8ea8f4ea275e..8ad6d94d8b78 100644 --- a/common/common-ui/src/main/res/values-lv/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-lv/strings-common-ui.xml @@ -34,7 +34,7 @@ Atcelt - Always On - On - Off + Vienmēr ieslēgts + Ieslēgts + Izslēgts
    diff --git a/common/common-ui/src/main/res/values-nb/strings-common-ui.xml b/common/common-ui/src/main/res/values-nb/strings-common-ui.xml index d22d024059dc..c8bfc1f416d3 100644 --- a/common/common-ui/src/main/res/values-nb/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-nb/strings-common-ui.xml @@ -34,7 +34,7 @@ Avbryt - Always On - On - Off + Alltid på + + Av
    diff --git a/common/common-ui/src/main/res/values-nl/strings-common-ui.xml b/common/common-ui/src/main/res/values-nl/strings-common-ui.xml index b94f5cb4647e..d669a5aaf1b4 100644 --- a/common/common-ui/src/main/res/values-nl/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-nl/strings-common-ui.xml @@ -34,7 +34,7 @@ Annuleren - Always On - On - Off + Altijd aan + Aan + Uit
    diff --git a/common/common-ui/src/main/res/values-pl/strings-common-ui.xml b/common/common-ui/src/main/res/values-pl/strings-common-ui.xml index b7ee548f5294..c4af1054740f 100644 --- a/common/common-ui/src/main/res/values-pl/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-pl/strings-common-ui.xml @@ -34,7 +34,7 @@ Anuluj - Always On - On - Off + Zawsze włączone + Wł. + Wyłączone
    diff --git a/common/common-ui/src/main/res/values-pt/strings-common-ui.xml b/common/common-ui/src/main/res/values-pt/strings-common-ui.xml index 15889221f5e5..8e1106f04077 100644 --- a/common/common-ui/src/main/res/values-pt/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-pt/strings-common-ui.xml @@ -34,7 +34,7 @@ Cancelar - Always On - On - Off + Sempre ligada + Ligado + Desligado
    diff --git a/common/common-ui/src/main/res/values-ro/strings-common-ui.xml b/common/common-ui/src/main/res/values-ro/strings-common-ui.xml index c84496cd8709..0cfe73e8cc2a 100644 --- a/common/common-ui/src/main/res/values-ro/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-ro/strings-common-ui.xml @@ -34,7 +34,7 @@ Anulează - Always On - On - Off + Întotdeauna activat + Activat + Dezactivat
    diff --git a/common/common-ui/src/main/res/values-ru/strings-common-ui.xml b/common/common-ui/src/main/res/values-ru/strings-common-ui.xml index c54b92d895b5..1a48f590ca33 100644 --- a/common/common-ui/src/main/res/values-ru/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-ru/strings-common-ui.xml @@ -34,7 +34,7 @@ Отменить - Always On - On - Off + Всегда включено + вкл. + Выкл
    diff --git a/common/common-ui/src/main/res/values-sk/strings-common-ui.xml b/common/common-ui/src/main/res/values-sk/strings-common-ui.xml index ba49777d6852..8b1ea21b141c 100644 --- a/common/common-ui/src/main/res/values-sk/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-sk/strings-common-ui.xml @@ -34,7 +34,7 @@ Zrušiť - Always On - On - Off + Vždy zapnuté + Zapnuté + Vypnuté
    diff --git a/common/common-ui/src/main/res/values-sl/strings-common-ui.xml b/common/common-ui/src/main/res/values-sl/strings-common-ui.xml index 9f53c38a520e..e98e9ca94347 100644 --- a/common/common-ui/src/main/res/values-sl/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-sl/strings-common-ui.xml @@ -34,7 +34,7 @@ Preklic - Always On - On - Off + Vedno vklopljeno + Vključeno + Izklopljeno
    diff --git a/common/common-ui/src/main/res/values-sv/strings-common-ui.xml b/common/common-ui/src/main/res/values-sv/strings-common-ui.xml index 52cc5a62b035..007b754ad045 100644 --- a/common/common-ui/src/main/res/values-sv/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-sv/strings-common-ui.xml @@ -34,7 +34,7 @@ Avbryt - Always On - On - Off + Alltid på + + Av
    diff --git a/common/common-ui/src/main/res/values-tr/strings-common-ui.xml b/common/common-ui/src/main/res/values-tr/strings-common-ui.xml index e05a40dcc94d..0b8b9e152e6f 100644 --- a/common/common-ui/src/main/res/values-tr/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values-tr/strings-common-ui.xml @@ -34,7 +34,7 @@ Vazgeç - Always On - On - Off + Her Zaman Açık + Açık + Kapalı
    diff --git a/common/common-ui/src/main/res/values/strings-common-ui.xml b/common/common-ui/src/main/res/values/strings-common-ui.xml index a968c0fc3072..12d0143b6d06 100644 --- a/common/common-ui/src/main/res/values/strings-common-ui.xml +++ b/common/common-ui/src/main/res/values/strings-common-ui.xml @@ -34,7 +34,7 @@ Cancel - Always On - On - Off + Always On + On + Off
    diff --git a/subscriptions/subscriptions-impl/src/main/res/values-bg/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-bg/strings-subscriptions.xml index daf32e3e4828..091524ccd318 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-bg/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-bg/strings-subscriptions.xml @@ -78,6 +78,7 @@ Премахване от това устройство Помощ и поддръжка Изпратете отзив + Активиране Всичко е готово. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-cs/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-cs/strings-subscriptions.xml index 10644dccb90f..8887c226d06a 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-cs/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-cs/strings-subscriptions.xml @@ -78,6 +78,7 @@ Odebrat z tohohle zařízení Nápověda a podpora Odeslat zpětnou vazbu + Aktivuje se A je to. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-da/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-da/strings-subscriptions.xml index 98e5f5006269..65c11b5d3f26 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-da/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-da/strings-subscriptions.xml @@ -78,6 +78,7 @@ Fjern fra denne enhed Hjælp og support Send tilbagemelding + Aktiverer Du er klar. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-de/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-de/strings-subscriptions.xml index 03af65767526..53f08d18d606 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-de/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-de/strings-subscriptions.xml @@ -78,6 +78,7 @@ Von diesem Gerät entfernen Hilfe und Support Rückmeldung senden + Wird aktiviert Du bist startklar. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-el/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-el/strings-subscriptions.xml index cd1c9b60aea3..105ea311f77f 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-el/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-el/strings-subscriptions.xml @@ -78,6 +78,7 @@ Αφαίρεση από αυτήν τη συσκευή Βοήθεια και υποστήριξη Αποστολή σχολίου + Ενεργοποίηση Είστε πανέτοιμοι. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-es/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-es/strings-subscriptions.xml index c3a53a29ee6b..f65b9af298bc 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-es/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-es/strings-subscriptions.xml @@ -78,6 +78,7 @@ Eliminar de este dispositivo Ayuda y asistencia Enviar comentarios + Activando ¡Todo listo! diff --git a/subscriptions/subscriptions-impl/src/main/res/values-et/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-et/strings-subscriptions.xml index 25715c93737c..3495c69f8e0b 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-et/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-et/strings-subscriptions.xml @@ -78,6 +78,7 @@ Eemalda sellest seadmest Abi ja tugi Saada tagasisidet + Aktiveerimine Kõik on valmis. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-fi/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-fi/strings-subscriptions.xml index dadf2f330df5..55c564da6079 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-fi/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-fi/strings-subscriptions.xml @@ -78,6 +78,7 @@ Poista tältä laitteelta Apu ja tuki Lähetä palautetta + Aktivoidaan Kaikki on valmista. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-fr/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-fr/strings-subscriptions.xml index 0e5ac3cb30eb..74ff5e8720e0 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-fr/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-fr/strings-subscriptions.xml @@ -78,6 +78,7 @@ Supprimer de cet appareil Aide et assistance Envoyer vos remarques + Activation en cours Tout est prêt ! diff --git a/subscriptions/subscriptions-impl/src/main/res/values-hr/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-hr/strings-subscriptions.xml index b046d65afe18..14332f6029a6 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-hr/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-hr/strings-subscriptions.xml @@ -78,6 +78,7 @@ Ukloni s ovog uređaja Pomoć i podrška Pošalji povratnu informaciju + Aktiviranje u tijeku... Sve je spremno. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-hu/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-hu/strings-subscriptions.xml index 06624bbbdc72..38514cb62fbe 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-hu/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-hu/strings-subscriptions.xml @@ -78,6 +78,7 @@ Eltávolítás erről az eszközről Segítség és támogatás Visszajelzés küldése + Aktiválás Minden készen áll. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-it/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-it/strings-subscriptions.xml index a4c08d692c2b..d67ccf6cf6b0 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-it/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-it/strings-subscriptions.xml @@ -78,6 +78,7 @@ Rimuovi da questo dispositivo Aiuto e assistenza Invia feedback + Attivazione in corso… È tutto pronto. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-lt/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-lt/strings-subscriptions.xml index 792da09dcc9b..98a4876a0bd4 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-lt/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-lt/strings-subscriptions.xml @@ -78,6 +78,7 @@ Pašalinti iš šio įrenginio Pagalba ir palaikymas Siųsti atsiliepimą + Aktyvavimas Viskas paruošta. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-lv/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-lv/strings-subscriptions.xml index 94e24caf99e0..bc55caef8485 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-lv/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-lv/strings-subscriptions.xml @@ -78,6 +78,7 @@ Noņemt no šīs ierīces Palīdzība un atbalsts Sūtīt atsauksmi + Notiek aktivizēšana Viss ir gatavs. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-nb/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-nb/strings-subscriptions.xml index f41777a9c6a5..c3fd299e9095 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-nb/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-nb/strings-subscriptions.xml @@ -78,6 +78,7 @@ Fjern fra denne enheten Hjelp og kundestøtte Send tilbakemelding + Aktiverer Alt klart. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-nl/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-nl/strings-subscriptions.xml index 48c8302dd241..c02eb80827bc 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-nl/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-nl/strings-subscriptions.xml @@ -78,6 +78,7 @@ Verwijderen van dit apparaat Hulp en ondersteuning Verstuur feedback + Bezig met activeren Je bent klaar. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-pl/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-pl/strings-subscriptions.xml index e9a6a72e53d6..dd8c1aaa04a7 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-pl/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-pl/strings-subscriptions.xml @@ -78,6 +78,7 @@ Usuń z tego urządzenia Pomoc i wsparcie Wyślij opinię + Aktywacja Wszystko gotowe. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-pt/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-pt/strings-subscriptions.xml index 3e1680d5684a..af0d1c320b06 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-pt/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-pt/strings-subscriptions.xml @@ -78,6 +78,7 @@ Remover Deste Dispositivo Ajuda e Suporte Enviar comentário + A ativar… Está tudo pronto. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-ro/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-ro/strings-subscriptions.xml index 9664f8cbaa39..de3368adc695 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-ro/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-ro/strings-subscriptions.xml @@ -78,6 +78,7 @@ Elimină de pe acest dispozitiv Ajutor și suport Trimite feedback + Se activează Ești gata. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-ru/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-ru/strings-subscriptions.xml index d9085f7284c4..d3aabf5a43ab 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-ru/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-ru/strings-subscriptions.xml @@ -78,6 +78,7 @@ Удалить с этого устройства Справка и поддержка Отправить отзыв + Выполняется активация Все готово! diff --git a/subscriptions/subscriptions-impl/src/main/res/values-sk/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-sk/strings-subscriptions.xml index f7aee982b57f..6502b97114f2 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-sk/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-sk/strings-subscriptions.xml @@ -78,6 +78,7 @@ Odstrániť z tohto zariadenia Pomoc a podpora Odoslať spätnú väzbu + Aktivácia Máš všetko pripravené. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-sl/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-sl/strings-subscriptions.xml index 160ace4500f4..210d6e3e167e 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-sl/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-sl/strings-subscriptions.xml @@ -78,6 +78,7 @@ Odstrani iz te naprave Pomoč in podpora Pošljite povratne informacije + Aktiviranje Vse je pripravljeno. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-sv/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-sv/strings-subscriptions.xml index 00cb2c5e585c..224bb1cce2b5 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-sv/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-sv/strings-subscriptions.xml @@ -78,6 +78,7 @@ Ta bort från den här enheten Hjälp och support Skicka återkoppling + Aktiverar Du är klar. diff --git a/subscriptions/subscriptions-impl/src/main/res/values-tr/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values-tr/strings-subscriptions.xml index 1b14ea04f7d2..43caf1c716d5 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values-tr/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values-tr/strings-subscriptions.xml @@ -78,6 +78,7 @@ Bu Cihazdan Kaldır Yardım ve Destek Geri Bildirim gönder + Etkinleştiriliyor Her şey hazır. diff --git a/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml b/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml deleted file mode 100644 index f002ba80c3d9..000000000000 --- a/subscriptions/subscriptions-impl/src/main/res/values/donottranslate.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - Activating - - diff --git a/subscriptions/subscriptions-impl/src/main/res/values/strings-subscriptions.xml b/subscriptions/subscriptions-impl/src/main/res/values/strings-subscriptions.xml index 7927174f0331..9d16769ee752 100644 --- a/subscriptions/subscriptions-impl/src/main/res/values/strings-subscriptions.xml +++ b/subscriptions/subscriptions-impl/src/main/res/values/strings-subscriptions.xml @@ -77,6 +77,7 @@ Remove From This Device Help and Support Send Feedback + Activating You\'re all set. diff --git a/sync/sync-impl/src/main/res/values-bg/strings-sync.xml b/sync/sync-impl/src/main/res/values-bg/strings-sync.xml index c4d915a3c43f..e921564538a4 100644 --- a/sync/sync-impl/src/main/res/values-bg/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-bg/strings-sync.xml @@ -36,7 +36,7 @@ Сигурно синхронизиране на отметките и паролите между отделни устройства. Данните Ви са изцяло криптирани и DuckDuckGo няма достъп до ключа за криптиране. Настройка на едно устройство - Other Options + Други опции Възстановяване на синхронизирани данни Синхронизиране и архивиране на това устройство diff --git a/sync/sync-impl/src/main/res/values-cs/strings-sync.xml b/sync/sync-impl/src/main/res/values-cs/strings-sync.xml index 63807cc000d9..da7b54679365 100644 --- a/sync/sync-impl/src/main/res/values-cs/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-cs/strings-sync.xml @@ -36,7 +36,7 @@ Bezpečně synchronizuj záložky a hesla mezi svými zařízeními. U tvých dat se uplatňuje end-to-end šifrování a DuckDuckGo nemá přístup k šifrovacímu klíči. Nastavení jednoho zařízení - Other Options + Další možnosti Obnovit synchronizovaná data Synchronizace a záloha tohoto zařízení diff --git a/sync/sync-impl/src/main/res/values-da/strings-sync.xml b/sync/sync-impl/src/main/res/values-da/strings-sync.xml index 2fe5fafe92c4..069ca4303b0f 100644 --- a/sync/sync-impl/src/main/res/values-da/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-da/strings-sync.xml @@ -36,7 +36,7 @@ Synkroniser sikkert bogmærker og adgangskoder mellem dine enheder. Dine data er fuldt krypterede, og DuckDuckGo har ikke adgang til krypteringsnøglen. Opsætning af en enkelt enhed - Other Options + Andre muligheder Gendan synkroniserede data Synkroniser og sikkerhedskopier denne enhed diff --git a/sync/sync-impl/src/main/res/values-de/strings-sync.xml b/sync/sync-impl/src/main/res/values-de/strings-sync.xml index 5e4e14ee47c1..e583b129aa3d 100644 --- a/sync/sync-impl/src/main/res/values-de/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-de/strings-sync.xml @@ -36,7 +36,7 @@ Lesezeichen und Passwörter sicher zwischen deinen Geräten synchronisieren. Deine Daten sind Ende-zu-Ende-verschlüsselt. DuckDuckGo hat keinen Zugriff auf den Verschlüsselungsschlüssel. Einrichtung für ein einzelnes Gerät - Other Options + Andere Optionen Synchronisierte Daten wiederherstellen Dieses Gerät synchronisieren und sichern diff --git a/sync/sync-impl/src/main/res/values-el/strings-sync.xml b/sync/sync-impl/src/main/res/values-el/strings-sync.xml index 319ba2623844..544c916ec2dd 100644 --- a/sync/sync-impl/src/main/res/values-el/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-el/strings-sync.xml @@ -36,7 +36,7 @@ Συγχρονίστε με ασφάλεια σελιδοδείκτες και κωδικούς πρόσβασης μεταξύ των συσκευών σας. Τα δεδομένα σας είναι κρυπτογραφημένα από άκρο σε άκρο και το DuckDuckGo δεν έχει πρόσβαση στο κλειδί κρυπτογράφησης. Εγκατάσταση μίας συσκευής - Other Options + Άλλες επιλογές Ανάκτηση συγχρονισμένων δεδομένων Συγχρονισμός και δημιουργία αντιγράφων ασφάλειας αυτής της συσκευής diff --git a/sync/sync-impl/src/main/res/values-es/strings-sync.xml b/sync/sync-impl/src/main/res/values-es/strings-sync.xml index b4893b2df82e..0ffa201bad80 100644 --- a/sync/sync-impl/src/main/res/values-es/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-es/strings-sync.xml @@ -36,7 +36,7 @@ Sincroniza de forma segura los marcadores y las contraseñas entre tus dispositivos. Tus datos están encriptados de extremo a extremo y DuckDuckGo no tiene acceso a la clave de encriptación. Configuración para un solo dispositivo - Other Options + Otras opciones Recuperar datos sincronizados Sincronizar y hacer una copia de seguridad de este dispositivo diff --git a/sync/sync-impl/src/main/res/values-et/strings-sync.xml b/sync/sync-impl/src/main/res/values-et/strings-sync.xml index 9fb182435445..01536353d396 100644 --- a/sync/sync-impl/src/main/res/values-et/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-et/strings-sync.xml @@ -36,7 +36,7 @@ Sünkrooni järjehoidjaid ja paroole turvaliselt oma seadmete vahel. Sinu andmed on otsast lõpuni krüptitud ja DuckDuckGo ei pääse krüpteerimisvõtmele ligi. Ühe seadme seadistamine - Other Options + Muud valikud Taasta sünkroonitud andmed Selle seadme sünkroonimine ja varundamine diff --git a/sync/sync-impl/src/main/res/values-fi/strings-sync.xml b/sync/sync-impl/src/main/res/values-fi/strings-sync.xml index 46d46251547e..b035c0c5b928 100644 --- a/sync/sync-impl/src/main/res/values-fi/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-fi/strings-sync.xml @@ -36,7 +36,7 @@ Synkronoi kirjanmerkit ja salasanat turvallisesti laitteittesi välillä. Tietosi on salattu päästä päähän, eikä DuckDuckGolla ole hallussaan salausavainta. Yhden laitteen asennus - Other Options + Muut vaihtoehdot Palauta synkronoidut tiedot Synkronoi ja varmuuskopioi tämä laite diff --git a/sync/sync-impl/src/main/res/values-fr/strings-sync.xml b/sync/sync-impl/src/main/res/values-fr/strings-sync.xml index 0b67dc52e9fd..9f28e71a37f1 100644 --- a/sync/sync-impl/src/main/res/values-fr/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-fr/strings-sync.xml @@ -36,7 +36,7 @@ Synchronisez en toute sécurité les signets et mots de passe entre vos appareils. Vos données sont cryptées de bout en bout et DuckDuckGo n\'a pas accès à la clé de chiffrement. Configuration d\'un seul appareil - Other Options + Autres options Récupérer les données synchronisées Synchroniser et sauvegarder cet appareil diff --git a/sync/sync-impl/src/main/res/values-hr/strings-sync.xml b/sync/sync-impl/src/main/res/values-hr/strings-sync.xml index c69cf347b92b..faac18fe777c 100644 --- a/sync/sync-impl/src/main/res/values-hr/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-hr/strings-sync.xml @@ -36,7 +36,7 @@ Sigurno sinkroniziraj oznake i lozinke između svojih uređaja. Tvoji su podaci šifrirani od početka do kraja, a DuckDuckGo nema pristup ključu za šifriranje. Postavljanje jednog uređaja - Other Options + Ostale mogućnosti Oporavak sinkroniziranih podataka Sinkroniziraj i izradi sigurnosnu kopiju ovog uređaja diff --git a/sync/sync-impl/src/main/res/values-hu/strings-sync.xml b/sync/sync-impl/src/main/res/values-hu/strings-sync.xml index c80c7449efc4..5ebd5ea99d79 100644 --- a/sync/sync-impl/src/main/res/values-hu/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-hu/strings-sync.xml @@ -36,7 +36,7 @@ Szinkronizáld biztonságosan a könyvjelzőket és jelszavakat az eszközök között. Az adataid végponttól végpontig titkosítva vannak, a DuckDuckGo pedig nem fér hozzá a titkosítási kulcshoz. Egyeszközös beállítás - Other Options + Egyéb lehetőségek Szinkronizált adatok helyreállítása Az eszköz szinkronizálása és biztonsági mentése diff --git a/sync/sync-impl/src/main/res/values-it/strings-sync.xml b/sync/sync-impl/src/main/res/values-it/strings-sync.xml index 04158bb8e6f5..9767a07ac912 100644 --- a/sync/sync-impl/src/main/res/values-it/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-it/strings-sync.xml @@ -36,7 +36,7 @@ Sincronizza in sicurezza i segnalibri e le password tra i tuoi dispositivi. I tuoi dati sono crittografati end-to-end e DuckDuckGo non ha accesso alla chiave di crittografia. Configurazione di un singolo dispositivo - Other Options + Altre opzioni Recupera i dati sincronizzati Sincronizza ed esegui il backup di questo dispositivo diff --git a/sync/sync-impl/src/main/res/values-lt/strings-sync.xml b/sync/sync-impl/src/main/res/values-lt/strings-sync.xml index eba727b6d5dd..8f34da2caec4 100644 --- a/sync/sync-impl/src/main/res/values-lt/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-lt/strings-sync.xml @@ -36,7 +36,7 @@ Saugiai sinchronizuokite žymes ir slaptažodžius tarp savo įrenginių. Jūsų duomenys šifruojami ištisiniu būdu, o „DuckDuckGo“ neturi prieigos prie šifravimo rakto. Vieno įrenginio sąranka - Other Options + Kitos parinktys Atkurti sinchronizuotus duomenis Sinchronizuokite ir sukurkite atsarginę šio įrenginio kopiją diff --git a/sync/sync-impl/src/main/res/values-lv/strings-sync.xml b/sync/sync-impl/src/main/res/values-lv/strings-sync.xml index 0a65a8b10969..ad4c839b6898 100644 --- a/sync/sync-impl/src/main/res/values-lv/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-lv/strings-sync.xml @@ -36,7 +36,7 @@ Droši sinhronizē grāmatzīmes un paroles starp ierīcēm. Tavi dati tiek šifrēti no gala līdz galam, un DuckDuckGo nav piekļuves šifrēšanas atslēgai. Vienas ierīces iestatīšana - Other Options + Citas iespējas Sinhronizēto datu atgūšana Šīs ierīces sinhronizācija un dublēšana diff --git a/sync/sync-impl/src/main/res/values-nb/strings-sync.xml b/sync/sync-impl/src/main/res/values-nb/strings-sync.xml index 96c624f323f1..318aa586327a 100644 --- a/sync/sync-impl/src/main/res/values-nb/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-nb/strings-sync.xml @@ -36,7 +36,7 @@ Synkroniser bokmerker og passord på en sikker måte mellom enhetene dine. Dataene dine er ende-til-ende-kryptert og DuckDuckGo har ikke tilgang til krypteringsnøkkelen. Oppsett for én enhet - Other Options + Andre alternativer Gjenopprett synkroniserte data Synkroniser og sikkerhetskopier denne enheten diff --git a/sync/sync-impl/src/main/res/values-nl/strings-sync.xml b/sync/sync-impl/src/main/res/values-nl/strings-sync.xml index a48cba1ce8d2..fe5f0259fe5a 100644 --- a/sync/sync-impl/src/main/res/values-nl/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-nl/strings-sync.xml @@ -36,7 +36,7 @@ Synchroniseer bladwijzers en wachtwoorden veilig tussen je apparaten. Je gegevens zijn volledig versleuteld en DuckDuckGo heeft geen toegang tot de versleutelingscode. Configuratie van één apparaat - Other Options + Andere opties Gesynchroniseerde gegevens herstellen Dit apparaat synchroniseren en back-up maken diff --git a/sync/sync-impl/src/main/res/values-pl/strings-sync.xml b/sync/sync-impl/src/main/res/values-pl/strings-sync.xml index ae9c6e42ad53..632111ae831e 100644 --- a/sync/sync-impl/src/main/res/values-pl/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-pl/strings-sync.xml @@ -36,7 +36,7 @@ Bezpiecznie synchronizuj zakładki i hasła między swoimi urządzeniami. Twoje dane są kompleksowo szyfrowane, a DuckDuckGo nie ma dostępu do klucza szyfrowania. Konfiguracja na jednym urządzeniu - Other Options + Inne opcje Odzyskaj zsynchronizowane dane Synchronizuj i twórz kopie zapasowe tego urządzenia diff --git a/sync/sync-impl/src/main/res/values-pt/strings-sync.xml b/sync/sync-impl/src/main/res/values-pt/strings-sync.xml index bb3f4464c408..2984ca67728b 100644 --- a/sync/sync-impl/src/main/res/values-pt/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-pt/strings-sync.xml @@ -36,7 +36,7 @@ Sincroniza os marcadores e palavras-passe entre os teus dispositivos em segurança. Os teus dados são encriptados de ponta a ponta e o DuckDuckGo não tem acesso à chave de encriptação. Configuração de dispositivo único - Other Options + Outras opções Recuperar dados sincronizados Sincronizar e fazer cópia de segurança deste dispositivo diff --git a/sync/sync-impl/src/main/res/values-ro/strings-sync.xml b/sync/sync-impl/src/main/res/values-ro/strings-sync.xml index 125500b9d484..e1434e235f0e 100644 --- a/sync/sync-impl/src/main/res/values-ro/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-ro/strings-sync.xml @@ -36,7 +36,7 @@ Sincronizează în siguranță marcajele și parolele între dispozitivele tale. Datele tale sunt criptate integral, iar DuckDuckGo nu are acces la cheia de criptare. Configurare pe un singur dispozitiv - Other Options + Alte opțiuni Recuperează datele sincronizate Sincronizează și fă backup pentru acest dispozitiv diff --git a/sync/sync-impl/src/main/res/values-ru/strings-sync.xml b/sync/sync-impl/src/main/res/values-ru/strings-sync.xml index af04a64284d6..eefc0d8ff3f2 100644 --- a/sync/sync-impl/src/main/res/values-ru/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-ru/strings-sync.xml @@ -36,7 +36,7 @@ Безопасная синхронизация закладок и паролей на ваших устройствах. Ваши данные защищены сквозным шифрованием. У DuckDuckGo нет доступа к ключу шифрования. Настройка на одном устройстве - Other Options + Другие варианты Восстановить синхронизированные данные Синхронизация и резервное копирование устройства diff --git a/sync/sync-impl/src/main/res/values-sk/strings-sync.xml b/sync/sync-impl/src/main/res/values-sk/strings-sync.xml index 5eada8423bff..6b708b39d954 100644 --- a/sync/sync-impl/src/main/res/values-sk/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-sk/strings-sync.xml @@ -36,7 +36,7 @@ Bezpečne synchronizujte záložky a heslá medzi svojimi zariadeniami. Vaše údaje sú šifrované na oboch koncoch (end-to-end) a DuckDuckGo nemá prístup k šifrovaciemu kľúču. Nastavenie jedného zariadenia - Other Options + Ďalšie možnosti Obnovenie synchronizovaných údajov Synchronizujte a zálohujte toto zariadenie diff --git a/sync/sync-impl/src/main/res/values-sl/strings-sync.xml b/sync/sync-impl/src/main/res/values-sl/strings-sync.xml index e10923f29932..348fa2faa26a 100644 --- a/sync/sync-impl/src/main/res/values-sl/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-sl/strings-sync.xml @@ -36,7 +36,7 @@ Varno sinhronizirajte zaznamke in gesla med napravami. Vaši podatki so celovito šifrirani in DuckDuckGo nima dostopa do šifrirnega ključa. Nastavitev ene naprave - Other Options + Druge možnosti Obnovitev sinhroniziranih podatkov Sinhronizirajte in varnostno kopirajte to napravo diff --git a/sync/sync-impl/src/main/res/values-sv/strings-sync.xml b/sync/sync-impl/src/main/res/values-sv/strings-sync.xml index fc18134bf3f9..a7eed535aef0 100644 --- a/sync/sync-impl/src/main/res/values-sv/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-sv/strings-sync.xml @@ -36,7 +36,7 @@ Synkronisera bokmärken och lösenord mellan dina enheter på ett säkert sätt. Dina data krypteras under hela vägen och DuckDuckGo har inte tillgång till krypteringsnyckeln. Konfiguration för en enda enhet - Other Options + Andra alternativ Återställ synkroniserade data Synkronisera och säkerhetskopiera denna enhet diff --git a/sync/sync-impl/src/main/res/values-tr/strings-sync.xml b/sync/sync-impl/src/main/res/values-tr/strings-sync.xml index f36ebf13edd4..986ff91bd637 100644 --- a/sync/sync-impl/src/main/res/values-tr/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values-tr/strings-sync.xml @@ -36,7 +36,7 @@ Yer imlerini ve parolaları cihazlarınız arasında güvenli bir şekilde senkronize edin. Verileriniz uçtan uca şifrelenir ve DuckDuckGo\'nun şifreleme anahtarına erişimi yoktur. Tek Cihaz Kurulumu - Other Options + Diğer Seçenekler Senkronize Edilen Verileri Kurtar Bu Cihazı Senkronize Et ve Yedekle diff --git a/sync/sync-impl/src/main/res/values/strings-sync.xml b/sync/sync-impl/src/main/res/values/strings-sync.xml index 3465966ac68f..7b7a75927f7e 100644 --- a/sync/sync-impl/src/main/res/values/strings-sync.xml +++ b/sync/sync-impl/src/main/res/values/strings-sync.xml @@ -36,7 +36,7 @@ Securely sync bookmarks and passwords between your devices. Your data is end-to-end encrypted, and DuckDuckGo does not have access to the encryption key. Single-Device Setup - Other Options + Other Options Recover Synced Data Sync and Back Up This Device From 01076f64964149e5cd26349907de1abaf7c19500 Mon Sep 17 00:00:00 2001 From: Ana Capatina Date: Mon, 6 Jan 2025 09:09:39 +0000 Subject: [PATCH 28/32] Android Crash: java.lang.OutOfMemoryError - com.duckduckgo.autofill.impl.configuration.RealAutofillRuntimeConfigProvider.getRuntimeConfiguration (#5433) Task/Issue URL: https://app.asana.com/0/1200905986587319/1209069285792741/f ### Description Optimized string manipulation within getRuntimeConfiguration function. ### Steps to test this PR Smoke test for autofill. ### NO UI changes --- .../AutofillRuntimeConfigProvider.kt | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/configuration/AutofillRuntimeConfigProvider.kt b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/configuration/AutofillRuntimeConfigProvider.kt index 75fa4a587438..90b0a1f7525e 100644 --- a/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/configuration/AutofillRuntimeConfigProvider.kt +++ b/autofill/autofill-impl/src/main/java/com/duckduckgo/autofill/impl/configuration/AutofillRuntimeConfigProvider.kt @@ -66,11 +66,19 @@ class RealAutofillRuntimeConfigProvider @Inject constructor( ) val availableInputTypes = generateAvailableInputTypes(url) - return rawJs - .replace("// INJECT contentScope HERE", contentScope) - .replace("// INJECT userUnprotectedDomains HERE", userUnprotectedDomains) - .replace("// INJECT userPreferences HERE", userPreferences) - .replace("// INJECT availableInputTypes HERE", availableInputTypes) + return StringBuilder(rawJs).apply { + replacePlaceholder(this, TAG_INJECT_CONTENT_SCOPE, contentScope) + replacePlaceholder(this, TAG_INJECT_USER_UNPROTECTED_DOMAINS, userUnprotectedDomains) + replacePlaceholder(this, TAG_INJECT_USER_PREFERENCES, userPreferences) + replacePlaceholder(this, TAG_INJECT_AVAILABLE_INPUT_TYPES, availableInputTypes) + }.toString() + } + + private fun replacePlaceholder(builder: StringBuilder, placeholder: String, replacement: String) { + val index = builder.indexOf(placeholder) + if (index != -1) { + builder.replace(index, index + placeholder.length, replacement) + } } private suspend fun generateAvailableInputTypes(url: String?): String { @@ -139,4 +147,11 @@ class RealAutofillRuntimeConfigProvider @Inject constructor( } private fun determineIfEmailAvailable(): Boolean = emailManager.isSignedIn() + + companion object { + private const val TAG_INJECT_CONTENT_SCOPE = "// INJECT contentScope HERE" + private const val TAG_INJECT_USER_UNPROTECTED_DOMAINS = "// INJECT userUnprotectedDomains HERE" + private const val TAG_INJECT_USER_PREFERENCES = "// INJECT userPreferences HERE" + private const val TAG_INJECT_AVAILABLE_INPUT_TYPES = "// INJECT availableInputTypes HERE" + } } From 11dcf5ba7cdaaa8821afba6e13364a10c7b07143 Mon Sep 17 00:00:00 2001 From: Ana Capatina Date: Mon, 6 Jan 2025 09:32:06 +0000 Subject: [PATCH 29/32] AppTP: Flaky whenLocalDateNowThenReturnWeeklyCohort test (#5426) Task/Issue URL: https://app.asana.com/0/1200905986587319/1209058892339948/f ### Description Fixed flaky test. `whenLocalDateNowThenReturnWeeklyCohort` should assert on week based year and not the year directly as this makes the expected value to be incorrect in edge-cases where the date is a date in a year and falls into a previous year week. I.e 2025-01-01. ### Steps to test this PR Note: PR Unit tests should pass as it was submitted the same day that caused the failure (2024-01-30). - [x] change `whenLocalDateNowThenReturnWeeklyCohort` date to be `LocalDate.of(2024, 1, 30)` - [x] verify test passes ### NO UI changes --- .../mobile/android/vpn/cohort/RealCohortCalculatorTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app-tracking-protection/vpn-impl/src/test/java/com/duckduckgo/mobile/android/vpn/cohort/RealCohortCalculatorTest.kt b/app-tracking-protection/vpn-impl/src/test/java/com/duckduckgo/mobile/android/vpn/cohort/RealCohortCalculatorTest.kt index c3c987da5d1c..2b90412db854 100644 --- a/app-tracking-protection/vpn-impl/src/test/java/com/duckduckgo/mobile/android/vpn/cohort/RealCohortCalculatorTest.kt +++ b/app-tracking-protection/vpn-impl/src/test/java/com/duckduckgo/mobile/android/vpn/cohort/RealCohortCalculatorTest.kt @@ -80,7 +80,7 @@ class RealCohortCalculatorTest { @Test fun whenLocalDateNowThenReturnWeeklyCohort() { val date = LocalDate.now() - val year = date.year + val year = date.get(IsoFields.WEEK_BASED_YEAR) assertEquals("$year-week-${date.get(IsoFields.WEEK_OF_WEEK_BASED_YEAR)}", cohortCalculator.calculateCohortForDate(date)) } From ad28ee1f94eb29a6b443ae9fd9ac39abe15129af Mon Sep 17 00:00:00 2001 From: Ana Capatina Date: Mon, 6 Jan 2025 09:45:06 +0000 Subject: [PATCH 30/32] Android ANR: com.duckduckgo.app.tabs.ui.TabSwitcherAdapter.loadTabPreviewImage (#5432) Task/Issue URL: https://app.asana.com/0/488551667048375/1209069285792730/f ### Description Moved file operations to background. ### Steps to test this PR - [x] Install from this branch. - [x] Open many tabs and go to the Tab Switcher screen. - [x] Notice the tabs are loaded properly and the app doesn't freeze. ### NO UI changes --- .../app/tabs/ui/TabSwitcherActivity.kt | 2 +- .../app/tabs/ui/TabSwitcherAdapter.kt | 25 +++++++++++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt index 4b2529dbd8c5..9f421caa352c 100644 --- a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherActivity.kt @@ -115,7 +115,7 @@ class TabSwitcherActivity : DuckDuckGoActivity(), TabSwitcherListener, Coroutine private val viewModel: TabSwitcherViewModel by bindViewModel() - private val tabsAdapter: TabSwitcherAdapter by lazy { TabSwitcherAdapter(this, webViewPreviewPersister, this, faviconManager) } + private val tabsAdapter: TabSwitcherAdapter by lazy { TabSwitcherAdapter(this, webViewPreviewPersister, this, faviconManager, dispatchers) } // we need to scroll to show selected tab, but only if it is the first time loading the tabs. private var firstTimeLoadingTabsList = true diff --git a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt index b33be228fc2a..08cecc03ac9b 100644 --- a/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/tabs/ui/TabSwitcherAdapter.kt @@ -47,10 +47,11 @@ import com.duckduckgo.app.tabs.ui.TabSwitcherAdapter.TabViewHolder import com.duckduckgo.app.tabs.ui.TabSwitcherAdapter.TabViewHolder.GridTabViewHolder import com.duckduckgo.app.tabs.ui.TabSwitcherAdapter.TabViewHolder.ListTabViewHolder import com.duckduckgo.common.ui.view.show +import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.common.utils.swap import java.io.File -import java.util.Collections.swap import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import timber.log.Timber class TabSwitcherAdapter( @@ -58,6 +59,7 @@ class TabSwitcherAdapter( private val webViewPreviewPersister: WebViewPreviewPersister, private val lifecycleOwner: LifecycleOwner, private val faviconManager: FaviconManager, + private val dispatchers: DispatcherProvider, ) : Adapter() { private val list = mutableListOf() @@ -174,14 +176,23 @@ class TabSwitcherAdapter( private fun loadTabPreviewImage(tab: TabEntity, glide: RequestManager, holder: GridTabViewHolder) { val previewFile = tab.tabPreviewFile ?: return glide.clear(holder.tabPreview) - val cachedWebViewPreview = File(webViewPreviewPersister.fullPathForFile(tab.tabId, previewFile)) - if (!cachedWebViewPreview.exists()) return glide.clear(holder.tabPreview) - glide.load(cachedWebViewPreview) - .transition(DrawableTransitionOptions.withCrossFade()) - .into(holder.tabPreview) + lifecycleOwner.lifecycleScope.launch { + val cachedWebViewPreview = withContext(dispatchers.io()) { + File(webViewPreviewPersister.fullPathForFile(tab.tabId, previewFile)).takeIf { it.exists() } + } + + if (cachedWebViewPreview == null) { + glide.clear(holder.tabPreview) + return@launch + } + + glide.load(cachedWebViewPreview) + .transition(DrawableTransitionOptions.withCrossFade()) + .into(holder.tabPreview) - holder.tabPreview.show() + holder.tabPreview.show() + } } private fun attachClickListeners(holder: TabViewHolder, tab: TabEntity) { From 9808fea9dc6252d5465f1f0abf096edc8bfec4f3 Mon Sep 17 00:00:00 2001 From: Ana Capatina Date: Mon, 6 Jan 2025 09:45:31 +0000 Subject: [PATCH 31/32] Android Bug: Address Bar can be hidden on NTP by user and doesn't reappear until background/foreground (#5427) Task/Issue URL: https://app.asana.com/0/715106103902962/1209003862601172/f ### Description Fixed scrolling issue on focused view. ### Steps to test this PR See task description for video https://app.asana.com/0/715106103902962/1209003862601172/f Steps to reproduce: - [x] Install from develop. - [x] Have Address Bar set to Top. - [x] On NTP use finger to hold/slide the address bar to the top of the device. - [x] Observe that you can not use any gesture to make the address bar reappear. Steps to test the fix: - [x] Install from this branch. - [x] Have Address Bar set to Top. - [x] On NTP use finger to hold/slide the address bar to the top of the device. - [x] Notice the Address Bar does not scroll. ### NO UI changes --- app/src/main/res/layout/fragment_browser_tab.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/layout/fragment_browser_tab.xml b/app/src/main/res/layout/fragment_browser_tab.xml index 6a1ec794923c..9cefb55c106d 100644 --- a/app/src/main/res/layout/fragment_browser_tab.xml +++ b/app/src/main/res/layout/fragment_browser_tab.xml @@ -58,6 +58,7 @@ android:background="?attr/daxColorSurface" android:layout_width="match_parent" android:layout_height="match_parent" + app:layout_scrollFlags="noScroll" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> Date: Mon, 6 Jan 2025 13:46:08 +0000 Subject: [PATCH 32/32] Updated version number for new release - 5.223.0 --- app/version/version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/version/version.properties b/app/version/version.properties index 943643f2cef4..0ba71a1c077c 100644 --- a/app/version/version.properties +++ b/app/version/version.properties @@ -1 +1 @@ -VERSION=5.222.0 \ No newline at end of file +VERSION=5.223.0 \ No newline at end of file