Skip to content

Commit 8e8956b

Browse files
authored
Remove FXIOS-15234 [Feature flag clean up] Remove felt deletion (#33016)
Remove felt deletion
1 parent ccd204b commit 8e8956b

40 files changed

Lines changed: 56 additions & 628 deletions

File tree

BrowserKit/Sources/Common/Constants/StandardImageIdentifiers.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ public struct StandardImageIdentifiers {
6363
public static let creditCard = "creditCardLarge"
6464
public static let cross = "crossLarge"
6565
public static let crossCircleFill = "crossCircleFillLarge"
66-
public static let dataClearance = "dataClearanceLarge"
6766
public static let delete = "deleteLarge"
6867
public static let deviceDesktop = "deviceDesktopLarge"
6968
public static let deviceDesktopSend = "deviceDesktopSendLarge"

BrowserKit/Sources/Shared/Prefs.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ public struct PrefsKeys {
147147

148148
// Firefox contextual hint
149149
public enum ContextualHints: String, CaseIterable {
150-
case dataClearanceKey = "ContextualHintDataClearance"
151150
case jumpBackinKey = "ContextualHintJumpBackin"
152151
case jumpBackInConfiguredKey = "JumpBackInConfigured"
153152
case jumpBackInSyncedTabKey = "ContextualHintJumpBackInSyncedTab"
@@ -238,9 +237,6 @@ public struct PrefsKeys {
238237
// The timestamp where the app was last opened as default browser
239238
public static let LastOpenedAsDefaultBrowser = "LastOpenedAsDefaultBrowser"
240239

241-
// Used to only show the felt deletion alert confirmation once, used for private mode
242-
public static let dataClearanceAlertShown = "dataClearanceAlertShownKey"
243-
244240
// Used to only show the Default Browser Banner, in Main Menu, until is dismissed by the user
245241
public static let defaultBrowserBannerShown = "defaultBrowserBannerShownKey"
246242

firefox-ios/Client.xcodeproj/project.pbxproj

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,6 @@
11911191
8AAEBA082BF52708000C02B5 /* MicrosurveyCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AAEBA072BF52708000C02B5 /* MicrosurveyCoordinator.swift */; };
11921192
8AAEBA0B2BF53AF6000C02B5 /* MicrosurveyStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AAEBA092BF53AB5000C02B5 /* MicrosurveyStateTests.swift */; };
11931193
8AB30EC82B6C038600BD9A9B /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 8AB30EC72B6C038600BD9A9B /* Lottie */; };
1194-
8AB30ECA2B6C03C700BD9A9B /* DataClearanceAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB30EC92B6C03C700BD9A9B /* DataClearanceAnimation.swift */; };
11951194
8AB53B3A2D4138F200C97590 /* MessageCardMiddleware.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB53B392D4138ED00C97590 /* MessageCardMiddleware.swift */; };
11961195
8AB53B3E2D41463900C97590 /* MessageCardAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB53B3D2D41463400C97590 /* MessageCardAction.swift */; };
11971196
8AB8571F27D931B40075C173 /* EmptyTopSiteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB8571E27D931B40075C173 /* EmptyTopSiteCell.swift */; };
@@ -1206,8 +1205,6 @@
12061205
8AB893A92C73CBBD00DAEED7 /* CreditCardProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB893A82C73CBBD00DAEED7 /* CreditCardProvider.swift */; };
12071206
8ABA9C8D28931223002C0077 /* MockDispatchQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ABA9C8C28931223002C0077 /* MockDispatchQueue.swift */; };
12081207
8ABB15C92D5A4E3900A4635C /* RemoteTabsMiddlewareTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ABB15C82D5A4E3900A4635C /* RemoteTabsMiddlewareTests.swift */; };
1209-
8ABCFEA32B45C36100C2988A /* PrivateBrowsingTelemetry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ABCFEA22B45C36100C2988A /* PrivateBrowsingTelemetry.swift */; };
1210-
8ABCFEA62B45CB4C00C2988A /* PrivateBrowsingTelemetryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ABCFEA42B45CAC300C2988A /* PrivateBrowsingTelemetryTests.swift */; };
12111208
8ABDBAA62CB6BF6600B51F63 /* HomepageHeaderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8ABDBAA52CB6BF6600B51F63 /* HomepageHeaderCell.swift */; };
12121209
8ABE9F1A2CB45B4B0080E1DF /* RemotePasswordRules.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AF4E7702C45B98F00BAD91C /* RemotePasswordRules.json */; };
12131210
8ABE9F1B2CB4620A0080E1DF /* RemoteSettingsFetchConfig.json in Resources */ = {isa = PBXBuildFile; fileRef = 8AF4E76D2C41D86100BAD91C /* RemoteSettingsFetchConfig.json */; };
@@ -9382,7 +9379,6 @@
93829379
8AAEBA072BF52708000C02B5 /* MicrosurveyCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MicrosurveyCoordinator.swift; sourceTree = "<group>"; };
93839380
8AAEBA092BF53AB5000C02B5 /* MicrosurveyStateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MicrosurveyStateTests.swift; sourceTree = "<group>"; };
93849381
8AB04613B101195AADCC1F1B /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = "cs.lproj/Default Browser.strings"; sourceTree = "<group>"; };
9385-
8AB30EC92B6C03C700BD9A9B /* DataClearanceAnimation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataClearanceAnimation.swift; sourceTree = "<group>"; };
93869382
8AB53B392D4138ED00C97590 /* MessageCardMiddleware.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageCardMiddleware.swift; sourceTree = "<group>"; };
93879383
8AB53B3D2D41463400C97590 /* MessageCardAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageCardAction.swift; sourceTree = "<group>"; };
93889384
8AB8571E27D931B40075C173 /* EmptyTopSiteCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyTopSiteCell.swift; sourceTree = "<group>"; };
@@ -9393,8 +9389,6 @@
93939389
8AB893A82C73CBBD00DAEED7 /* CreditCardProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditCardProvider.swift; sourceTree = "<group>"; };
93949390
8ABA9C8C28931223002C0077 /* MockDispatchQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDispatchQueue.swift; sourceTree = "<group>"; };
93959391
8ABB15C82D5A4E3900A4635C /* RemoteTabsMiddlewareTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteTabsMiddlewareTests.swift; sourceTree = "<group>"; };
9396-
8ABCFEA22B45C36100C2988A /* PrivateBrowsingTelemetry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivateBrowsingTelemetry.swift; sourceTree = "<group>"; };
9397-
8ABCFEA42B45CAC300C2988A /* PrivateBrowsingTelemetryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivateBrowsingTelemetryTests.swift; sourceTree = "<group>"; };
93989392
8ABDBAA52CB6BF6600B51F63 /* HomepageHeaderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomepageHeaderCell.swift; sourceTree = "<group>"; };
93999393
8ABE9F1C2CB462730080E1DF /* RemoteSettingsFetchConfigTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteSettingsFetchConfigTests.swift; sourceTree = "<group>"; };
94009394
8AC0B1BF2D1D9356004237FD /* ContextMenuConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuConfiguration.swift; sourceTree = "<group>"; };
@@ -13213,7 +13207,6 @@
1321313207
children = (
1321413208
810FF3532B178343009F062C /* FeltPrivacyMiddleware.swift */,
1321513209
810FF3572B1784E7009F062C /* PrivateModeAction.swift */,
13216-
8AB30EC92B6C03C700BD9A9B /* DataClearanceAnimation.swift */,
1321713210
);
1321813211
path = FeltPrivacy;
1321913212
sourceTree = "<group>";
@@ -16246,7 +16239,6 @@
1624616239
8A44F20D2B585E1F0016BC81 /* HomepageTelemetry.swift */,
1624716240
5A32C2B42AD8515F00A9B5A4 /* MetricKit */,
1624816241
8A1AB6BA2E7B8D5C00167FF5 /* NotificationManagerTelemetry.swift */,
16249-
8ABCFEA22B45C36100C2988A /* PrivateBrowsingTelemetry.swift */,
1625016242
8ADC2A132A33762900543DAA /* ReferringPage.swift */,
1625116243
43F7952425795F69005AEE40 /* SearchTelemetry.swift */,
1625216244
E51E24922EF1743D004F7785 /* ShareExtensionTelemetry.swift */,
@@ -16583,7 +16575,6 @@
1658316575
CA24B52024ABD7D40093848C /* PasswordManagerViewModelTests.swift */,
1658416576
CA24B53824ABFE250093848C /* PasswordManagerSelectionHelperTests.swift */,
1658516577
2FDB10921A9FBEC5006CF312 /* PrefsTests.swift */,
16586-
8ABCFEA42B45CAC300C2988A /* PrivateBrowsingTelemetryTests.swift */,
1658716578
8A11C8102731CFD700AC7318 /* ReaderModeStyleTests.swift */,
1658816579
03CCC9171AF05E7300DBF30D /* RelativeDatesTests.swift */,
1658916580
1D62C5262EE8E77C00C6BCB9 /* RelayControllerTests.swift */,
@@ -19576,7 +19567,6 @@
1957619567
61DD72D12F5936C4002BFEA6 /* AIControlsSetting.swift in Sources */,
1957719568
AB42CC752A1F5240003C9594 /* CreditCardBottomSheetHeaderView.swift in Sources */,
1957819569
21371FA428AA7A8D00BC3F37 /* OnboardingViewModelProtocol.swift in Sources */,
19579-
8ABCFEA32B45C36100C2988A /* PrivateBrowsingTelemetry.swift in Sources */,
1958019570
8ADC2A1F2A3399BD00543DAA /* LicenseAndAcknowledgementsSetting.swift in Sources */,
1958119571
21A43CDD291461C700B1206D /* ReaderModeFontTypeButton.swift in Sources */,
1958219572
8A7835332D50FEFF0052E328 /* BookmarksMiddleware.swift in Sources */,
@@ -19622,7 +19612,6 @@
1962219612
C400467C1CF4E43E00B08303 /* BackForwardListViewController.swift in Sources */,
1962319613
D5D237782640BBA600326204 /* ExperimentsSettingsViewController.swift in Sources */,
1962419614
D3972BF31C22412B00035B87 /* ShareManager.swift in Sources */,
19625-
8AB30ECA2B6C03C700BD9A9B /* DataClearanceAnimation.swift in Sources */,
1962619615
8A19ACB62A3290F9001C2147 /* NotificationsSetting.swift in Sources */,
1962719616
21365E392F30FD700000C369 /* BrowserViewControllerLayoutManager.swift in Sources */,
1962819617
43D16B8229831E6A009F8279 /* CreditCardInputField.swift in Sources */,
@@ -19797,7 +19786,6 @@
1979719786
E16941B42C4E4A2E00FF5F4E /* BrowserViewControllerStateTests.swift in Sources */,
1979819787
0B7B05412D64C088007FD7AC /* MockURLResponse.swift in Sources */,
1979919788
EDD334902D109A5B004516D0 /* ShareTelemetryActivityItemProviderTests.swift in Sources */,
19800-
8ABCFEA62B45CB4C00C2988A /* PrivateBrowsingTelemetryTests.swift in Sources */,
1980119789
ED33E3572D0A4CE9002265A7 /* URLActivityItemProviderTests.swift in Sources */,
1980219790
281B2BEA1ADF4D90002917DC /* MockProfile.swift in Sources */,
1980319791
AA6A6F382EF57EC000D1912D /* SystemLocaleProviderTests.swift in Sources */,

firefox-ios/Client/Application/AccessibilityIdentifiers.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ struct AccessibilityIdentifiers {
2424
static let shareButton = "TabLocationView.shareButton"
2525
static let summarizeButton = "TabLocationView.summarizeButton"
2626
static let backButton = "TabToolbar.backButton"
27-
static let fireButton = "TabToolbar.fireButton"
2827
static let forwardButton = "TabToolbar.forwardButton"
2928
static let tabsButton = "TabToolbar.tabsButton"
3029
static let addNewTabButton = "TabToolbar.addNewTabButton"

firefox-ios/Client/Assets/Images.xcassets/dataClearanceLarge.imageset/Contents.json

Lines changed: 0 additions & 15 deletions
This file was deleted.
Binary file not shown.

firefox-ios/Client/FeatureFlags/NimbusFlaggableFeature.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ enum NimbusFeatureFlagID: String, CaseIterable {
2020
case bottomSearchBar
2121
case deeplinkOptimizationRefactor
2222
case downloadLiveActivities
23-
case feltPrivacyFeltDeletion
2423
case firefoxJpGuideDefaultSite
2524
case firefoxSuggestFeature
2625
case hntSponsoredShortcuts
@@ -89,7 +88,6 @@ enum NimbusFeatureFlagID: String, CaseIterable {
8988
.homepageStoryCategories,
9089
.hostedSummarizer,
9190
.improvedAppStoreReviewTriggerFeature,
92-
.feltPrivacyFeltDeletion,
9391
.microsurvey,
9492
.nativeErrorPage,
9593
.needsReloadRefactor,
@@ -162,7 +160,6 @@ struct NimbusFlaggableFeature: HasNimbusSearchBar {
162160
.bookmarksSearchFeature,
163161
.deeplinkOptimizationRefactor,
164162
.downloadLiveActivities,
165-
.feltPrivacyFeltDeletion,
166163
.firefoxJpGuideDefaultSite,
167164
.homepageSearchBar,
168165
.homepageStoriesScrollDirection,

firefox-ios/Client/Frontend/Browser/BrowserViewController/Actions/GeneralBrowserAction.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ enum GeneralBrowserActionType: ActionType {
7979
case addNewTab
8080
case showNewTabLongPressActions
8181
case addToReadingListLongPressAction
82-
case clearData
8382
case showPasswordGenerator
8483
case didSelectedTabChangeToHomepage
8584
case enteredZeroSearchScreen

firefox-ios/Client/Frontend/Browser/BrowserViewController/Extensions/BrowserViewController+ToolBarActionMenuDelegate.swift

Lines changed: 0 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,6 @@ import Shared
77
import UIKit
88

99
extension BrowserViewController: PhotonActionSheetProtocol {
10-
// MARK: Data Clearance CFR / Contextual Hint
11-
12-
// Reset the CFR timer for the data clearance button to avoid presenting the CFR
13-
// In cases, such as if user navigates to homepage or if fire icon is not available
14-
func resetDataClearanceCFRTimer() {
15-
dataClearanceContextHintVC.stopTimer()
16-
}
17-
18-
func configureDataClearanceContextualHint(_ view: UIView) {
19-
guard contentContainer.hasWebView,
20-
tabManager.selectedTab?.url?.displayURL?.isWebPage() == true
21-
else {
22-
resetDataClearanceCFRTimer()
23-
return
24-
}
25-
dataClearanceContextHintVC.configure(
26-
anchor: view,
27-
withArrowDirection: toolbarHelper.shouldShowNavigationToolbar(for: traitCollection) ? .down : .up,
28-
andDelegate: self,
29-
presentedUsing: { [weak self] in
30-
self?.presentContextualHint(for: .dataClearance)
31-
},
32-
andActionForButton: { },
33-
overlayState: overlayManager)
34-
}
35-
36-
private func presentDataClearanceContextualHint() {
37-
present(dataClearanceContextHintVC, animated: true)
38-
UIAccessibility.post(notification: .layoutChanged, argument: dataClearanceContextHintVC)
39-
}
40-
4110
// Starts a timer to monitor for a navigation button double tap for the navigation contextual hint
4211
@MainActor
4312
func startNavigationButtonDoubleTapTimer() {
@@ -185,7 +154,6 @@ extension BrowserViewController: PhotonActionSheetProtocol {
185154
switch hintType {
186155
case .summarizeToolbarEntry: presentSummarizeToolbarEntryContextualHint()
187156
case .translation: presentTranslationContextualHint()
188-
case .dataClearance: presentDataClearanceContextualHint()
189157
case .navigation: presentNavigationContextualHint()
190158
case .toolbarUpdate: presentToolbarUpdateContextualHint()
191159
default: break
@@ -207,7 +175,6 @@ extension BrowserViewController: PhotonActionSheetProtocol {
207175
}
208176

209177
func resetCFRsTimer() {
210-
resetDataClearanceCFRTimer()
211178
resetSummarizeToolbarCFRTimer()
212179
}
213180

@@ -217,75 +184,6 @@ extension BrowserViewController: PhotonActionSheetProtocol {
217184
translationContextHintVC.stopTimer()
218185
}
219186

220-
/// Triggers clearing the users private session data, an alert is shown once and then, deletion is done directly after
221-
func didTapOnDataClearance() {
222-
guard !(profile.prefs.boolForKey(PrefsKeys.dataClearanceAlertShown) ?? false) else {
223-
performDeletionAction()
224-
return
225-
}
226-
227-
let alert = UIAlertController(
228-
title: .Alerts.FeltDeletion.Title,
229-
message: .Alerts.FeltDeletion.Body,
230-
preferredStyle: .alert
231-
)
232-
233-
let cancelAction = UIAlertAction(
234-
title: .Alerts.FeltDeletion.CancelButton,
235-
style: .default,
236-
handler: { [weak self] _ in
237-
self?.privateBrowsingTelemetry.sendDataClearanceTappedTelemetry(didConfirm: false)
238-
}
239-
)
240-
241-
let deleteDataAction = UIAlertAction(
242-
title: .Alerts.FeltDeletion.ConfirmButton,
243-
style: .destructive,
244-
handler: { [weak self] _ in
245-
self?.performDeletionAction()
246-
}
247-
)
248-
249-
alert.addAction(deleteDataAction)
250-
alert.addAction(cancelAction)
251-
present(alert, animated: true) { [weak self] in
252-
self?.profile.prefs.setBool(true, forKey: PrefsKeys.dataClearanceAlertShown)
253-
}
254-
}
255-
256-
private func performDeletionAction() {
257-
self.privateBrowsingTelemetry.sendDataClearanceTappedTelemetry(didConfirm: true)
258-
self.setupDataClearanceAnimation { timingConstant in
259-
DispatchQueue.main.asyncAfter(deadline: .now() + timingConstant) {
260-
self.closePrivateTabsAndOpenNewPrivateHomepage()
261-
}
262-
}
263-
}
264-
265-
private func closePrivateTabsAndOpenNewPrivateHomepage() {
266-
tabManager.removeTabs(tabManager.privateTabs)
267-
tabManager.selectTab(tabManager.addTab(isPrivate: true))
268-
}
269-
270-
/// Setup animation for data clearance flow unless reduce motion is enabled
271-
/// - Parameter completion: returns the proper timing to match animation on when to close tabs and display toast
272-
private func setupDataClearanceAnimation(completion: @escaping (Double) -> Void) {
273-
let showAnimation = !UIAccessibility.isReduceMotionEnabled
274-
let timingToMatchGradientOverlay = showAnimation ? 0.8 : 0.0
275-
276-
guard showAnimation else {
277-
completion(timingToMatchGradientOverlay)
278-
return
279-
}
280-
let dataClearanceAnimation = DataClearanceAnimation()
281-
dataClearanceAnimation.startAnimation(
282-
with: view,
283-
for: toolbarHelper.shouldShowTopTabs(for: traitCollection)
284-
)
285-
286-
completion(timingToMatchGradientOverlay)
287-
}
288-
289187
func dismissUrlBar() {
290188
if addressToolbarContainer.inOverlayMode {
291189
addressToolbarContainer.leaveOverlayMode(reason: .finished, shouldCancelLoading: false)

firefox-ios/Client/Frontend/Browser/BrowserViewController/State/BrowserViewControllerState.swift

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ struct BrowserViewControllerState: ScreenState {
3838
case readerMode
3939
case newTabLongPressActions
4040
case readerModeLongPressAction
41-
case dataClearance
4241
case passwordGenerator
4342
case translationLanguagePicker(TranslationLanguagePickerData)
4443
}
@@ -377,8 +376,6 @@ struct BrowserViewControllerState: ScreenState {
377376
return handleShowNewTabLongPressAction(state: state, action: action)
378377
case GeneralBrowserActionType.addToReadingListLongPressAction:
379378
return handleAddToReadingListLongPressAction(state: state, action: action)
380-
case GeneralBrowserActionType.clearData:
381-
return handleClearDataAction(state: state, action: action)
382379
case GeneralBrowserActionType.showPasswordGenerator:
383380
return handleShowPasswordGeneratorAction(state: state, action: action)
384381
case GeneralBrowserActionType.showSummarizer:
@@ -678,19 +675,6 @@ struct BrowserViewControllerState: ScreenState {
678675
autoTranslatePromptState: AutoTranslatePromptState.reducer(state.autoTranslatePromptState, action))
679676
}
680677

681-
@MainActor
682-
private static func handleClearDataAction(state: BrowserViewControllerState,
683-
action: GeneralBrowserAction) -> BrowserViewControllerState {
684-
return BrowserViewControllerState(
685-
searchScreenState: state.searchScreenState,
686-
windowUUID: state.windowUUID,
687-
shouldShowReaderModeBarSummarizerButton: state.shouldShowReaderModeBarSummarizerButton,
688-
browserViewType: state.browserViewType,
689-
displayView: .dataClearance,
690-
microsurveyState: MicrosurveyPromptState.reducer(state.microsurveyState, action),
691-
autoTranslatePromptState: AutoTranslatePromptState.reducer(state.autoTranslatePromptState, action))
692-
}
693-
694678
@MainActor
695679
private static func handleShowPasswordGeneratorAction(state: BrowserViewControllerState,
696680
action: GeneralBrowserAction) -> BrowserViewControllerState {

0 commit comments

Comments
 (0)